Published on

Arab Security Cyber War Games Qualifications 2023

Authors
  • avatar
    Name
    Amr Zaki
    Twitter

Arab Security War Games Qualifications

Hello there, this is Amr Zaki also known as z4ki. I participated with my team in the ASWG qualifications and managed to solve 5 of the 7 web challenges. It was pretty amusing and fun to do so let's dive right in.

N1 - Easy 200 points

image

We are provided with a link to the challenge so let's go see what's there.

image
image

It's a static webpage with nothing interesting in the source code. So, first things first, let's go and see what our friend robots.txt has to say.

image

Noice, it seems like an easy win, right? sadly no, not this time as this path gives us a 404 :"(

The description of the challenge tells us not to brute force the directories, but instead to search deep inside the page. Let's fire up our Param Miner extension in burpsuite and see if there's any hidden headers or parameters. Luckly we get a hit for a GET parameter called url.

image

Notice when we provide this parameter a "Hacking Attempt" gets printed on the screen. I realized that this is actually misleading :"D after hours of trying to provide the url and see how can I bypass this message.

The url parameter is usually used for redirects or file reading, so, after trying some possible values and encoding with the path in the robots.txt file, we got the flag.

image

This was a rabbit hole, lots of them in this CTF, and for an easy challenge we spent a lot of time on it as did other teams :"D.

Iniectio - Easy 300 points

image

The challenge description is written in Latin, for reasons that escapes me. It translates like this.

10 this week she got sick and went to the hospital and the nurse gave her a serum injection and now she is fine.

It basically tells us that it's an injection of some sort, so let's open up the link and see.

image

Another static page with nothing interesting. But we notice it's a php page. Whenever I see a php extension I try to append ~ to see if the source code is there, and in this case in was.

<?php
  
  $dangerousFunctions = array('GET','POST','print','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>

Notice a get parameter called name and it must be less than 36 characters, and if we passed the validation for dangerous functions, out input gets passed to eval. The blocked functions are quite a lot and I searched for ways to execute system commands in php, a lot of the functions I found was there, but one wasn't. The glorious backticks `` so my payload this is my payload.

http://34.18.3.149:8000/xchal.php?name=".`ls -la`."
image

flag.php is there we can't read it with cat or tac as they're blocked so let's use base64.

image

Decoding the base64 string we get the flag.

<?php
ASCWG{yeah_mrx_come_her!!!!!!!!!!!!!!!!}
?>

Father's Light - Medium 600 points

image

This challenge was quite amusing and very fun to do, but also had a rabbit hole that I dived right into :"P.

image

The link goes right to a login panel, so I tried the obvious authentication bypass but none worked. So, let's try to cause some errors and hope it reaveals somthing.

image

Sending the username as an array reveals some of the source code but not all, also tells us we're working with a Flask app. This snippet of source code doesn't tell us much, so we need to read further. Let's send the password as an array instead.

image

Awesome we got another line and that contains credentials to log in with. Once we log in we got redirected to /user endpoint with nothing else in the page source. Once redirected we got assigned a cookie which at first glance looks like a JWT.

image

Trying to decode the cookie with jwt.io we get the following:

image

Doesn't look like a valid JWT right? so back to searching. Googling Flask and session cookie we get a lot of results with one interesting hacktricks blog. So, using the command line we could decode the cookie, and if it had a weak signature, we can guess the passphrase.

image

Very neat right? let's go paste this session cookie and see what we got.

image

Nothing else has changed but we're not admin, so let's look for endpoints accessible for admins only. Brute forcing directories we get 3 endpoints.

  • /dashboard -> this is interesting.
  • /console -> this is a werkzeug python console but needs a PIN code. another rabbit hole :"(
  • /admin -> this is the admin page we currently on.

So, let's navigate to the /dashboard endpoint and see what's what.

image

The name and post content gets reflected so I tried to cause some errors by passing the name parameter as an array, as we already know errors are enabled on this site, we got a snippet of the source code that reveals it is an SSTI vulnerability.

def template():
    if request.method == 'GET':
        return redirect(url_for('dashboard'))
    if 'username' in session_for_template and session_for_template['is_admin']:
        if request.method == 'POST':
            name = request.form['name']
            pattern = r'\b(bash|sh|nc|netcat|python|perl|ruby|ncat|python|curl|wget|__subclasses__|read()|__class__|/etc/passwd|/|write|__import__|popen|__init__|_TemplateReference__context|__globals__|__init__|for|from_pyfile|bin|shell|RUNCMD|request.__class__|request|attr|{{request.__class__}}|join|application|config.items)\b'
            if re.search(pattern, name) or name.lower() == "{{config}}":
                alert_message = "Againnn ?? Do You think you can Hack My Applicationnnnnnnn!!!"
                return render_template('index.html', alert_message=alert_message)
            else:

So, there's a regex that matches our name input with a pattern used to prevent SSTI, but what's intresting is this line of code:

if re.search(pattern, name) or name.lower() == "{{config}}":

It looks for the string {{config}} so a workaround this would be submitting a {{ config }} -with spaces- and it worked, we got the flag.

image

SadQL - Medium 600 points

image

The objective is quite clear, we need to bypass the login function and the name of the challenge hints it is an SQL injection.

image

There's not a lot of functionality in this site, just the login page. Let's try to cause some errors,

image

The error indicates that addslashes() function in PHP is used to escape our input, so we can't break the query. I found this awesome blog that explains how to bypass this function. It's a pretty popular bypass by using GBK characters, which is a multi-byte character that fools the addslashes() function.

So let's try it and see..

image

Awesome, we broke the query. Now, let's try and use the basic authentication bypass payloads of SQL. We notice that or, union, spaces and probably others more are stripped of our input.

image

I noticed that our input is not stripped recursively, so I supplied oorr and it returned or.

image

Now to get a space in, we can use an empty comment /**/ and it worked and got the flag.

image

Blind - Medium 600 points

image

This challenge was quite annoying and was indeed another rabbit hole that I dived into for a few hours.

From the description, it tells us to escalate our privilege and become a director(admin).

image

There's a login function and a Register function, and after registering a new user, we have a dashboard.php which reflects our name and an update function in the profile.php page where we can update our name.

image

The rabbit hole was the update functionality had an SQL injection exactly like SadQL challenge. So I spent hours tried to get the admin password or somtheing like that but with no luck. I almost gave up but tried one last thing before I went to sleep :"D, it I tried supplying an extra parameter in the update function, like this..

image

When I got to the dashboard, the flag was right there waiting ❤️.

image

Conclusion

If you reached the end I salute you, it was very fun and satisfying. Till we meet in another writeup, see you next year hopefully. Adios ❤️