요즘 http request smuggling 공격에 대해 몇일간 공부 중이다. 몇달 전에 이 공격을 처음 접하게 되면서 이 공격에 대해 매우 흥미를 느꼈다. http request smuggling 공격에 대해 portswigger 라는 홈페이지에서 자료를 통해 공부를 했고 실습 환경을 만들어 공부 해보면 어떻까 라는 생각을 해서 이렇게 글로 정리를 해본다.

 

이 실습 환경 만든다고 개고생 했다.. 삽질한 것을 바탕으로 아래 글에 나와 있는데로 진행할 경우 성공할 것이라고 생각한다.

 

필자가 참고한 사이트는 아래 Reference에 있으니 참고 하길 바란다.

 

 

 


# 1. Setting Practice Environment

https://paper.seebug.org/1049

HTTP request smuggling 공격 환경을 만들기 위해서는 사용자와 메인 서버 사이에 proxy 서버가 필요하다.

필자는 Apache Traffic Server(ATS) 7.1.2 버전을 사용했다.

ATS 7.1.2 보다 상위 버전은 이 공격에 대해 petch가 되어 있기 때문에 7.1.2 버전을 사용해야 한다.

또한 ubuntu 18.04 이상 버전에서 ATS 7.1.2 에 버그가 있어서 ubuntu 16.04 버전을 사용해야 한다.

== Proxy Server ==
ubuntu 16.04 (버전 중요!)
Apache Traffic Server 7.1.2 (버전 중요!)

 

LNMP 서버와 LAMP 서버를 세팅해야 하는데, docker를 이용해서 이 두 서버를 생성할 계획이다.

아래는 LNMP와 LAMP 서버를 구축하기 위한 정보이다.

== LNMP ==

docker-compose.yml

web:
 image: fbraz3/lnmp
 ports:
 - "10000"
== LAMP ==

docker pull mattrayner/lamp:latest-1804
docker run -d -p 10001 [image hash]

 

 

# 1-1. ATS Install & Configuration

 

여기서 부터 모든 명령어를 root 또는 sudo 로 진행하는 것을 강력히 추천한다.

 

본인 서버에 ATS를 설치하기 위해, 아래와 같은 명령어로 필요한 것들을 설치 해야한다.

apt-get install -y autoconf automake libtool pkg-config libmodule-install-perl gcc libssl-dev libpcre3-dev libcap-dev libhwloc-dev libncurses5-dev libcurl4-openssl-dev flex tcl-dev net-tools vim curl wget

 

ATS source 파일을 다운 받기 위해 아래와 같은 명령어를 입력하여 ATS 7.1.2 파일을 다운 후 압축을 푼다.

$ wget https://github.com/apache/trafficserver/archive/7.1.2.tar.gz
$ gzip -d [ATS 7.1.2 file name]
$ tar -xvf [ATS 7.1.2 file name]

 

압축을 푼 폴더로 이동해서 아래와 같은 명령어를 입력한다. (모든 명령어는 root 또는 sudo 로 진행하는 것을 추천한다.) make 명령어에서 30분에서 1시간 정도 걸릴 것이다.

$ cd trafficserver-7.1.2
$ autoreconf -if
$ ./configure --prefix=/opt/ts-712
$ make
$ make install

 

여기까지가 ATS 설치이고 이후는 설정이다.

records.config 파일을 열어 몇몇 옵션을 변경해야 한다. (추가하는 것이 아니라 변경이다.)

$ vi /opt/ts-712/etc/trafficserver/records.config

CONFIG proxy.config.http.cache.http INT 0 # close caching
CONFIG proxy.config.reverse_proxy.enabled INT 1 # Enable reverse proxy
CONFIG proxy.config.url_remap.remap_required INT 1 # Limit ATS to only access the mapped address in the map table
CONFIG proxy.config.http.server_ports STRING 80 80:ipv6 # Listen local port 80

 

위 파일을 수정했다면, remap.config 파일을 수정해야한다.

이 파일은 어느 서버로 포워딩 할 것인지 proxy 설정 파일이라고 생각하면 된다.

$ vi /opt/ts-712/etc/trafficserver/remap.config

map http://your-domain1.com/ http://[docker-lnmp-ip]:10000/
map http://your-domain2.com/ http://[docker-lamp-ip]:10001/

아직 docker로 lamp와 lnmp 를 설치 하지 않아서 localhost 라고 적어놓자.

그렇기 때문에 원래 ATS 를 재시작해야 하는데, 일단 이 상태로 둔다.

 

 

# 1-2. Docker LNMP Install & Configuration

(Docker를 찬양하라~)

 

혹시 본인 서버에 docker와 docker-compose가 설치 되어 있지 않다면 설치를 먼저 하자.

 

docker-compose.yml 파일을 생성하여 아래 내용을 복붙하자.

(port를 변경하고 싶다면 원하는 것으로 바꿔도 상관없다. 단, ATS remap.conf 파일에 적었던 port 도 바꿔줘야 할것이다.)

web:
 image: fbraz3/lnmp
 ports:
 - "10000"

 

아래 명령어로 docker container 를 생성한다.

$ docker-compose up -d

 

container가 생성이 되면 안으로 들어가 설정을 바꾼다.

$ docker exec -it [container ID] /bin/bash

root@[container ID]: vi /etc/nginx/site-enabled/default

listen 80을 listen 10000 으로 변경
root /app/~ 되어 있는 것을 root /var/www/html 로 변경
root@[container ID]: service nginx restart
root@[container ID]: cd /var/www/html
root@[container ID]: echo "<?php echo 'test'; ?>" > index.php
root@[container ID]: ls
index.php

 

docker LNMP 의 내부 IP를 알아야 하므로 아래 명령어로 IP를 알아낸다.

필자의 LNMP 내부 IP는 172.17.0.2 이다.

root@[container ID]: apt-get update && apt-get install net-tools
root@[container ID]: ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 2884  bytes 21085517 (21.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2624  bytes 243512 (243.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

container를 빠져나와 아래와 같은 명령어로 접속이 잘 되는지 확인한다.

$ wget 172.17.0.2:10000

--2020-03-22 04:23:40--  http://172.17.0.2:10000/
Connecting to 172.17.0.2:10000... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'index.html'
index.html                            [ <=>                                                          ]     332  --.-KB/s    in 0s      
2020-03-22 04:23:42 (8.65 MB/s) - 'index.html' saved [332]


$ cat index.html
test
$

 

위에서 ATS remap.conf 파일을 수정했었는데, 다시 열어서 LNMP 서버의 IP 주소를 적는다.

$ vi /opt/ts-712/etc/trafficserver/remap.config

map http://your-domain1.com/ http://172.17.0.2:10000/		# <---- 변경 부분
map http://your-domain2.com/ http://[docker-lamp-ip]:10001/

 

 

 

# 1-3. Docker LAMP Install & Configuration

 

아래 명령어를 입력하여 LAMP 이미지를 다운 받는다.

$ docker pull mattrayner/lamp:latest-1804
$ docker run -d -p 10001 [image hash]

LAMP 설치는 끝이다.(와우!)

아래는 설정 부분이다.

 

$ docker exec -it [container ID] /bin/bash

root@[container ID]: vi /etc/apache2/port.config

Listen 80 을 Listen 10001 으로 바꾸기
root@[container ID]: vi /etc/apache2/site-enabled/000-default

<VirtualHost: *:80> 을 10001 으로 바꾸기 (숫자만 바꿈)
root@[container ID]: service apache2 restart
root@[container ID]: cd /var/www/html
root@[container ID]: rm index.php
root@[container ID]: echo "<?php echo 'test'; ?>" > index.php
root@[container ID]: ls
inde.php

 

이번에도 역시 wget 명령어로 잘 되는지 확인한다.

root@[container ID]: wget localhost:10001

 

LAMP 내부 IP를 알아야 하기 때문에 아래와 같은 명령어를 입력한다.

필자는 172.17.0.3 이다.

root@[container ID]: apt-get update && apt-get install net-tools
root@[container ID]: ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 2884  bytes 21085517 (21.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2624  bytes 243512 (243.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

container에서 나와서 remap,conf 파일을 수정한다.

$ vi /opt/ts-712/etc/trafficserver/remap.config

map http://your-domain1.com/ http://172.17.0.2:10000/		
map http://your-domain2.com/ http://172.17.0.3:10001/  # <---- 변경 부분

 

 

 

# 2. Run ATS

 

모든 환경이 다 만들어 졌다.

우리는 ATS 7.1.2 프록시 서버와 내부 LNMP, LAMP 서버도 구축을 완료했다.

https://paper.seebug.org/1049

내부에서는 LNMP와 LAMP 웹 서버가 잘 동작한다. 하지만 ATS 서버는 설정만 했지 서비스로는 동작을 하지 않고 있기 때문에 이를 동작하게 해줘야 한다.

 

ATS를 다운받아 압축을 푼 경로로 이동한다.

cmd 폴더 안에는 여러개의 명령어 폴더가 존재한다. 여기서 우리가 사용할 것은 traffic_ctl과 traffic_manager 이다.

$ cd trafficserver-7.1.2/cmd
$ ls
Makefile     Makefile.in  traffic_crashlog  traffic_layout   traffic_top  traffic_wccp
Makefile.am  traffic_cop  traffic_ctl       traffic_manager  traffic_via

 

서버를 서비스하려면 traffic_manager 폴더로 들어가 traffic_manager 파일을 실행한다.

실행하면 2~3줄 정도 출력 될 것이다.

$ cd traffic_manager
$ ./traffic_manager

[ 대충 서비스가 시작된다는 내용 ]

 

자 이제 http://your-domain1.com 으로 웹 브라우저로 요청을 보내면 test 라는 문장이 웹 페이지에 보일 것이다.

마찬가지로 http://your-domain2.com 도 웹 바라우저로 요청을 보내면 똑같은 결과를 얻을 수 있을 것이다.

 

만약 ATS 설정을 바꿔야 하는 상황이 발생한다면, 설정 파일을 수정한 후, 아래 명령어를 입력한다.

$ cd trafficserver-7.1.2/cmd/traffic_ctl
$ ./traffic_ctl server restart

traffic_ctl은 서버 관련해서 서버를 재시작하거나 등등의 역할을 한다.

위 명령어를 입력하면 아까 ./traffic_manager 를 실행한 터미널에서 자동으로 중지 후 재시작하는 메시지가 출력이 되었을 것이다.

 

더 자세한 명령어는 아래 사이트를 참고하자.

https://github.com/apache/trafficserver

https://docs.trafficserver.apache.org/

 

 

 

 

# 3. After..

 

ㅠㅠ 정말 http request smuggling 공격 실습하려고 x랄 을 다하면서 했는데 결국 성공했다.

ubuntu 18.04 에서 계속 하다가 이 버전에서는 ATS 7.1.2 버그가 있고 상위 버전을 쓰면 http request smuggling 공격은 패치 되서 막막... 결국 ubuntu 16.04 버전에서 진행하고.. ATS 서비스는 어떻게 시작하는지... 역시 구글링이 답이었다.

 

아래 Reference 를 보고 정리 목적으로 작성했기 때문에 이 이상으로 환경 및 실습을 세팅하고 싶다면 

https://paper.seebug.org/1049/ 

사이트를 추천한다.

 

 

 

 

 

 

# 4. Reference

 

< http request smuggling 공격 관련 >

https://portswigger.net/web-security/request-smuggling

https://paper.seebug.org/1049/

< Apache Traffic Server 관련 >
https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-traffic-server-as-a-reverse-proxy-on-ubuntu-14-04
https://github.com/apache/trafficserver
https://docs.trafficserver.apache.org/

 

< 실습 환경 lnmp 설치 >
https://hub.docker.com/r/fbraz3/lnmp

< 실습 환경 lamp 설치 >
https://hub.docker.com/r/fauria/lamp/