commit 65986c1ca521ff6e9dcf74e57f45510f7e01763a Author: dongho Date: Wed Oct 30 21:58:10 2024 +0900 first commit diff --git a/Task pwn01/pwn01.zip b/Task pwn01/pwn01.zip new file mode 100644 index 0000000..e44f90a Binary files /dev/null and b/Task pwn01/pwn01.zip differ diff --git a/Task pwn01/question.png b/Task pwn01/question.png new file mode 100644 index 0000000..0c01f84 Binary files /dev/null and b/Task pwn01/question.png differ diff --git a/Task pwn02/week02 2/hard/client.py b/Task pwn02/week02 2/hard/client.py new file mode 100644 index 0000000..5da08fd --- /dev/null +++ b/Task pwn02/week02 2/hard/client.py @@ -0,0 +1,21 @@ +import socket + +# Fill in the right target here +HOST = 'localhost' # TODO +PORT = ... # 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 + + # TODO + + sf.close() + s.close() + + +if __name__ == '__main__': + get_flag() diff --git a/Task pwn02/week02 2/hard/description/description.pdf b/Task pwn02/week02 2/hard/description/description.pdf new file mode 100644 index 0000000..a1879bf Binary files /dev/null and b/Task pwn02/week02 2/hard/description/description.pdf differ diff --git a/Task pwn02/week02/easy/check_interface.py b/Task pwn02/week02/easy/check_interface.py new file mode 100644 index 0000000..c3be214 --- /dev/null +++ b/Task pwn02/week02/easy/check_interface.py @@ -0,0 +1,17 @@ +import netifaces + + +def print_ethernet_interfaces(): + """Prints all Ethernet interfaces and their IP addresses.""" + + interfaces = netifaces.interfaces() + for interface in interfaces: + addresses = netifaces.ifaddresses(interface) + if netifaces.AF_INET in addresses: + for addr in addresses[netifaces.AF_INET]: + ip_address = addr["addr"] + print(f"Interface: {interface}, IP Address: {ip_address}") + + +if __name__ == "__main__": + print_ethernet_interfaces() diff --git a/Task pwn02/week02/easy/client.py b/Task pwn02/week02/easy/client.py new file mode 100644 index 0000000..22d71dc --- /dev/null +++ b/Task pwn02/week02/easy/client.py @@ -0,0 +1,69 @@ +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__) +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_PORT = 20102 +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 + + +def handle_packet(packet: Packet): + # TODO: please implement me! + packet.show() + + +# Function to start the packet sniffing +def start_sniffing(): + sniff( + 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!!! + ) + + +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. + + # TODO: send intial first byte + + +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() diff --git a/Task pwn02/week02/easy/description/description.pdf b/Task pwn02/week02/easy/description/description.pdf new file mode 100644 index 0000000..1d55630 Binary files /dev/null and b/Task pwn02/week02/easy/description/description.pdf differ diff --git a/Task pwn02/week02/easy/server.py b/Task pwn02/week02/easy/server.py new file mode 100644 index 0000000..0d4cf56 --- /dev/null +++ b/Task pwn02/week02/easy/server.py @@ -0,0 +1,136 @@ +import hashlib +import logging +import subprocess + +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 + +log = logging.getLogger(__name__) +TCP_CLIENTS = {} # ((IP, port) -> [sent_packets]) + +SERVER_IP = "127.0.0.1" # TODO +SERVER_PORT = 20102 +COOKIE_SECRET = "TASTY_COOKIES123" +INITIAL_SEQ = 1337 + + +# The cookie is calculated by first taking the sha256 hash of (clientIP || clientPort || serverSecret) and then +# 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() + 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) + 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) + return ip / syn + + +def handle_packet(packet: Packet): + 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 (packet[IP].src, packet[TCP].sport) in TCP_CLIENTS: + del TCP_CLIENTS[(packet[IP].src, packet[TCP].sport)] + return + + 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) + # 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}") + rst = get_rst(src_ip, src_port, seq) + send(rst) + 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()}") + 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}") + 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() + ip = IP(dst=src_ip) + 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) + 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 = False + server_thread = threading.Thread(target=start_sniffing) + server_thread.start() + + +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/test.py b/Task pwn02/week02/easy/test.py new file mode 100644 index 0000000..173a33a --- /dev/null +++ b/Task pwn02/week02/easy/test.py @@ -0,0 +1,71 @@ +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()