Tags: regex sqli 

Rating:

When browsing to the target URL, we are presented with a login form and a
[link to the login source code](http://2018shell3.picoctf.com:53261/login.txt) :

```php
";
echo "username: ", htmlspecialchars($username), "\n";
echo "password: ", htmlspecialchars($password), "\n";
echo "SQL query: ", htmlspecialchars($query), "\n";
echo "";
}

//validation check
$pattern ="/.*['\"].*OR.*/i";
$user_match = preg_match($pattern, $username);
$password_match = preg_match($pattern, $username);
if($user_match + $password_match > 0) {
echo "<h1>SQLi detected.</h1>";
}
else {
$result = $con->query($query);
$row = $result->fetchArray();

if ($row) {
echo "<h1>Logged in!</h1>";
echo "

Your flag is: $FLAG

";
} else {
echo "<h1>Login failed.</h1>";
}
}
?>
```

It is apparent from the code that we're looking at an SQL injection, this time
with a [regex](https://en.wikipedia.org/wiki/Regular_expression)-based filter
to circumvent.

We can also see that the script takes a `debug` parameter that will echo the
SQL query.

The regex used for validation is:

```
/.*['\"].*OR.*/i
```
That translates to
`(any character, 0 or more times) followed by (a single quote) followed by ("OR") followed by (any character, 0 or more times)`

This filter would prevent using the basic `' OR 1=1 --` injection.

## The filtering bug

If we look closely at the code, we can notice a mistake :

```php
$user_match = preg_match($pattern, $username);
$password_match = preg_match($pattern, $username);
```

Instead of checking the validation regex against the `username` and `password`
fields, the `username` field is checked twice ! This means we can use our basic
injection on the `password` field.

Thanks to the `debug` parameter, we know that the query is constructed as
follows:

```sql
SELECT 1 FROM users WHERE name='username' AND password='password'
```

So if we were to inject our `' OR 1=1 ; --` payload in the `password` field, we
would end up with the following query :

```sql
SELECT 1 FROM users WHERE name='username' AND password='' OR 1=1 ; --'
```

That circumvents password verification, but we still need a valid username for
the query to return at least one row.

So I took a wild guess and tried a username of `admin` and a password of
`' OR 1=1 ; --`. Bingo : `picoCTF{w3lc0m3_t0_th3_vau1t_23495366}`

## A better solution

Let's assume for a moment that the filter was correctly used (i.e. if the
`username` and `password` fields were correctly checked). Would that mean
that we couldn't leverage an SQL injection ? Certainly not.

Here's an alternative solution I thought about when writing this up : if you pass
`'/*` as username and `*/ OR 1=1 --` as password, you get the flag and would
get it without the bug exploited in the previous solution.

The reason for that is that the two components of the injection (the `'`
escaping the quoted block and the always true `OR 1=1` condition) that are checked
against are split in different fields, preventing the regex from matching :

- `'/*` has a single quote but no `OR` : the `username` field doesn't match
- `*/ OR 1=1 --` contains `OR` but no single quote before : the `password` field doesn't match

The `/* */` is pretty much the same as in javascript : it declares an inline
comment, meaning that anything between `/*` and `*/` will be ignored.

So with that request, this query is constructed

```sql
SELECT 1 FROM users WHERE name=''/*' AND password='*/ OR 1=1 --'
```

Removing the commented-out parts, this is executed :

```sql
SELECT 1 FROM users WHERE name='' OR 1=1
```

This is a better solution for 2 reasons :

1. It would work even if the filter checking were fixed
2. It doesn't require to guess a valid username.

Original writeup (http://blog.iodbh.net/picoctf2018-web-the-vault.html).
garixmartin64Oct. 29, 2018, 10:17 a.m.

Play the great free online Mahjong connect online game,millions over users like and play this game,such a great awesome addition game <a href="https://mahjongconnectonline.com">Play mahjongg connect</a> it is not high concept game,i have fully enjoyed play this board game,now this id right time play or forward this url link to all users.