Tags: web crypto reverse 

Rating:

��## Master Page (Reverse, Web, Crypto, 315p)

tl;dr sqli via domain txt record

In this task, we're provided with a url to a simple login page, after looking around for a bit, we've noticed that `https://masterpage.asis-ctf.ir/.git/` returns error 403, which means there's a repository inside and we can access it

After [dumping](https://github.com/internetwache/GitTools/blob/master/Dumper/gitdumper.sh) the repo, we can easily check that there were 3 files in the repo `config.php`, `index.php` and `query.php`

`index.php` contains the interesting authentication part we're looking for:

``` php

$id = $mysql->filter($_POST['user'], "auth");

$pw = $mysql->filter($_POST['pass'], "pass");

$ip = $mysql->filter($_SERVER['REMOTE_ADDR'], "hash");

/* resolve ip addr. */

$dns = dns_get_record(gethostbyaddr($ip));

$ip = ($dns) ? print_r($dns, true) : ($ip);

/* mysql filtration */

$filter = "_|information|schema|con|\_|ha|b|x|f|@|\"|`|admin|cas|txt|sleep|benchmark|procedure|\^";

foreach($_POST as $_VAR){

if(preg_match("/{$filter}/i", $_VAR) || preg_match("/{$filter}/i", $ip))

{

exit("Blocked!");

}

}

if(strlen($id.$pw.$ip) >= 1024 || substr_count("(", $id.$pw.$ip) > 2)

{

exit("Too Long!");

}

/* admin auth */

$query = "SELECT id, pw FROM admin WHERE id='{$id}' AND pw='{$pw}' AND ip='{$ip}';";

$result = $mysql->query($query, 1);

if($result['id'] === "admin" && $result['pw'] === $_POST['pw'])

{

echo $flag."<HR>";

}

```

It's pretty obvious that the goal is to perform a SQL injection and get the flag, but how do we deal with the filters?

It turns out, that we can easily bypass the `mysql filtration` section by performing a GET request instead of POST, which means, we have to inject the payload into $ip.

We can do that by setting a TXT record of our domain to the needed string

After some debugging, we came up with a working payload: `' union select 'admin',NULL or '1'='`

The query becomes:

`"SELECT id, pw FROM admin WHERE id='NULL' AND pw='{NULL}' AND ip='GARBAGE` `' union select 'admin',NULL or '1'='` `GARBAGE';";`

The first part doesn't return any rows, the second select returns one row: `'admin', NULL` which allows it to pass the final check:

`$result['id'] === "admin" && $result['pw'] === $_POST['pw']`

Summing it up, create a TXT record with payload on a controlled domain, make a GET request from said domain and get the flag!

Original writeup (https://github.com/p4-team/ctf/blob/master/2016-09-09-asis-final/master_page/README.md).