Освойте возможности использования самых сложных SQL-инъекций
Иногда вам нужна мощь четырех элементов , чтобы автоматизировать использование SQL-инъекций.
Это то что --eval дает вам, и вот как взять на себя эту силу.
В зависимости от случая вам может потребоваться изменить различные части запроса.
SQLMap использует exec() метод для выполнения вашего скрипта. инструмент передает разные части запроса этому методу как локальные переменные. таким образом, вы можете получить к ним доступ и изменить их.
тело сообщения запроса может иметь разные типы данных, такие как JSON, XML и т. д., чтобы обеспечить доступ к элементам каждого типа, SQLMap распознает тип по этим регулярным выражениям затем спрашивает, хотите ли вы, чтобы инструмент обрабатывал данные:
JSON/XML/... data found in POST/PUT/... body. Do you want to process it?
очевидно, вам нужно ответить YES, если вы хотите, чтобы все работало как задумано.
если пользователь указывает пользовательскую точку внедрения в пути URL-адреса, uriПараметр также будет содержать внедренную полезную нагрузку в кодировке URL.
пример:
локальная переменная:
локальная переменная:
команда:
локальная переменная:
пример:
локальные переменные:
Примечание: если имя параметра содержит специальные символы или является зарезервированным ключевым словом в python, перед передачей переменной в exec() метод, SQLMap меняет свое имя на основе этого шаблона:
применяется ко всем переменным, которые передаются в метод exec(), включая файлы cookie и данные POST.
содержание заголовков Cookie, а также введенная полезная нагрузка (если есть) доступны через переменную cookie.
команда:
локальная переменная:
Вы можете получить доступ к заголовкам запроса через headers, но его изменение не повлияет на запрос, чтобы внести изменения в заголовки конечного запроса, вам нужен update() в auxHeaders.
Значение auxHeaders является Noneпо умолчанию. это означает, что вам нужно добавить все заголовки — измененные или нет, в auxHeaders.
пример:
допустим, вы хотите изменить значение заголовка User-Agent и добавьте собственный заголовок аутентификации X-Auth.
Это может выглядеть так.
POST тело
SQLMap распознает шесть типов данных POST, используя регулярные выражения:
JSON
JSON-like (regex)
XML
Multipart
Array-like (regex)
Form-based
Чтобы увидеть, как выглядят типы данных, подобные JSON и массивам, обратитесь к регулярным выражениям, которые их распознают. На момент написания этой статьи SQLMap разбирает form-based а также json типы данных. Для других типов данных у вас нет доступа к значению элементов но вы все равно можете изменить значение элементов, объявив переменную с тем же именем, что и имя элемента. SQLMap заменяет исходное значение новым с помощью регулярного выражения,обратите внимание, что эта реализация содержит ошибки array-like типы данных, но вы можете найти решение здесь .
но если ваш сценарий длиннее, не рекомендуется писать весь сценарий в терминале, вместо этого вы можете написать свой код в .py файл и импортировать его как модуль:
Пользователь имеет доступ к этим словарям как к локальным переменным:
headers: все заголовки запроса. изменение этого словаря повлияет на запрос.
get_data: обработанные данные запроса GET
post_data: обработанное тело POST. независимо от того, какой тип данных, пользователь имеет доступ ко ВСЕМ элементам и атрибутам типа данных.
get_query: необработанные данные запроса GET
post_body: необработанные данные тела POST
Примечание: изменение get_query или же post_body перезапишет изменения, внесенные в get_data, а также post_data соответственно.
Вам нужно добавить эти библиотеки в папку thirdparty:
xmltodict
request_toolblet
для получения дополнительной информации об этой реализации обратитесь к pull request on Github.
ОРИГИНАЛЬНАЯ СТАТЬЯ
Иногда вам нужна мощь четырех элементов , чтобы автоматизировать использование SQL-инъекций.
Это то что --eval дает вам, и вот как взять на себя эту силу.
В зависимости от случая вам может потребоваться изменить различные части запроса.
SQLMap использует exec() метод для выполнения вашего скрипта. инструмент передает разные части запроса этому методу как локальные переменные. таким образом, вы можете получить к ним доступ и изменить их.
тело сообщения запроса может иметь разные типы данных, такие как JSON, XML и т. д., чтобы обеспечить доступ к элементам каждого типа, SQLMap распознает тип по этим регулярным выражениям затем спрашивает, хотите ли вы, чтобы инструмент обрабатывал данные:
JSON/XML/... data found in POST/PUT/... body. Do you want to process it?
очевидно, вам нужно ответить YES, если вы хотите, чтобы все работало как задумано.
Доступ к различным частям запроса
URI
URI запроса без строки запроса доступен через uriпараметр.если пользователь указывает пользовательскую точку внедрения в пути URL-адреса, uriПараметр также будет содержать внедренную полезную нагрузку в кодировке URL.
пример:
Код:
sqlmap -u “http://example.com/path?id=123"
локальная переменная:
Код:
uri --> http://example.com/path
локальная переменная:
Код:
uri --> http://example.com/path
команда:
Код:
sqlmap -u “http://example.com/path*?id=123"
локальная переменная:
Код:
uri --> http://example.com/path<URL-ENCODED PAYLOAD>
GET - запрос
значение каждого параметра запроса GET, а также введенная полезная нагрузка (если есть) доступны через локальные переменные с именем исходных параметров GET.пример:
Код:
sqlmap -u "http://example.com/path?param1=123¶m2=456&class.id=789"
локальные переменные:
Код:
param1 --> 123
param2 --> 456
EVAL_636c6173732e6964 --> 789(читайте примечание ниже)
Примечание: если имя параметра содержит специальные символы или является зарезервированным ключевым словом в python, перед передачей переменной в exec() метод, SQLMap меняет свое имя на основе этого шаблона:
Код:
EVAL_<HEX OF ORIGINAL NAME>
применяется ко всем переменным, которые передаются в метод exec(), включая файлы cookie и данные POST.
ВКУСНЯШКИ
содержание заголовков Cookie, а также введенная полезная нагрузка (если есть) доступны через переменную cookie.
команда:
Код:
sqlmap -u "http://example.com/path?id=123" --cookie=”C1=123; C2=456"
локальная переменная:
Код:
cookie --> C1=123; C2=456
заголовки
есть два словаря в exec(), связанный с заголовками запроса:
Код:
_locals['headers']
_locals['auxHeaders']
Значение auxHeaders является Noneпо умолчанию. это означает, что вам нужно добавить все заголовки — измененные или нет, в auxHeaders.
пример:
допустим, вы хотите изменить значение заголовка User-Agent и добавьте собственный заголовок аутентификации X-Auth.
Это может выглядеть так.
Код:
# _locals['auxHeaders'] is None here
_locals['headers']['User-Agent'] = "pentesting, no worries!!"
_locals['headers']['X-Auth'] = "My_Secret_Token"
_locals['auxHeaders'].update(_locals['headers'])
POST тело
SQLMap распознает шесть типов данных POST, используя регулярные выражения:
JSON
JSON-like (regex)
XML
Multipart
Array-like (regex)
Form-based
Чтобы увидеть, как выглядят типы данных, подобные JSON и массивам, обратитесь к регулярным выражениям, которые их распознают. На момент написания этой статьи SQLMap разбирает form-based а также json типы данных. Для других типов данных у вас нет доступа к значению элементов но вы все равно можете изменить значение элементов, объявив переменную с тем же именем, что и имя элемента. SQLMap заменяет исходное значение новым с помощью регулярного выражения,обратите внимание, что эта реализация содержит ошибки array-like типы данных, но вы можете найти решение здесь .
полезная нагрузка
полезная нагрузка SQL, которую SQLMap внедрил в запрос, доступен через _locals['payload'] переменную.длинные сценарии
Когда код, который вы хотите выполнить, состоит из нескольких строк, вы можете добавить скрипт в качестве значения --eval в терминале:
Код:
sqlmap ... --eval="#first_line; #second_line; #third_line"
Код:
sqlmap ... --eval="import myModule; #use_functions_of_myModule"
отладка
Если вы хотите отладить свой код внутри SQLMap или хотите познакомиться с окружающей средой, вы можете использовать ipdp модуль это дает вам отладочную оболочку, и вы можете перемещаться и видеть, что происходит. в locals() может быть хорошей отправной точкой.
Код:
sqlmap ... --eval=”import ipdb; ipdb.set_trace()”
Новая реализация
Как вы можете видеть, гораздо лучше с флагом --eval. В этой новой реализации все типы данных поддерживаются унифицированным образом, также, я сделал row GET/ POST данные доступны как локальные переменные, так что, если пользователю нужно модифицировать запрос, а уже локальные существующие переменные ему не нужны, он может использовать сырые данные и парсить их так, как ему нужно.Пользователь имеет доступ к этим словарям как к локальным переменным:
headers: все заголовки запроса. изменение этого словаря повлияет на запрос.
get_data: обработанные данные запроса GET
post_data: обработанное тело POST. независимо от того, какой тип данных, пользователь имеет доступ ко ВСЕМ элементам и атрибутам типа данных.
get_query: необработанные данные запроса GET
post_body: необработанные данные тела POST
Примечание: изменение get_query или же post_body перезапишет изменения, внесенные в get_data, а также post_data соответственно.
Код:
if conf.evalCode:
delimiter = conf.paramDel or DEFAULT_GET_POST_DELIMITER
variables = {"uri": uri, "get_query": get, "headers": headers, "post_body": post, "get_data": {}, "post_data": {}, "lastPage": threadData.lastPage, "_locals": locals()}
original_get = get
original_post = post
if get:
for part in get.split(delimiter):
if '=' in part:
name, value = part.split('=', 1)
name = name.strip()
value = urldecode(value, convall=True)
variables['get_data'][name] = value
if kb.postHint:
if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP):
variables['post_data'] = xmltodict.parse(post)
if kb.postHint == POST_HINT.JSON:
variables['post_data'] = json.loads(post)
if kb.postHint == POST_HINT.JSON_LIKE:
if json_like_type == 3:
post = re.sub(r'(,|\{)\s*([^\'\s{,]+)\s*:', '\g<1>"\g<2>":', post)
if json_like_type == 4:
post = re.sub(r'(,|\{)\s*([^\'\s{,]+)\s*:', "\g<1>'\g<2>':", post)
if json_like_type in (2, 4):
post = post.replace("\\'", REPLACEMENT_MARKER).replace('\"','\\"').replace("'",'"').replace(REPLACEMENT_MARKER, "'")
variables['post_data'] = json.loads(post)
if kb.postHint == POST_HINT.MULTIPART:
multipart = MultipartDecoder(bytes(post, 'utf-8'), contentType)
boundary = '--' + multipart.boundary.decode('utf-8')
for part in multipart.parts:
name = re.search(r'"([^\"]*)"', part.headers._store[b'content-disposition'][1].decode('utf-8')).group(1)
value = part.text
variables['post_data'][name] = value
if kb.postHint == POST_HINT.ARRAY_LIKE:
post = re.sub(r"\A%s" % delimiter, "", post)
array_name = re.findall(r"%s(.*?)\[\]=" % delimiter, post)[0].strip()
variables['post_data'] = []
for value in post.split("%s[]=" % array_name)[1:]:
variables['post_data'].append(value.replace(delimiter, ""))
elif post:
for part in post.split(delimiter):
if '=' in part:
name, value = part.split('=', 1)
name = name.strip()
value = urldecode(value, convall=True, spaceplus=kb.postSpaceToPlus)
variables['post_data'][name] = valueevaluateCode(conf.evalCode, variables)if kb.postHint:
if kb.postHint in (POST_HINT.XML, POST_HINT.SOAP):
post = xmltodict.unparse(variables['post_data'])
if kb.postHint == POST_HINT.JSON:
post = json.dumps(variables['post_data'])
if kb.postHint == POST_HINT.JSON_LIKE:
post = json.dumps(variables['post_data'])
if json_like_type in (3, 4):
post = re.sub(r'"([^"]+)":', '\g<1>:', post)
if json_like_type in (2, 4):
post = post.replace('\\"', REPLACEMENT_MARKER).replace("'", "\\'").replace('"', "'").replace(REPLACEMENT_MARKER, '"')
if kb.postHint == POST_HINT.MULTIPART:
for name, value in variables['post_data'].items():
post = re.sub(r"(?s)(name=\"%s\"(?:; ?filename=.+?)?\r\n\r\n).*?(%s)" % (name, boundary), r"\g<1>%s\r\n\g<2>" % value.replace('\\', r'\\'), post)
if kb.postHint == POST_HINT.ARRAY_LIKE:
post = array_name + "[]=" + (delimiter + array_name + "[]=").join(variables['post_data'])
else:
post = delimiter.join(f'{key}={value}' for key, value in variables['post_data'].items())uri = variables['uri']
get = delimiter.join(f'{key}={value}' for key, value in variables['get_data'].items())
auxHeaders.update(variables['headers'])
cookie = variables['headers']['Cookie'] if 'Cookie' in variables['headers'] else None
get = variables['get_query'] if variables['get_query'] != original_get else get
post = variables['post_body'] if variables['post_body'] != original_post else post
Вам нужно добавить эти библиотеки в папку thirdparty:
xmltodict
request_toolblet
для получения дополнительной информации об этой реализации обратитесь к pull request on Github.
ОРИГИНАЛЬНАЯ СТАТЬЯ