# Lesson learned?

{% embed url="<https://tryhackme.com/room/lessonlearned>" %}

Thanks Tib3rius for the room and the quick exchange on discord. I definitely take the topic with me and have learned something, even if I am so far only active in CTFs.

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

## Recon

Even though the room description states that there is only a login page, no hidden files, and no rabbit holes, we hit up Nmap and scanned our target machine. We have two open ports: an HTTP server running on port 80 and an SSH server running on port 22.

<figure><img src="/files/iIH6Ki1bh7CJHeliD0gt" alt=""><figcaption></figcaption></figure>

While visiting the website, we use Gobuster to check for interesting directories on the web server, but do not find anything of interest.

<figure><img src="/files/y83DMTY9QIvjmFMrljak" alt=""><figcaption></figcaption></figure>

Visiting the site gives us a login form, asking for a username and password. Common attacks on login forms are SQL injection and brute-force attacks. To get the flag, we have to bypass the login using either of these attacks.

<figure><img src="/files/WqV8MtEQSKklQt5eOT6X" alt=""><figcaption></figcaption></figure>

## Login Bypass

First of all, we check the login page with default credentials `admin:admin` and retrieve the error message `Invalid username and password`. This might come in handy later.<br>

<figure><img src="/files/JEjKhC7f3cDitJGpy7b6" alt=""><figcaption></figcaption></figure>

Next, we check for possible SQL injection, but most of the payloads did not respond with any errors.

<figure><img src="/files/J2kOjS9ZQaWYsosQGeSP" alt=""><figcaption></figcaption></figure>

After several attempts and missing error messages, we just tried the following.

<figure><img src="/files/HjzQldnN56sJfPSYQm8g" alt=""><figcaption></figcaption></figure>

Desperately trying to bypass the login via `admin' OR '1'='1` simply, we get a warning message.

It is teaching us why it wouldn't bypass the login and the consequences of our injection. The injected statement made it into a DELETE statement, which removes our flag. To get the flag, we have to restart the machine and avoid using the OR injection next time.

Another example of `' OR '1'='1` bad practice is that all rows of a table are returned, and those can be very large.

Even SQLmap does not use `OR 1=1` unless the risk level is set to 3. Having the error message in mind and the message to treat this box as if it were a real target and not a CTF, we continue with a different approach.

<figure><img src="/files/Ez0eHJ3IGk6AVrZP1hp0" alt=""><figcaption></figcaption></figure>

Revisiting our login with default credentials `admin:admin` we look at the error message.&#x20;

<figure><img src="/files/JEjKhC7f3cDitJGpy7b6" alt=""><figcaption></figcaption></figure>

With the error message `Invalid username and password`, we are able to enumerate possible stored usernames. This violates against the OWASP Authentication Guidelines

{% hint style="info" %}
<https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Authentication_Cheat_Sheet.md#authentication-and-error-messages>
{% endhint %}

> Incorrectly implemented error messages in the case of authentication functionality can be used for the purposes of user ID and password enumeration. An application should respond (both HTTP and HTML) in a generic manner.

Some of the SQL statements provided by Tib3rius are less harmful and good examples of SQL injection, and we'll follow his example.

> If you want good examples for SQL injection, use these.\
> \
> Auth Bypass: admin'; -- -\
> \
> SELECT \* FROM users WHERE username = 'admin'; -- -' AND password = 'password'\
> \
> Boolean: ' AND '1'='1 / ' AND '1'='2\
> \
> SELECT \* FROM articles WHERE author = 'admin' AND '1'='1' <https://t.co/NTeXNE8OdY>
>
> — Tib3rius (@0xTib3rius) [February 12, 2023](https://twitter.com/0xTib3rius/status/1624819441044185088?ref_src=twsrc%5Etfw)

<figure><img src="/files/28BHjebr6QyWHe4ijsdn" alt=""><figcaption><p>source: <a href="https://twitter.com/0xTib3rius/status/1623734218302930946">https://twitter.com/0xTib3rius/status/1623734218302930946</a></p></figcaption></figure>

So the idea is, to retrieve a valid username, to be able to inject a valid `' AND '1'='1` statement to bypass the login.

We intercept the login request via Burp Suite to get the necessary information to craft our command for Hydra to brute-force a possible user. We see that it is a POST request, requiring the variables  `username` and `password`.<br>

<figure><img src="/files/DjWmPDlH9lmCN7GfLXa6" alt=""><figcaption></figcaption></figure>

With the following command, we fire up Hydra and are able to retrieve some usernames using the `xato-net-10-million-usernames.txt` from SecLists:

```
┌──(0xb0b㉿kali)-[/usr/share/wordlists/SecLists/Usernames]
└─$ hydra -L /usr/share/wordlists/SecLists/Usernames/xato-net-10-million-usernames.txt -p asdf 10.10.172.59 http-post-form "/:username=^USER^&password=^PASS^:Invalid username and password."
```

<figure><img src="/files/yWOeDbSDKPDPBzPwGk18" alt=""><figcaption></figcaption></figure>

To confirm the results, we try to log in with one of the usernames and get another error message about an invalid password - Nice. We enumerated the user `kelly`.

<figure><img src="/files/1uwaM5Tzctr01ebGBDAI" alt=""><figcaption></figcaption></figure>

Now, we want to craft our statement.&#x20;

With the original statement in mind, which probably looks something like this

`SELECT * FROM users WHERE username = 'user_var' AND password = 'pass_var’`

We craft the payload `kelly' AND '1'='1'-- -` resulting in&#x20;

`SELECT * FROM users WHERE username = 'kelly' AND '1'='1' -- - AND password = ''`

<figure><img src="/files/AXAD2xpz80CLI6Juwpxj" alt=""><figcaption></figcaption></figure>

By providing the payload, we are greeted with the flag and an explanation about the risks of using the `OR 1 = 1` injection.

<figure><img src="/files/1wrZtyOquRhsoDDe6OEB" alt=""><figcaption></figcaption></figure>

## Alternative Solution&#x20;

Upon trying some payloads provided by HackTricks to check the login form for SQL injection and checking for the number of columns using union-based SQL injection to enumerate the table further, the flag was also retrieved and the login bypassed.

{% embed url="<https://book.hacktricks.xyz/pentesting-web/sql-injection#union-select>" %}

The query `admin' UNION SELECT null-- -` does bypass the login as well.&#x20;

After a quick chat with Tib3rius I got the following explanation:

The username check solely verifies the presence of a single row resulting from the query. With the remaining portion of the query commented out, the password check is absent as well. Since UNION makes no sense in a DELETE statement, it got skipped too.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xb0b.gitbook.io/writeups/tryhackme/2023/lesson-learned.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
