modified the changes
This commit is contained in:
23
Task pwn01/week01/client.py
Normal file
23
Task pwn01/week01/client.py
Normal file
@ -0,0 +1,23 @@
|
||||
import socket
|
||||
|
||||
# Fill in the right target here
|
||||
HOST = 'localhost' # TODO
|
||||
PORT = 20001 # TODO
|
||||
|
||||
|
||||
def get_flag():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
s.connect((HOST, PORT))
|
||||
sf = s.makefile('rw') # we use a file abstraction for the sockets
|
||||
|
||||
print(sf.readline().rstrip('\n'))
|
||||
sf.write('Hello World\n')
|
||||
sf.flush()
|
||||
|
||||
sf.close()
|
||||
s.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
get_flag()
|
87
Task pwn01/week01/server.py
Normal file
87
Task pwn01/week01/server.py
Normal file
@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3
|
||||
import dataclasses
|
||||
import random
|
||||
import string
|
||||
import asyncio
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
import ast
|
||||
from asyncio import StreamReader, StreamWriter
|
||||
from typing import TypeVar, Callable
|
||||
|
||||
from pwn_utils import utils
|
||||
from pwn_utils.utils import read_line_safe
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
clients = {} # task -> (reader, writer)
|
||||
|
||||
|
||||
def accept_client(client_reader: StreamReader, client_writer: StreamWriter):
|
||||
task = asyncio.Task(handle_client(client_reader, client_writer))
|
||||
clients[task] = (client_reader, client_writer)
|
||||
|
||||
def client_done(task):
|
||||
del clients[task]
|
||||
client_writer.close()
|
||||
log.info('connection closed')
|
||||
|
||||
task.add_done_callback(client_done)
|
||||
|
||||
|
||||
async def handle_client(client_reader: StreamReader, client_writer: StreamWriter):
|
||||
try:
|
||||
remote = client_writer.get_extra_info('peername')
|
||||
if remote is None:
|
||||
log.error('Could not get ip of client')
|
||||
return
|
||||
remote = '%s:%s' % (remote[0], remote[1])
|
||||
log.info('new connection from: %s' % remote)
|
||||
except Exception as e:
|
||||
log.error('EXCEPTION (get peername): %s (%s)' % (e, type(e)))
|
||||
return
|
||||
|
||||
try:
|
||||
client_writer.write('Please enter username:\n'.encode())
|
||||
await client_writer.drain()
|
||||
username = await read_line_safe(client_reader)
|
||||
if username != 'admin':
|
||||
client_writer.write('Invalid username\n'.encode())
|
||||
await client_writer.drain()
|
||||
return
|
||||
client_writer.write('Please enter password:\n'.encode())
|
||||
await client_writer.drain()
|
||||
|
||||
password = await read_line_safe(client_reader)
|
||||
if password != 'password':
|
||||
client_writer.write('Invalid password\n'.encode())
|
||||
await client_writer.drain()
|
||||
return
|
||||
client_writer.write('Welcome admin\n'.encode())
|
||||
await client_writer.drain()
|
||||
flag = subprocess.check_output('flag')
|
||||
client_writer.write(flag)
|
||||
await client_writer.drain()
|
||||
except Exception as e:
|
||||
utils.log_error(e, client_writer)
|
||||
|
||||
|
||||
def main():
|
||||
# start server
|
||||
loop = asyncio.get_event_loop()
|
||||
f = asyncio.start_server(accept_client, host=None, port=20001)
|
||||
log.info('Server waiting for connections')
|
||||
loop.run_until_complete(f)
|
||||
loop.run_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s',
|
||||
)
|
||||
|
||||
# "INFO:asyncio:poll took 25.960 seconds" is annyoing
|
||||
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
||||
|
||||
main()
|
@ -15,55 +15,73 @@ log = logging.getLogger(__name__)
|
||||
TCP_CLIENTS = {} # ((IP, port) -> [sent_packets])
|
||||
|
||||
# SERVER_IP = '131.159.15.68' # don't use the domain name in this case
|
||||
|
||||
SERVER_IP = "127.0.0.1" # don't use the domain name in this case
|
||||
SERVER_IP = '127.0.0.1' # don't use the domain name in this case
|
||||
SERVER_PORT = 20102
|
||||
COOKIE_SECRET = "TASTY_COOKIES123"
|
||||
COOKIE_SECRET = 'TASTY_COOKIES123'
|
||||
|
||||
SRC_PORT = randrange(10000, 50000)
|
||||
|
||||
|
||||
def generate_syn_cookie(client_ip: str, client_port: int, server_secret: str):
|
||||
# TODO: please implement me!
|
||||
return 0
|
||||
hash_input = f'{client_ip}{client_port}{server_secret}'.encode()
|
||||
return int(hashlib.sha256(hash_input).hexdigest(), 16) % (2**32)
|
||||
|
||||
|
||||
def handle_packet(packet: Packet):
|
||||
# TODO: please implement me!
|
||||
packet.show()
|
||||
if packet.haslayer(TCP) and packet[TCP].dport == SRC_PORT and "S" == packet[TCP].flags:
|
||||
server_seq = packet[TCP].seq
|
||||
ip = IP(dst=SERVER_IP)
|
||||
ack = TCP(sport=SRC_PORT, dport=SERVER_PORT, flags='A', seq=packet[TCP].ack, ack=1337)
|
||||
send(ip / ack)
|
||||
print("Sent ACK packet with modified ACK number:", server_seq)
|
||||
|
||||
|
||||
|
||||
|
||||
# Function to send the initial SYN packet
|
||||
def send_initial_syn():
|
||||
# Generate the SYN cookie
|
||||
cookie = generate_syn_cookie(SERVER_IP, SERVER_PORT, COOKIE_SECRET)
|
||||
|
||||
# Construct the IP and TCP layers
|
||||
ip = IP(dst=SERVER_IP)
|
||||
syn = TCP(sport=SRC_PORT, dport=SERVER_PORT, flags='S', seq=cookie)
|
||||
|
||||
# Send the packet
|
||||
send(ip / syn)
|
||||
print("Sent initial SYN packet with cookie:", cookie)
|
||||
|
||||
|
||||
# Function to start the packet sniffing
|
||||
def start_sniffing():
|
||||
def start_sniffing():
|
||||
sniff(
|
||||
filter=f"tcp port {SERVER_PORT}", # this should filter all packets relevant for this challenge.
|
||||
filter=f'tcp port {SERVER_PORT}', # this should filter all packets relevant for this challenge.
|
||||
prn=handle_packet,
|
||||
store=False,
|
||||
monitor=True,
|
||||
iface="eth0", # set to your interface. IMPORTANT: SET TO enX0 FOR AUTOGRADER!!!
|
||||
iface='lo', # set to your interface. IMPORTANT: SET TO enX0 FOR AUTOGRADER!!!
|
||||
)
|
||||
|
||||
|
||||
COOKIE = generate_syn_cookie(SERVER_IP, SERVER_PORT, COOKIE_SECRET)
|
||||
|
||||
|
||||
# Run the server in a separate thread
|
||||
def main():
|
||||
conf.use_pcap = False
|
||||
server_thread = threading.Thread(target=start_sniffing)
|
||||
server_thread.start()
|
||||
|
||||
time.sleep(1) # wait for the sniffer to start.
|
||||
time.sleep(3) # wait for the sniffer to start.
|
||||
|
||||
# TODO: send intial first byte
|
||||
# TODO: send intial first byte
|
||||
send_initial_syn()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s",
|
||||
format='%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s',
|
||||
)
|
||||
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
||||
|
||||
main()
|
||||
|
@ -12,9 +12,10 @@ from scapy.sendrecv import send, sniff
|
||||
log = logging.getLogger(__name__)
|
||||
TCP_CLIENTS = {} # ((IP, port) -> [sent_packets])
|
||||
|
||||
SERVER_IP = "127.0.0.1" # TODO
|
||||
# SERVER_IP = '131.159.15.68' # TODO
|
||||
SERVER_IP = '127.0.0.1'
|
||||
SERVER_PORT = 20102
|
||||
COOKIE_SECRET = "TASTY_COOKIES123"
|
||||
COOKIE_SECRET = 'TASTY_COOKIES123'
|
||||
INITIAL_SEQ = 1337
|
||||
|
||||
|
||||
@ -22,115 +23,116 @@ INITIAL_SEQ = 1337
|
||||
# converting the hex digest to an integer
|
||||
# The cookie is then this result modulo 2^32 to fit the 32-bit field
|
||||
def generate_syn_cookie(client_ip: str, client_port: int, server_secret: str):
|
||||
hash_input = f"{client_ip}{client_port}{server_secret}".encode()
|
||||
hash_input = f'{client_ip}{client_port}{server_secret}'.encode()
|
||||
return int(hashlib.sha256(hash_input).hexdigest(), 16) % (2**32)
|
||||
|
||||
|
||||
def get_initial_syn(ip, port, ack) -> Packet:
|
||||
ip = IP(dst=ip)
|
||||
syn = TCP(sport=SERVER_PORT, dport=port, flags="SA", seq=INITIAL_SEQ, ack=ack)
|
||||
syn = TCP(sport=SERVER_PORT, dport=port, flags='SA', seq=INITIAL_SEQ, ack=ack)
|
||||
return ip / syn
|
||||
|
||||
|
||||
def get_rst(ip, port, ack) -> Packet:
|
||||
ip = IP(dst=ip)
|
||||
syn = TCP(sport=SERVER_PORT, dport=port, flags="R", seq=INITIAL_SEQ, ack=ack)
|
||||
syn = TCP(sport=SERVER_PORT, dport=port, flags='R', seq=INITIAL_SEQ, ack=ack)
|
||||
return ip / syn
|
||||
|
||||
|
||||
def handle_packet(packet: Packet):
|
||||
print("Received a packet on the server:", packet.summary())
|
||||
if packet.haslayer(TCP) and packet[TCP].dport == SERVER_PORT:
|
||||
if "F" in packet[TCP].flags or "R" in packet[TCP].flags:
|
||||
print("Received FIN or Reset packet:", packet.summary())
|
||||
if 'F' in packet[TCP].flags or 'R' in packet[TCP].flags:
|
||||
print('Received FIN or Reset packet:', packet.summary())
|
||||
if (packet[IP].src, packet[TCP].sport) in TCP_CLIENTS:
|
||||
del TCP_CLIENTS[(packet[IP].src, packet[TCP].sport)]
|
||||
return
|
||||
|
||||
print("Received packet:", packet.summary())
|
||||
|
||||
|
||||
print('Received packet:', packet.summary())
|
||||
|
||||
# Extract the TCP layer
|
||||
tcp_layer = packet[TCP]
|
||||
src_ip = packet[IP].src
|
||||
src_port = tcp_layer.sport
|
||||
seq = packet[TCP].seq
|
||||
ack = packet[TCP].ack
|
||||
|
||||
|
||||
expected_cookie = generate_syn_cookie(SERVER_IP, SERVER_PORT, COOKIE_SECRET)
|
||||
|
||||
|
||||
if (src_ip, src_port) not in TCP_CLIENTS:
|
||||
print("New client:", src_ip, src_port, seq)
|
||||
print('New client:', src_ip, src_port, seq)
|
||||
# first packet from client to initiate handshake
|
||||
|
||||
if (not "S" in packet[TCP].flags) or (
|
||||
not packet[TCP].seq == expected_cookie
|
||||
):
|
||||
print(f"Invalid cookie {seq}, expected {expected_cookie}")
|
||||
|
||||
|
||||
if (not 'S' in packet[TCP].flags) or (not packet[TCP].seq == expected_cookie):
|
||||
print(f'Invalid cookie {seq}, expected {expected_cookie}')
|
||||
rst = get_rst(src_ip, src_port, seq)
|
||||
send(rst)
|
||||
else:
|
||||
else:
|
||||
TCP_CLIENTS[(src_ip, src_port)] = 1
|
||||
initial_syn = get_initial_syn(src_ip, src_port, seq)
|
||||
|
||||
print(f"Cookie {expected_cookie} and packet is correct")
|
||||
print(f"Sending packet: {initial_syn.summary()}")
|
||||
|
||||
print(f'Cookie {expected_cookie} and packet is correct')
|
||||
print(f'Sending packet: {initial_syn.summary()}')
|
||||
send(initial_syn)
|
||||
|
||||
|
||||
else:
|
||||
if (
|
||||
("S" in packet[TCP].flags)
|
||||
or (not seq == expected_cookie)
|
||||
or (not ack == INITIAL_SEQ)
|
||||
):
|
||||
print(f"Invalid cookie {seq}, expected {expected_cookie}")
|
||||
if ('S' in packet[TCP].flags):
|
||||
print("S in flag")
|
||||
if (not ack == INITIAL_SEQ):
|
||||
print(ack)
|
||||
print("acak and seq different")
|
||||
if (not seq == expected_cookie):
|
||||
print("seq cookie")
|
||||
if ('S' in packet[TCP].flags) or (not seq == expected_cookie) or (not ack == INITIAL_SEQ):
|
||||
print(f'Invalid cookie {seq}, expected {expected_cookie}')
|
||||
rst = get_rst(src_ip, src_port, seq)
|
||||
send(rst)
|
||||
else:
|
||||
print(f"Cookie {expected_cookie} and packet is again correct")
|
||||
|
||||
flag = subprocess.check_output("flag").decode()
|
||||
print(f'Cookie {expected_cookie} and packet is again correct')
|
||||
|
||||
flag = "ALL GOOD BROTHER"
|
||||
ip = IP(dst=src_ip)
|
||||
syn_ack = (
|
||||
TCP(
|
||||
sport=SERVER_PORT,
|
||||
dport=src_port,
|
||||
flags="A",
|
||||
seq=ack,
|
||||
ack=seq,
|
||||
)
|
||||
/ flag
|
||||
)
|
||||
|
||||
syn_ack = TCP(
|
||||
sport=SERVER_PORT,
|
||||
dport=src_port,
|
||||
flags='A',
|
||||
seq=ack,
|
||||
ack=seq,
|
||||
) / flag
|
||||
|
||||
send(ip / syn_ack)
|
||||
|
||||
|
||||
del TCP_CLIENTS[(src_ip, src_port)]
|
||||
|
||||
|
||||
# Function to start the packet sniffing
|
||||
def start_sniffing():
|
||||
print("Starting TCP server on port:", SERVER_PORT)
|
||||
print('Starting TCP server on port:', SERVER_PORT)
|
||||
sniff(
|
||||
filter=f"tcp port {SERVER_PORT}",
|
||||
filter=f'tcp port {SERVER_PORT}',
|
||||
prn=handle_packet,
|
||||
store=False,
|
||||
monitor=True,
|
||||
iface="lo",
|
||||
iface='lo',
|
||||
)
|
||||
|
||||
|
||||
# Run the server in a separate thread
|
||||
def main():
|
||||
conf.use_pcap = False
|
||||
print("Server is starting...") # Added print statement
|
||||
server_thread = threading.Thread(target=start_sniffing)
|
||||
server_thread.start()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s",
|
||||
format='%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s',
|
||||
)
|
||||
|
||||
# "INFO:asyncio:poll took 25.960 seconds" is annyoing
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
||||
|
||||
main()
|
||||
|
@ -1,71 +0,0 @@
|
||||
import hashlib
|
||||
import logging
|
||||
import time
|
||||
import threading
|
||||
|
||||
from scapy.config import conf
|
||||
from scapy.layers.inet import TCP, IP
|
||||
from scapy.packet import Packet
|
||||
from scapy.sendrecv import send, sniff
|
||||
|
||||
from random import randrange
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
SERVER_IP = "127.0.0.1"
|
||||
SERVER_PORT = 20102
|
||||
COOKIE_SECRET = "TASTY_COOKIES123"
|
||||
SRC_PORT = randrange(10000, 50000)
|
||||
|
||||
|
||||
def generate_syn_cookie(client_ip: str, client_port: int, server_secret: str):
|
||||
hash_input = f"{client_ip}{client_port}{server_secret}".encode()
|
||||
return int(hashlib.sha256(hash_input).hexdigest(), 16) % (2**32)
|
||||
|
||||
|
||||
def handle_packet(packet: Packet):
|
||||
if (
|
||||
packet.haslayer(TCP)
|
||||
and packet[TCP].dport == SRC_PORT
|
||||
and "A" in packet[TCP].flags
|
||||
):
|
||||
print("Flag found in payload:", packet[TCP].payload)
|
||||
exit()
|
||||
|
||||
|
||||
# Function to start the packet sniffing
|
||||
def start_sniffing():
|
||||
sniff(
|
||||
filter=f"tcp port {SERVER_PORT}",
|
||||
prn=handle_packet,
|
||||
store=False,
|
||||
monitor=True,
|
||||
iface="lo",
|
||||
)
|
||||
|
||||
|
||||
# Run the server in a separate thread
|
||||
def main():
|
||||
conf.use_pcap = True
|
||||
server_thread = threading.Thread(target=start_sniffing)
|
||||
server_thread.start()
|
||||
|
||||
time.sleep(1) # wait for the sniffer to start.
|
||||
|
||||
# Calculate the SYN cookie to send
|
||||
cookie = generate_syn_cookie(SERVER_IP, SERVER_PORT, COOKIE_SECRET)
|
||||
|
||||
# Send SYN packet with correct cookie
|
||||
syn_packet = IP(dst=SERVER_IP) / TCP(
|
||||
sport=SRC_PORT, dport=SERVER_PORT, flags="S", seq=cookie
|
||||
)
|
||||
send(syn_packet)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s %(levelname)s [%(module)s:%(lineno)d] %(message)s",
|
||||
)
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
main()
|
Reference in New Issue
Block a user