fragrout和jolt2发送的都是乱序和不完整的ip碎片,不能重组成完整的上层报文,因为他么是用来模拟碎片攻击的,为了通过碎片来发送一个完整的ip包,鄙人对jolt2的代码做了些许修改。
声明:如有转载,请著名出处和作者信息。
- //ipdefrag.c mod from jolt2.c by cme@2010-06-11 <duanjigang1983@126.com, QQ:84025840>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <unistd.h>
-
#include <string.h>
-
#include <netdb.h>
-
#include <sys/socket.h>
-
#include <sys/types.h>
-
#include <netinet/in.h>
-
#include <netinet/ip.h>
-
#include <netinet/ip_icmp.h>
-
#include <netinet/udp.h>
-
#include <arpa/inet.h>
-
#include <getopt.h>
-
#define DATA_LEN 8
-
struct
-
{
-
struct iphdr ip;
-
union
-
{
-
struct icmphdr icmp;
-
struct udphdr udp;
-
} proto;
-
char data[DATA_LEN];
-
} first_pkt;
-
struct
-
{
-
struct iphdr ip;
-
char data[DATA_LEN];
-
} data;
-
int icmplen = sizeof(struct icmphdr),
-
udplen = sizeof(struct udphdr),
-
iplen = sizeof(struct iphdr),
-
spf_sck;
-
//1 按照自然序发送碎片 0 乱序发送碎片
-
#define send_pkt_in_turns 1
-
//发送碎片个数
-
#define send_time 20
-
void quit(char *reason)
-
{
-
perror(reason);
-
close(spf_sck);
-
exit(-1);
-
}
-
int do_frags (int sck, u_long src_addr, u_long dst_addr, int port)
-
{
-
int bs, psize;
-
unsigned long x;
-
struct sockaddr_in to;
-
u_int16_t seq = 0;
-
u_int16_t flag = 8192;
-
to.sin_family = AF_INET;
-
to.sin_port = 10000;
-
to.sin_addr.s_addr = dst_addr;
-
-
if (port)
-
{
-
psize = iplen + udplen + DATA_LEN;
-
}
-
else
-
{
-
psize = iplen + icmplen + DATA_LEN;
-
}
-
memset(&first_pkt, 0, psize);
-
-
first_pkt.ip.version = 4;
-
first_pkt.ip.ihl = 5;
-
first_pkt.ip.tot_len = htons(iplen + icmplen) + 40;
-
first_pkt.ip.ttl = 255;
-
first_pkt.ip.protocol = (port ? IPPROTO_UDP : IPPROTO_ICMP);
-
first_pkt.ip.saddr = src_addr;
-
first_pkt.ip.daddr = dst_addr;
-
-
-
if (port)
-
{
-
first_pkt.proto.udp.source = htons(port);
-
first_pkt.proto.udp.dest = htons(port);
-
first_pkt.proto.udp.len = htons(8);
-
} else
-
{
-
first_pkt.proto.icmp.type = ICMP_ECHO;
-
first_pkt.proto.icmp.code = 0;
-
first_pkt.proto.icmp.checksum = 0;
-
}
-
first_pkt.ip.frag_off = htons(8192);
-
first_pkt.ip.id = htons(1);
-
first_pkt.ip.saddr = src_addr;
-
strncpy(first_pkt.data, "aaaaaaaa", 8);
-
memcpy(&data.ip, &first_pkt.ip, sizeof(struct iphdr));
-
-
for (seq = 1; seq <= send_time; seq++)
-
{
-
int i = 0;
-
char ch;
-
switch(seq)
-
{
-
case 1: //first pkt, frag off is 00100000 00000000
-
data.ip.frag_off = htons(flag);
-
break;
-
case send_time: //last pkt, mf set to 0, frag off is 000xxxxx xxxxxxxx, xx is the seq value
-
data.ip.frag_off = htons(send_time); //last pkt mf is set to zero
-
break;
-
default:// pkt in middle, frag off is 001xxxxx xxxxxxxx
-
data.ip.frag_off =
-
send_pkt_in_turns ? htons(flag|(seq)):htons(flag|(send_time - seq + 1));
-
break;
-
}
-
ch = 'a' + seq - 1;
-
for (i = 0; i < DATA_LEN; i++)
-
{
-
data.data[i] = ch;
-
}
-
-
if (seq == 1)
-
bs = sendto(sck, &first_pkt, psize, 0,
-
(struct sockaddr *) &to, sizeof(struct sockaddr));
-
else
-
bs = sendto(sck, &data, psize - udplen, 0,
-
(struct sockaddr *) &to, sizeof(struct sockaddr));
-
}
-
return bs;
-
}
-
int main(int argc, char *argv[])
-
{
-
u_long src_addr, dst_addr;
-
int i, bs=1, port=0;
-
char hostname[32];
-
if (argc !=4)
-
{
-
printf ("usage:%s srcaddr dest_port destaddr\n");
-
return 0;
-
}
-
spf_sck = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-
if (!spf_sck)
-
quit("socket()");
-
if (setsockopt(spf_sck, IPPROTO_IP, IP_HDRINCL, (char *)&bs,
-
sizeof(bs)) < 0)
-
quit("IP_HDRINCL");
-
do_frags (spf_sck, inet_addr(argv[1]), inet_addr(argv[3]), atoi(argv[2]));
-
}