复现HITB PHP lover代码审计
參考文獻:https://www.anquanke.com/post/id/104952
一直想學代碼審計來著,看到了一篇大佬的關于php代碼審計的wp,決定自己試一下
源碼下載地址:https://hitbxctf2018.xctf.org.cn/contest_challenge/里面的web題目中的PHP lover
代碼結構
Controller 控制器,只有index.controller.php Core 類及方法定義 templates 前端的各種html界面 uploads 里面是兩張圖片 back.sql 創建的數據表 config.php 連接數據庫 function.php 定義過濾函數 index.php 入口文件從index.controller.php看下主要功能
public function login() public function register() public function add() public function view() public function edit() public function export()- login()
1.png
登錄調用User類的login()方法,跟進login()函數(在user.class.php中)
2.png
跟進username的過濾函數filter()(在function.php文件中)
3.png
其中正則表達式中的b表示的為單詞邊界,而不是通配,如preg_match("/bwebb/i")只能匹配到web,而web123這種就不能。
所以可以用"select * from/**/users"繞過此過濾(/**/作為空格注入)
但是在User類的login()方法中,
這就把/**/過濾了,所以這個方法不行
-
register()
1.png跟進user類的register()方法
2.png
其中$username和$nickname沒有可能了
再看一下email,看下正則匹配
其中([\"].+[\"])只需要""包圍即可,引號中可以隨便寫。所以可以用·'"' and 1=1#'"@skysec.top'這種繞過,但是在daddslashes()這個函數中將"轉義了。
-
add()
1.png跟進user類中的add()方法
2.png
全部被轉義 -
view()
1.png
跟進user類中的getarticle()函數
2.png
emmm,直接intval()也是妙。。 -
edit()
1.png上傳功能,類型檢測可以抓包bypass,但是
文件后綴直接是mine的類型,這樣就不能bypass上傳惡意文件了
跟進下user類的getuser()方法
2.png
文件名、是我們注冊的用戶名,用戶名是無法bypass的,所以這里的上傳,除了文件名長度其他都不可控
-
export()
1.png跟進user()類中的report()方法
2.png
這里被當做錯誤觸發,未做任何過濾,其中email的插入很關鍵
所以接下來才算步入正題。。。emmm先膜拜下大佬的思路。
攻擊點
- 這題注冊的時候,可以Bypass注冊惡意郵箱,但是其中有符號被轉義了
- 但是這個轉義在取出數據庫的時候會被去除
- 如果在取出后,系統又對這個數據進行了一次sql操作,就可以觸發注入,通過二次注入
- 我們的注冊的時候注冊惡意郵箱,在這里觸發錯誤報告的時候就會被系統再次調用,取出數據庫后轉義消失
- 拼接到insert語句時,構成sql注入攻擊
我們根據這一點注冊用戶,郵箱為
假設我們能觸發export()函數中的$this->user->report(1)
$this->email為我們郵箱取出數據庫的值:
"', 233), (2333, (SELECT group_concat(TABLE_NAME) FROM/**/ information_schema.TABLES where TABLE_SCHEMA=database()), 23333)#"@skysec.top此時利用report插入了兩條數據
$this->id,'"', 233 2333, (SELECT group_concat(TABLE_NAME) FROM/**/ information_schema.TABLES where TABLE_SCHEMA=database()), 23333)觸發sql注入需要解決
①自己的id需要知道,這樣可以插入
在view()方法中
若是不輸入article參數,會調用
function getid(){if ($this->islogin) return $this->id;else return null;}就可獲得id
②觸發if(file_exists($avatar) and filesize($avatar)<65535)false,這樣就會成功到else,構成攻擊
跟進user類中的getavatar()方法
2.png
查看back.sql文件,其中 $r[1]:data $r[3]:filepath
如果我們的上傳圖片有數據,就返回Base64后的數據,否則返回路徑
edit()的上傳功能中有
$filename="uploads/".$this->user->getuser().".".$type; if(is_uploaded_file($_FILES['avatar']['tmp_name'])){$this->user->edit("avatar",array($filename,$type));跟進user類中的edit()方法
if($feild=="avatar"){return $this->db->Insert("avatar",array("''",$this->id,"'$value[0]'","'$value[1]'")); }即avatar表的filepath字段為
uploads/用戶名.文件mine數據庫結構中
2.png用戶名的長度是300,而路徑長度
`filepath` varchar(300),如果我們的用戶名長度為300,此時插入的路徑就會被300截斷,而變成一個不存在的路徑,此時即可觸發file_exists($avatar)錯誤
題目鏈接打不開了,放下大佬的完整攻擊流程:
- 先隨便注冊個用戶,看一下自己的id
- 然后再迅速注冊用戶,驗證id是否是自己預想的id+1
- 登錄后觸發上傳功能
- 上傳空文件,抓包改mine
- 觸發export功能,即可完成攻擊,發現注入成功后的數據
最后得到flag表,以及數據
總結
以上是生活随笔為你收集整理的复现HITB PHP lover代码审计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [日常] Go语言圣经--Channel
- 下一篇: php对象序列化总出错false