USTC信息安全复习
信息安全复习
郭艳老师的信息安全课程
开胃菜
实现1994年圣诞节Kevin Minnick 对下村勉发动的攻击。
前备知识
几种典型的网络攻击
-
攻击ARP局域网,阻止局域网内系统正常联网
sudo netwox 80 -e MAC -i IP
-
ICMP重定向,成为受害者、网关之间的中间人
sudo netwox 86 --gw GWIP --src-ip SIP
-
TCP洪范攻击,SYN Flooding,Dos攻击。不过现在主机一般都有防止洪范措施,在实验中需要先关闭。
sudo netwox 76 -i TARGET_IP -p PORT
几个网络设备
- 网桥:连接局域网
- 网卡:计算机的一个网络管理硬件
- 网关:在传输层以上实现网络互联,可用于广域网和局域网,是一个翻译器
圣诞节攻击
攻击链条: Target的访问 <---> X-terminal <---> Server
- 对X-terminal:IP源地址欺骗和TCP序列号预测;
- 对Server:Dos攻击,使之不能(对意外SYN-ACK)发出RST;
一共使用了两种不同的攻击机制。 IP源地址欺骗和TCP序列号预测,使用这两种攻击获得了对主要用作X终端的无盘工作站的访问权。
在获得root访问权限之后,可加载内核STREAMS模块的方法劫持了与另一个系统的现有连接。
网络安全
ARP安全
Dos攻击:
netwox 80 使用ARP攻击,阻止局域网内系统正常联网
ARP:IP-->MAC
主机广播IP来寻找MAC,返回是单播;
然后(所有主机都)缓存IP--MAC的对应关系到ARP表,
但ARP表不是一成不变的,因为IP--MAC对应关系不断改变。(比如:虚拟机中的IP地址,多启动几回可能就换掉了)
局域网(以太网)帧格式:
帧类型 Frame types: 0800 IP 0806 ARP 8035 RARP
了解以太网帧的格式之后,就可以根据帧的结构发包;也可以借助netwox 80发ARP包,导致同在一个局域网的另一个主机不能联网。
IP协议安全
IP协议
具体分析:
-
首先是4 bit的协议字段:目前是4,代表IPv4;如果是IPv6,会有一个新的协议头部。
-
HLEN,表示包中IP头部的长度,它的单位是32 位,也就是4个字节,因此上面包中的5指示该数据包的IP头部的长度是4*5=20字节。
-
ToS:总共有八位,代表不同类型的服务,其中只能设置一位。常见的包括 min delay, 0x10; max throughput, 0x08;max reliability, 0x40; min cost, 0x20。
-
接下来是Total Length。以字节为单位的报文的长度。0054 --> 5X16+4=84Bytes
-
IDent,flags和 fragment offset(片偏移x8):一起用于数据包的分片和重组;后面详细讨论。【也是针对IP协议发起攻击的主要利用的字段】
-
TTL:Time to Live,由发送者启动,然后每经过一个路由器就减一。如果到达某一个路由器的时候数据包的TTL变为0,那么就被丢弃。可以有效地防止路由循环。
-
- Example: ping –t TTL IP allows us to specify the TTL field
- 思考: 如果修改数据包的TTL(定制数据包),一般需要root权限,那么为什么我们可以通过ping程序来修改TTL? 【实际上,发送ICMP数据包需要root权限】
- 思考:能不能找到一个TTL应用的例子?
- TraceRoute是如何实现的?
-
TYPE:IP报文中承载的数据的类型;
-
- 1, ICMP; 2 IGMP; 6 TCP; 17 UDP;
-
校验和:
-
- 16位补码;仅针对头部计算;每一条都需要重新计算;
-
源IP地址和目的IP地址。
-
IP选项,可省略。譬如,可以在IP头部中记录路由。
-
- 思考:IP选项的长度最长为多少? 20B~60B,最多60字节 (Fx4B=60B)
IP分片和重组
-
分片
IP fragmentation:IP分片功能
为什么需要分片功能?主要是因为硬件环境的MTU限制。一个IP报文最多可以达到65535的最大长度;但是网络硬件限制了帧的大小(以太网限制为1500字节)。
如何分片?(对应上面IP头部的第二行):
- IDENT: 也即identifier,用于标识IP报文段的唯一标识符;具有同一IDENT的片段属于同一个IP报文;
- FRAGMENT OFFSET: 简称FO,片偏移x8,指明当前片段在原始完整的IP报文中的位置(偏移)。该偏移的单位是8个字节。
- FLAGS: 【3个bit 独立工作】bit 0:保留; bit 1:不分片 bit 2:更多分片。如果此位是1,那么说明有更多分片,则不是最后一个分片。
-
重组
当接收方接收到分片,应该如何进行重组呢?在IP层上必须进行重组,将完整的数据包发到上层。
在IP协议的设计中就需要考虑一些问题:在路由器上上进行重组还是在目的主机进行重组? 重组发生在目的主机,分片发生在路由器上
如果某一个IP分片在路上因为各种原因 丢失,怎么办? 答:IP数据包全部重传,TCP不用
如果接收到的分片在Fragment Offset上出现的 重叠,怎么办?
如果 重组后大小超过65535,允许的最大值,怎么办?
IP攻击
-
Dos攻击
思路:攻击者构造两个分片,第一个分片的偏移为0;第二个分片的偏移是64800。
因为IP分片可以乱序到达,所以接收方会等待其他分片;同时会为其他分片分配内存空间。
相当于一个数据包会使用64K的内存。而且这段空间会持续保留15~255秒。这样,很快会耗尽主机的内存空间,造成DoS。
-
TearDrop攻击
TearDrop攻击的原理,在于构造两个分片。其中,第二个分片完全包含在第一个分片中。
这种攻击的成功,依赖于一种当分片发生重叠时,重组的方法。如果接收主机的实现中选择在发生重叠时,使用第一个分片来覆盖第二个分片的重叠内容,那么TearDrop攻击就能够成功。具体见下面分析:
处理重叠的方法(含有漏洞):
先把first 完全copy,然后计算copy_Second的长度:len=end- offset(after)=end- pre_end ,如果unsign类型的 len<0,就会产生一个非常大的数copy_Second_len,导致拷贝超多无关数据,导致内存占用过多以及系统崩溃
解决方法:
加上一个 if 判断语句,来保证 end-pre_end>0
-
分片攻击
防火墙通过数据包的包头信息,进行拦截(包过滤器防火墙)
RFC:互联网国际标准机构 Request For Comment
原有协议:有些端口阻止 外部访问请求,但是接受 对本机请求的回复(本机先发出请求)
漏洞是:只检查FO=0(第一个)数据片。
只要第一个混过去(包装成无害的样子),后面(具有同样IDentifier标识符的)分片可以跟着全部通过防火墙
-
微小碎片攻击
强迫TCP头部进入第二个分片,从而躲过防火墙过滤器的匹配(SYN)
-
重叠碎片攻击
用第二个分片(有害,SYN=1,ACK=0, FO==1),覆盖第一个无害分片(用于顶包接受检查,SYN=0, ACK=1)。
-
ICMP攻击
-
smurf攻击
Smurf攻击是一种DDOS攻击。
冒充受害者的IP地址,将大量ICMP的ECHO REQUEST广播到有大量主机的网络。默认情况下,网络上的大多数设备都会通过向源IP地址发送回复ECHO REPLY来对此做出响应。 如果网络上接收和响应这些数据包的机器数量非常大,受害者的计算机将忙于处理 ping 回复包。 这可能会使受害者的计算机变慢,无法继续工作。
防御手段?
-
配置各个主机和路由器,不响应ICMP请求或广播;
-
配置路由器不转发定向到广播地址的数据包。
-
-
ICMP重定向攻击
A:攻击者;B:受害者;C:受访问的网络
首先,当B要访问C网络的时候,会向当前网关发送访问请求。A通过pcap网络嗅探等工具捕获这一请求的时候,A冒充B的网关向B发送ICMP重定向报文,将网关地址重定向为虚假地址。当B收到A发送的重定向报文的时候,就会修改B的路由表,将访问C网络的网关地址改为重定向的地址。这样B上网会发生部分失败(因为路由器会更新正确的路由给B,但A会改成错的,两者互相改,造成部分对部分错)
防御手段:过滤掉ICMP重定向报文。
实验流程:1.pcap抓包得到受害者ip 2. 使用raw socket来手动修改ip、icmp里面的内容 3.开始发包,攻击受害者
TCP攻击
-
SYN flooding
A:攻击者;B:被攻击服务器;C:其他访问者
首先,B开放一个端口,进行侦听。A构造大量的TCP的SYN包发给B。
B一旦接收到SYN包就需要为即将建立的TCP连接分配TCB(Transmission Control Block),并进入半连接状态。由于B最多可开启的半开连接个数是一定的,受内存限制,当半开连接的个数过多,就会消耗掉可用的内存,使得新的正常的连接请求不能被处理。此时C对B进行访问,建立TCP连接的请求就不能被正常处理。
效果:Dos攻击--占用资源(内存、CPU、带宽),deny of service,拒绝正常的服务。(SYN flooding可以以小博大)
防止:
1. SYN Cookie:在(第三握)ACK到达之前不分配任何资源。
SYN Cookie关键在于:如何在不分配资源的同时,能够识别是否是一个完整的TCP三次握手。 SYN cookie精心构建初始序列号:t、m、s来验证。
2. SYNCache:四元组<源ip,源port,目的ip,目的port>,那么可以在接收到SYN包时,仅仅分配有限的空间,来维持其后可能需要的信息,而不是分配整个的TCP控制块。到第三步才分配。
-
nmap扫描
-
原理:尝试与一个个的端口连接:
- 没有任何回复是被过滤了:filtered
- 收到 SYN+ACK 就是开着的:open
- 收到 RST 就是关闭的:close
-
-sS:不建立连接、无痕迹;但需要root权限
-
-sT:建立连接、不隐蔽
-
-sA:发送ACK包,判断是否被过滤
-
idle扫描原理
A:攻击者;B:Zombie主机;C:目标主机
首先A先向B发送SYN/ACK包,然后B返回一个RST包,并记录该包的IPID。
然后A冒充B向C发送SYN包。如果C的端口开放,则返回SYN/ACK包,B收到后会回复一个RST包,并且IPID+1。如果C的端口不开放,则直接返回RST。
之后A再向B发送一个SYN/ACK包,查看B返回的IPID的值,如果IPID的值增加了2,则可知C的端口开放。
idle无法区分关闭和被过滤的情况。
-
防火墙
分类
- 包过滤(packet filter)防火墙【无状态、静态~】
- 应用层网关代理(Application level Gateway)
- 状态防火墙(stateful firewall)
iptables
包过滤防火墙
(packet filter)【无状态、静态~】
解决办法:
- 规定源端口的访问,防止直接连入数值端口的服务上
- 增加标志位,拒绝外界SYN包
应用层网关代理
(Application level Gateway)
外部主机看不到内部的情况,所有的通信都要经过【应用级代理】,客户和服务器没有真正的连接。
iptables实现代理防火墙
状态防火墙
(stateful firewall)动态包过滤防火墙
不同实时的状态,对应动态变化的匹配规则
过滤匹配机制
代理
- 正向代理
- 反向代理
netfilter
偷账号密码原理:TCP调用IP前,被钩子勾了,到了netfilter
数据报从进入系统,进行IP校验以后,首先经过第一个HOOK函数NF_IP_PRE_ROUTING进行处理;然后就进入路由代码,其决定该数据报是需要转发还是发给本机的;若该数据报是发被本机的,则该数据经过HOOK函数NF_IP_LOCAL_IN处理以后然后传递给上层协议;若该数据报应该被转发则它被NF_IP_FORWARD处理;经过转发的数据报经过最后一个HOOK函数NF_IP_POST_ROUTING处理以后,再传输到网络上。本地产生的数据经过HOOK函数NF_IP_LOCAL_OUT 处理后,进行路由选择处理,然后经过NF_IP_POST_ROUTING处理后发送出去。
后门
通常,攻击者通过远程攻击获得root访问权限(譬如密码猜测、破解、缓冲区溢出、0-day漏洞),然后安装后门,便于之后回访,安装rootkit,隐藏踪迹,收集信息,便于长期回访以及获得对其他系统的访问权限。
短暂的root权限+backdoor+rootkit==>长期的root权限
Backdoor
Linux权限管理:根据文件访问权限管理
UID
- real UID
- effective UID
- saved set-user-ID
Rookit
rootkit本身的发展过程:应用级->内核级->硬件级
LKM
可加载内核模块(Loadable Kernel Module),优点是动态加载:内核进行修改和扩展时,不需要重编译内核和重启系统。entry 和 exit 函数,分别用于插入、删除。
系统调用劫持
首先,当进行一次系统调用的时候,会触发软中断(INT $0x80)==》进入内核的系统调用处理程序。
然后在系统调用处理程序的代码中寻找到sys_call_table的地址。
接下来,根据系统调用表sys_call_table地址 和 eax中存放的系统调用号,
找到真正的 系统调用例程的地址,
将其替换为 攻击者的 系统调用处理函数地址。
缓冲区溢出
缓冲区:分配一段有限大小的内存空间
缓冲区溢出:从缓冲区 读/写 的数据超出了缓冲区可以容纳的范围。
返回地址
从子程序返回后,主程序继续执行的指令地址称为“返回地址”。
返回地址就是主程序中CALL指令后面一条指令的地址。函数的返回地址,也就是函数调用语句的下一条语句的地址。
call指令的作用是什么?
转移到调用的程序。
call + 调用函数的地址。
当执行调用(call)时,堆栈指针esp 递减4个字节(32位),
并且调用后的指令地址(返回地址)被写入现在由esp引用的存储器位置,
换句话说,返回地址被压入栈。
然后将 指令指针eip 设置指定为要调用的操作数的地址,并从该地址继续执行。
ret恰恰相反。简单的ret不会占用任何操作数。
处理器首先从esp中包含的内存地址中读取值,然后将esp增加4个字节,它会从堆栈中弹出返回地址。
eip设置为此值,并从该地址继续执行。
函数调用
首先,把函数调用的参数压栈,然后cs、eip(返回地址)压栈,
ebp(栈底)压栈,接下来,更新ebp的值为esp的值(栈对齐),
将esp减少一个特定的值(与调用函数内部申请空间相关),为调用函数获取一定的栈空间。
防止缓冲区溢出
-
编译器进行了栈保护:canary保护,和防止栈运行。
-
栈起始地址随机化,不同次运行同一个程序时,栈的起始位置都不一样。(防止猜测 ShellCode 的入口地址)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~