diff --git a/extra/vulnserver/__init__.py b/extra/vulnserver/__init__.py new file mode 100644 index 000000000..c654cbef7 --- /dev/null +++ b/extra/vulnserver/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +pass diff --git a/extra/vulnserver/vulnserver.py b/extra/vulnserver/vulnserver.py new file mode 100644 index 000000000..85f064814 --- /dev/null +++ b/extra/vulnserver/vulnserver.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +""" +vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes) + +Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +from __future__ import print_function + +import re +import sqlite3 +import sys +import traceback + +if sys.version_info >= (3, 0): + from http.client import FOUND + from http.client import NOT_FOUND + from http.client import OK + from http.server import BaseHTTPRequestHandler + from http.server import HTTPServer + from socketserver import ThreadingMixIn + from urllib.parse import parse_qs + from urllib.parse import unquote_plus +else: + from BaseHTTPServer import BaseHTTPRequestHandler + from BaseHTTPServer import HTTPServer + from httplib import FOUND + from httplib import NOT_FOUND + from httplib import OK + from SocketServer import ThreadingMixIn + from urlparse import parse_qs + from urllib import unquote_plus + +SCHEMA = """ + CREATE TABLE users ( + id INTEGER, + name TEXT, + surname TEXT + ); + 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', 'ming'); + INSERT INTO users (id, name, surname) VALUES (4, 'sqlmap/1.0-dev (http://sqlmap.org)', 'user agent header'); + INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull'); +""" + +LISTEN_ADDRESS = "localhost" +LISTEN_PORT = 8440 + +_conn = None +_cursor = None +_server = None + +def init(): + global _conn + global _cursor + + _conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False) + _cursor = _conn.cursor() + + _cursor.executescript(SCHEMA) + +class ThreadingServer(ThreadingMixIn, HTTPServer): + def finish_request(self, *args, **kwargs): + try: + HTTPServer.finish_request(self, *args, **kwargs) + except Exception: + traceback.print_exc() + +class ReqHandler(BaseHTTPRequestHandler): + def do_REQUEST(self): + path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "") + params = {} + + if query: + params.update(parse_qs(query)) + + if hasattr(self, "data"): + params.update(parse_qs(self.data)) + + for key in params: + if params[key]: + params[key] = params[key][-1] + + self.url, self.params = path, params + + if self.url == '/': + if "id" not in params: + self.send_response(FOUND) + self.send_header("Connection", "close") + self.send_header("Location", "/?id=1") + self.end_headers() + else: + self.send_response(OK) + self.send_header("Content-type", "text/html") + self.send_header("Connection", "close") + self.end_headers() + + try: + _cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params.get("id", "")) + + output = "SQL results:\n" + output += "
| %s | " % value + output += "