
SQL 인젝션 공격 도구
#BBQSQL# 블라인드 SQL 인젝션 공격 도구
블라인드 SQL 인젝션은 공격하기 까다롭습니다. 사용 가능한 도구가 작동할 때는 잘 작동하지만, 작동하지 않으면 직접 무언가를 작성해야 합니다. 이는 시간이 많이 걸리고 지루한 작업입니다. BBQSQL은 이러한 문제를 해결하는 데 도움을 줄 수 있습니다.
BBQSQL은 Python으로 작성된 블라인드 SQL 인젝션 프레임워크입니다. 까다로운 SQL 인젝션 취약점을 공격할 때 매우 유용합니다. BBQSQL은 반자동 도구로, 공격하기 어려운 SQL 인젝션 결과에 대해 상당한 사용자 정의를 허용합니다. 이 도구는 데이터베이스에 구애받지 않도록 설계되었으며 매우 다재다능합니다. 또한 직관적인 UI를 제공하여 공격 설정을 훨씬 쉽게 만들어 줍니다. Python gevent도 구현되어 있어 BBQSQL을 매우 빠르게 만듭니다.
저희는 도구를 UI에서 공격을 설정할 때 매우 자명하게 작동하도록 작성하려고 노력했습니다. 그러나 철저함을 위해 세부적인 README를 포함시켰으며, 각 구성 옵션의 세부 사항에 대한 추가적인 통찰을 제공할 것입니다. 한 가지 주의할 점은 UI의 모든 구성 옵션에 설명이 포함되어 있어, 이 페이지를 읽지 않고 도구를 실행하더라도 공격을 진행할 수 있을 것입니다.
다른 SQL 인젝션 도구와 유사하게 특정 요청 정보를 제공해야 합니다.
일반적인 정보를 제공해야 합니다:
그런 다음 인젝션이 발생할 위치와 어떤 구문을 주입할지 지정합니다. 자세한 내용은 계속 읽어보세요.
이 과정은 간단해야 하지만, 그렇지 않은 경우가 있습니다. 다음을 시도해 보세요:
sudo pip install bbqsql
작동하지 않으면 소스에서 설치할 수 있습니다. 도구는 gevent, requests가 필요합니다.
메뉴에서 BBQSQL 옵션을 위한 공간을 볼 수 있습니다. 여기서 다음 옵션을 지정합니다:
이에 대한 자세한 설명은 아래 쿼리 구문 개요에 나와 있습니다.
결과를 출력할 파일의 이름입니다. 파일 출력이 필요하지 않으면 비워 둡니다.
BBQSQL은 블라인드 SQL 인젝션 공격을 수행할 때 두 가지 기술을 사용합니다. 첫 번째이자 기본 기술은 binary_search입니다. 자세한 내용은 위키피디아를 참조하세요.
두 번째 기술은 frequency_search입니다. 빈도 검색은 영어의 분석을 기반으로 문자가 발생할 빈도를 결정합니다. 이 검색 방법은 엔트로피가 없는 데이터에 대해 매우 빠르지만, 영어가 아닌 데이터나 난독화된 데이터에 대해서는 느릴 수 있습니다.
이 매개변수의 값으로 binary_search 또는 frequency_search를 지정할 수 있습니다.
이것은 발견한 SQL 인젝션 유형을 지정합니다. 여기서 bbqsql이 true/false를 결정하기 위해 HTTP 응답의 어떤 속성을 볼지 설정합니다.
다음을 지정할 수 있습니다: status_code, url, time, size, text, content, encoding, cookies, headers, history
서버 상태 코드가 다른 SQL 인젝션을 식별했다면 여기에 'status_code'를 설정합니다. 쿠키가 다르면 'cookie'를 설정합니다. 응답 크기가 다르면 'size'를 설정합니다. 대략 이해하셨을 것입니다.
동시성은 Python의 gevent 라이브러리를 기반으로 합니다. 기능적으로는 스레딩처럼 보이지만, 이 작동 방식의 구체적인 내용은 DefCon 강연에서 확인할 수 있습니다 [여기에 링크 삽입]. 이 설정은 공격을 실행할 동시성 양을 제어합니다. 이는 요청을 제한하고 공격 시간을 단축하는 데 유용합니다. nginx와 같은 고성능 웹 서버의 경우 동시성을 75로 설정할 수 있었습니다. 기본값은 '30'으로 설정되어 있습니다.
어떤 이상한 특징(예: 특정 문자를 포함할 수 없거나 ASCII/CHAR 같은 함수가 작동하지 않음)이 있는 SQL 인젝션 취약점을 발견했다면, 아마도 사용자 정의 인젝션 구문으로 일종의 스크립트를 작성했을 것입니다. BBQSQL은 스크립팅 부분을 없애고 사용자 정의 쿼리 구문을 붙여넣고 쉽게 익스플로잇할 수 있는 방법을 제공합니다.
쿼리 입력은 데이터베이스에서 정보를 추출하는 데 사용할 쿼리를 구성하는 곳입니다. 이미 취약한 매개변수에서 SQL 인젝션을 식별하고 성공적인 쿼리를 테스트했다고 가정합니다.
다음은 쿼리를 구성하는 데 사용할 수 있는 예시 쿼리입니다.
이 예에서 공격자는 데이터베이스 버전을 선택하려고 합니다:
vulnerable_parameter'; if(ASCII(SUBSTRING((SELECT @@version LIMIT 1 OFFSET ${row_index}) , ${char_index} ,1))) ${comparator:>}ASCII(${char_val}) WAITFOR DELAY '0\:0\:0${sleep}'; --
쿼리 구문은 BBQSQL이 공격을 실행하는 방법을 알려주는 플레이스홀더를 기반으로 합니다.
공격이 작동하려면 다음 정보 플레이스홀더를 제공해야 합니다. 쿼리에 이를 넣으면 bbqSQL이 나머지를 처리합니다:
${row_index}: bbqSQL에 여기서 행을 반복하도록 지시합니다. LIMIT를 사용하므로 ${row_index} 값에 따라 n개의 행을 볼 수 있습니다.
${char_index}: bbqSQL에 하위 선택에서 어떤 문자를 쿼리할지 지시합니다.
${char_val}: bbqSQL에 하위 선택의 결과를 비교할 위치를 지시하여 결과를 검증합니다.
${comparator}: 응답을 비교하여 결과가 참인지 거짓인지 결정하는 방법을 BBQSQL에 알려줍니다. 기본적으로 > 기호가 사용됩니다.
${sleep}: 선택 사항이지만, 시간 기반 SQL 인젝션을 수행할 때 bbqSQL에 지연 시간(초)을 삽입할 위치를 알려줍니다.
이러한 플레이스홀더가 모두 필요한 것은 아닙니다. 예를 들어, 반블라인드 부울 기반 SQL 인젝션을 발견했다면 ${sleep} 매개변수를 생략할 수 있습니다.
BBQSQL에는 공격을 설정할 때 구성할 수 있는 많은 HTTP 매개변수가 있습니다. 최소한 URL, 인젝션 쿼리가 실행될 위치, 메서드를 제공해야 합니다. 다음 옵션을 설정할 수 있습니다:
인젝션 쿼리가 삽입될 위치를 템플릿 ${injection}을 사용하여 지정합니다. 인젝션 템플릿이 없으면 도구가 쿼리를 어디에 삽입해야 할지 알 수 없습니다.
요청과 함께 전송할 파일을 제공합니다. 값을 경로로 설정하면 BBQSQL이 파일 열기/포함을 처리합니다.
요청과 함께 전송할 HTTP 헤더입니다. 문자열 또는 사전일 수 있습니다. 예:
{"User-Agent":"bbqsql"}
또는
"User-Agent: bbqsql"
요청과 함께 전송할 쿠키의 사전 또는 문자열입니다. 예:
{"PHPSESSIONID":"123123"}
또는
PHPSESSIONID=123123;JSESSIONID=foobar
요청을 보낼 URL을 지정합니다.
HTTP 리디렉션을 요청 시 따를지 여부를 결정하는 부울 값입니다.
요청에 사용할 HTTP 프록시를 사전으로 지정합니다. 예:
{"http": "10.10.1.10:3128","https": "10.10.1.10:1080"}
요청과 함께 전송할 POST 데이터를 지정합니다. 문자열 또는 사전일 수 있습니다. 예:
{"input_field":"value"}
또는
input_field=value
HTTP 요청의 메서드를 지정합니다. 유효한 메서드는 다음과 같습니다:
'get','options','head','post','put','patch','delete'
HTTP 기본 인증에 사용할 사용자 이름과 비밀번호의 튜플을 지정합니다. 예:
("myusername","mypassword")
UI에서 공격을 설정한 후 구성 파일을 내보낼 수 있습니다. 도구를 실행하면 옵션이 표시됩니다. 내보낸 구성 파일은 ConfigParser를 사용하며 읽기 쉽습니다. 예시 구성 파일은 아래와 같습니다:
`[Request Config] url = http://example.com/sqlivuln/index.php?username=user1&password=secret${injection} method = GET
[HTTP Config] query = ' and ASCII(SUBSTR((SELECT data FROM data LIMIT 1 OFFSET ${row_index:1}),${char_index:1},1))${comparator:>}${char_val:0} # technique = binary_search comparison_attr = size concurrency = 30`
이는 공격을 재개하거나 쿼리를 조정할 때 유용하며, 모든 옵션을 다시 구성하는 번거로움을 피할 수 있습니다.
명령줄 또는 사용자 인터페이스에서 구성을 가져올 수 있습니다. 명령줄에서 구성을 가져오려면 다음 옵션으로 bbqsl을 실행하세요:
bbqsql -c config_file
명령줄 또는 사용자 인터페이스를 통해 구성 파일을 로드하면 동일한 유효성 검사 루틴이 매개변수에 실행되어 유효한지 확인합니다.
때로는 정말 특이한 작업을 수행해야 할 때가 있습니다. 필드에 들어가는 값을 암호화하거나 요청을 보내기 전에 삼중 URL 인코딩을 해야 할 수도 있습니다. 이러한 상황은 다른 도구를 사용 불가능하게 만듭니다. BBQSQL은 도구가 요청의 여러 지점에서 호출할 "훅" 함수를 정의할 수 있게 합니다. 예를 들어, 요청을 인수로 받아 필요한 변형을 수행한 후 수정된 요청을 서버로 보내는 pre_request 함수를 지정할 수 있습니다.
이를 구현하려면 Python 파일을 만들고 훅 함수를 지정하세요. 사용 가능한 함수 이름은 아래에 나열되어 있습니다. 훅 파일에서 이러한 훅 함수를 원하는 만큼 적게 또는 많이 정의할 수 있습니다. 그런 다음 메뉴의 bbqsql_options 섹션에서 훅 파일의 위치를 지정할 수 있습니다. BBQSQL은 이 파일을 읽어 정의한 모든 훅을 사용합니다.
지정하는 훅 함수의 이름이 정확히 아래에 명시된 이름이어야 함이 중요합니다. 그렇지 않으면 BBQSQL이 언제 어떤 훅을 호출해야 할지 알 수 없습니다. args 함수는 HTTP 요청을 생성하는 데 사용되는 모든 인수를 포함하는 하나의 매개변수를 받습니다. pre_request 함수는 요청이 전송되기 전에 요청 객체를 받습니다. post_request 함수는 요청이 전송된 직후 요청 객체를 받습니다. response 함수는 응답이 BBQSQL로 반환되기 전에 응답 객체를 받습니다.
다음 훅을 사용할 수 있습니다:
args: Request()에 전송되는 인수의 사전입니다.
pre_request: 전송되기 직전의 Request 객체입니다.
post_request: 전송된 직후의 Request 객체입니다.
response: Request에서 생성된 응답입니다.
이러한 훅이 어떻게 작동하는지, 그리고 hooks 사전이 어떻게 보여야 하는지에 대한 자세한 내용은 requests 라이브러리 문서의 훅 섹션을 확인하세요.
예시 훅 파일은 다음과 같을 수 있습니다:
# file: hooks.py
import time
def pre_request(req):
"""
this hook replaces a placeholder with the current time
expecting the url to look like this:
http://www.google.com?k=v&time=PLACEHOLDER
"""
req.url = req.url.replace('PLACEHOLDER',str(time.time()))
return req
버그 수정이나 기능 요청은 https://github.com/Neohapsis/bbqsql/ 에 제출해 주세요.
물론입니다! 저희는 이것이 완전한 기능을 갖춘 SQL 인젝션 프레임워크를 구축하기 위한 훌륭한 출발점이 될 것이라고 생각합니다. 코드를 포크하고 유용한 변경 사항이 있으면 병합하겠습니다.
BBQ는 정말 맛있고, SQL 인젝션도 마찬가지입니다!