1 <?php 2 error_reporting(0); 3 session_start(); 4 header("Content-type:image/jpeg"); 5 echo file_get_contents($_SESSION['avatar']); 6 ?>
在第5行發現 讀取的文件后,將文件進行了輸出。 所以猜測此處可能存在SSRF 和 任意文件讀取
搜索關鍵變量$_SESSION['avatar'] 發現在登陸 和修改密碼 讀取了改變量,而上傳的地方可以修改該變量 。
因為所有的$_SESSION['avatar']變量在發送數據包時都是加密的所以不能直接修改$_SESSION['avatar']導致任意文件讀取,所以采用上傳時修改其路徑。來改$_SESSION['avatar']
1 <?php 2 include_once('../sys/config.php'); 3 $uploaddir = '../uploads'; 4 5 if (isset($_POST['submit']) && isset($_FILES['upfile'])) { 6 7 if(is_pic($_FILES['upfile']['name'])){ 8 9 $avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name']; 10 11 if (move_uploaded_file($_FILES['upfile']['tmp_name'], $avatar)) { 12 //更新用戶信息 13 $query = "UPDATE users SET user_avatar = '$avatar' WHERE user_id = '{$_SESSION['user_id']}'"; 14 mysql_query($query, $conn) or die('update error!'); 15 mysql_close($conn); 16 //刷新緩存 17 $_SESSION['avatar'] = $avatar; 18 header('Location: edit.php'); 19 } 20 else { 21 echo 'upload error<br />'; 22 echo '<a href="edit.php">返回</a>'; 23 } 24 }else{ 25 echo '只能上傳 jpg png gif!<br />'; 26 echo '<a href="edit.php">返回</a>'; 27 } 28 } 29 else { 30 not_find($_SERVER['PHP_SELF']); 31 } 32 ?>
在第13行發現 $query = "UPDATE users SET user_avatar = '$avatar' WHERE user_id = '{$_SESSION['user_id']}'"; 他直接把上傳的路徑$avatar直接取出來,更新了數據庫
而UPDATE有個特殊的屬性在set設置多個相同的鍵時,只取最后一個鍵的值。 因此可以導致可以構造$_SESSION['avatar']
payload:
$avatar= ' , user_avatar = '讀取的文件路徑' WHERE user_id = 'zzz' 首先用單引號把$avatar去閉合,然后用逗號接下一個構造的變量 user_avatar = '讀取的文件路徑' ,但是出現了一個問題 user_id不是知道 但是可以取構造 user_name='注冊的用戶'
然后發現 if(is_pic($_FILES['upfile']['name'])) 對文件后綴進行了驗證
最終payload: $avatar= ' , user_avatar = '讀取的文件路徑' WHERE user_name='注冊的用戶' #.jpg
然后用戶登錄 上傳抓包,把抓到的
上傳文件修改文件名的包
去取變量$avatar
將取到的$avatar讀出來

修改文件名 filename

發現數據庫得到是 ../upload/..........._config.php 是因為取 單引號時對單引號和 / 進行了轉義導致單引號沒閉合


重新編碼成16進制 繞過單引號和/

成功構造。
然后先重放登錄頁面獲取去取變量$avatar
然后在
將取到的$avatar讀出來

如圖所示攻擊成功,本地文件任意讀取。
接下來測試SSRF
因為沒有內網環境,所以測試百度 將http://www.baidu.com

發現成功將百度頁面讀取,也就是可以讀取內網信息。所以存在SSRF
