ctfshow-爆破

web21 10

需要账号密码登录,盲猜账号admin,进行抓包

这里会发现,由于之前我在进行账号密码的登录的时候,都不是以请求头的方式出现的,这里有一种新的方式

Authorization请求头

作为HTTP 协议中用于身份验证的重要机制。凭证由用户名和密码组合而成,经过 Base64 编码后发送

  • 基本认证 格式:Authorization: Basic base64(username:password) [比较简单的认证方式,凭证由用户名和密码组合而成,经过 Base64 编码后发送]
  • 令牌认证 格式:Authorization: Bearer <token> [在 OAuth 2.0 和 JWT(JSON Web Token)中经常会用到。客户端会持有一个令牌(token),并在请求时将其发送给服务器。]
  • 摘要认证 格式:Authorization: Digest username="admin", realm="example.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/path/to/resource", response="3dcd4b20e5b0d84625a0252e69b199a8e", opaque="5ccc069c403ebaf9f0171e9517f40e410"根据服务器提供的挑战(challenge)计算出一个摘要值,并将其发送给服务器
  • OAuth 2.0 格式:Authorization: Bearer <access_token>使用访问令牌(access token)进行认证,其格式和令牌认证相似

进行爆破,由于这里是进行了基本认证,所以需要处理一下payload,添加前缀为admin,添加base64解码

同时这里需要取消url编码字符,=会影响base64编码

完成之后进行爆破即可

web22 10

爆破域名,这里爆破ctf.show的子域名,直接找一个子域名查询的在线网站即可

web23 10

代码审计

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-03 11:43:51
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-03 11:56:11
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
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__);

}
?>

第 2 个字符、第 15 个字符和第 18 个字符必须相同,同时

这里直接暴力枚举,出个脚本

import hashlib
import string
import itertools

def find_valid_token():
    characters = string.ascii_letters + string.digits + string.punctuation
    # 尝试不同长度的token
    for length in range(1, 10):
        for combination in itertools.product(characters, repeat=length):
            token = ''.join(combination)
            md5_hash = hashlib.md5(token.encode()).hexdigest()
            
            # 检查条件1: substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)
            if md5_hash[1] == md5_hash[14] and md5_hash[14] == md5_hash[17]:
                # 检查条件2: (intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))
                try:
                    a = int(md5_hash[1], 16)
                    d = int(md5_hash[31], 16)
                    if (a + a + a) / a == d:
                        return token
                except ZeroDivisionError:
                    continue
    return None

# 找到有效的token
valid_token = find_valid_token()
if valid_token:
    print(f"找到有效token: {valid_token}")
    print(f"访问URL: http://example.com/?token={valid_token}")
else:
    print("未找到符合条件的token")    

web24 10

<?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: h1xa@ctfer.com
# @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');
}

?>

代码审计,看到mt_srand()就可以想到伪随机数,这里直接固定种子是372619038,那么只需要使用相同种子生成随机数就可以了

<?php
mt_srand(372619038);  // 使用与目标服务器相同的种子
echo mt_rand();       // 输出与服务器相同的随机数
?>

web25 10

<?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: h1xa@ctfer.com
# @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');
}

代码审计,这里MD5 哈希前 8 个字符作为种子初始化 MT19937 伪随机数生成器,同时要求r等于服务器生成的随机数,并且需要在cookie中令token的值等于两个连续生成的随机数之和

  • 首先需要获取 mt_rand() 的无符号真实值(获得种子第一次的伪随机数生成值)
  • HP 代码中,$rand 的计算逻辑是$rand = intval($r) - intval(mt_rand());当r=0时,$rand = 0 - mt_rand(); // 即 $rand = -mt_rand()

所以基于seed的第一次随机数计算为1876750954,那么可以使用php_mt_seed去还原seed,

通过命令time ./php_mt_seed 1876750954找到seed,再次计算两次随机数相加的值

<?php
  mt_srand(1390368345);
  mt_rand();
  echo mt_rand()+mt_rand();
?>

,在进行还原seed的时候,数值有很多个,所以进行测试,测出来哪个是对的就行。这里r为什么等于1876750954前面已经解释清楚了

web26 10

进行抓包爆破

web27 10

进来就是一个教务系统的登录,打开录取名单会给你弹一个被录取的表格,接着看一下学籍系统的查询(抓包抓这个)

这里要求知道学生具体的身份证号码,这就是爆破的点,可以发现被隐藏的是个人的出生年月日

直接进行爆破,注意:爆破数据的格式要符合他身份证的格式

出来了就可以直接登录了,进去就是flag

web28 10

扫一下发现有非常多的目录,可以看到改变的是有顺序的数字,刚开始我以为改的只有这一个目录,测试发现改动了两个

进行爆破,将攻击类型改为cluster bomb

payload1和payload2都改一下

也是有响应了

上一篇
下一篇