diff --git a/Task pwn01/week01/client.py b/Task pwn01/week01/client.py new file mode 100644 index 0000000..0a02757 --- /dev/null +++ b/Task pwn01/week01/client.py @@ -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() diff --git a/Task pwn01/week01/server.py b/Task pwn01/week01/server.py new file mode 100644 index 0000000..0276cbf --- /dev/null +++ b/Task pwn01/week01/server.py @@ -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() diff --git a/Task pwn02/week02/easy/client.py b/Task pwn02/week02/easy/client.py index 22d71dc..485cad6 100644 --- a/Task pwn02/week02/easy/client.py +++ b/Task pwn02/week02/easy/client.py @@ -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() diff --git a/Task pwn02/week02/easy/server.py b/Task pwn02/week02/easy/server.py index 0d4cf56..5b41f00 100644 --- a/Task pwn02/week02/easy/server.py +++ b/Task pwn02/week02/easy/server.py @@ -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() diff --git a/Task pwn02/week02/easy/test.py b/Task pwn02/week02/easy/test.py deleted file mode 100644 index 173a33a..0000000 --- a/Task pwn02/week02/easy/test.py +++ /dev/null @@ -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()