如何侦服务器的tcp返回数据

如何侦服务器的tcp返回数据,第1张

在平时的开发中,经常会碰到一些需要检测tcp连接是否正常的场景。比如一个分布式的应用,一个调度任务的节点管理一堆用来跑业务的节点。当调度节点进行调度的时候,需要把任务分发给它认为正常的业务节点去执行。业务节点是否正常,一个重要的参考依据就是调度节点和业务节点之间的tcp连接是否正常。这时候就需要调度节点主动地去检测tcp连接。常见的检测方法有以下几种

方案一、通过TCP协议的返回值进行判断

<1>利用select,把socket设置为非阻塞。然后使用select等待该socket的可读事件。如果socket可读,但是recv的返回值是0,则说明socket已经被对端断开,这时候就可以调用close关闭socket。这里还要注意一点,recv还可能返回负数,这个代表socket操作出错。但是仍然应该判断一下errno是否为EINTR。如果errno是EINTR,则说明recv函数是被信号中断返回的,这时候不能判断socket的连接是否正常,也不应该调用close关闭socket。

<2>利用poll的事件。poll本身提供了POLLHUP,POLLERR, POLLNVAL三个事件。如果文件描述符是socket,则POLLHUP代表socket已经断开了连接,在TCP底层就是已经收到了FIN报文。POLLERR表示socket出现了错误,一般情况下是收到了rst报文,或者已经发送了rst报文。这两种情况都应该调用close关闭socket。POLLNVAL代表socket没有打开,这时不能使用close关闭它,而应该根据自己的业务做一些其他的操作。因为关闭一个未打开的socket会出错。

这两种方法都可以很精确地判断tcp连接是否正常,但是仍然有很明显的缺陷。就是它只可以根据TCP操作的返回值来进行判断。如果TCP四次握手没有正常被执行呢?比如连接对端机器直接挂了,那么就不会发送FIN报文给这一端,select不会返回socket可读,poll不会返回socket异常。那么这个死链接将会永远检测不到。直到写这个socket的时候,对端直接返回一个ret报文,这时才知道这个连接已经断掉了。这就意味着tcp连接异常可能永远检测不到,或者检测到的延迟非常大。这对于一些资源宝贵而且要求高性能的服务器是不能接受的,比如游戏服务器,比如搜索服务器。

方案二、在第一种方案的基础上设置socket的 keep alive 机制

方案一的主要缺陷在于检测不及时,或者根本检测不到。TCP协议提供了keep alive机制。如果开启了这个特性(暂时称开启了keep alive的一端为开启端),在默认情况下,开启的着一端的socket相关结构中会维护一个定时器,默认是2小时。如果在2小时内两端没有数据往来,那么开启端就会给另一端发送一个ack空报文。这时候分几种情况:

<1>对端机器可达,而且TCP相关组件运行正常。那么对端就会给开启端发送一个ack空报文。这时开启端就知道对端是正常的,意味着tcp连接也没有问题。开启端会重新初始化定时器,等待下一个超时的到来。需要注意的是,如果两端之间有数据往来,定时器也会被重新初始化为2个小时。

<2>对端挂了,或者正在重启,还没有完全起来。或者对端服务器不可达。 这种状态的对端是不会响应这个ack的。开启端的 keep alive 机制会把这种情况当探测超时来处理,并且重新发送ack到对端。当超时次数超过一定限制,keep alive 就认为这个tcp连接有问题。典型值是每次75秒,超时9次。

<3>对端挂过,但是已经重启完成。这时候发送这个ack和写已经关闭的socket是一种情况,对端会返回一个rst报文,这样开启端就知道tcp连接出问题了。

可以看出 keep alive 机制弥补了方案一种不能判断没有进行正常四次挥手连接出现问题的缺陷。默认的发送超时和发送间隔都是可以调整的。

tcp_keepalive_time: KeepAlive的空闲时长,默认是2小时

tcp_keepalive_intvl: KeepAlive探测包的发送间隔,默认是75s 

tcp_keepalive_probes: 在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数,默认是9次

这3个参数使用 setsockopt函数都是可以配置的。

方案二看似已经完美了,能够比较精确而且及时地发现有问题的连接。但是还有2个缺点。第一个是 keep alive 机制看似牛逼,但是很多人不建议使用。因为上面说的3个参数很难根据业务场景给出合适的值,设置不好很容易对tcp连接状态发生误判,关闭了一个本来正常的连接。而且没有一个主动通知应用层的方式。比如socket连接出错了,TCP协议接到了rst,fin,或者keep alive判断出socket有问题了,但是并不会主动去通知应用层,必须我们自己 recv socket或者等待错误事件才能得到这个错误。第二个是很多场景下,keep alive 检测仍然不够及时,比如对端挂了,最长需要等待 tcp_keepalive_intvl * tcp_keepalive_probes时间才可以检测出来,而且这两个值还不能设置得太小,太小了容易误判。

方案三、应用层的心跳

这种形式的心跳设计就比较多样化了,而且灵活,可以很好地适应业务场景。唯一的缺点就是要自己写代码。我目前接触到的就是定期进行RPC调用。看RPC调用是否正常,如果返回错误或者抛出异常,就说明连接有问题。

概述

1. SYN-Flooding攻击效果,受害者系统卡死.

2. TCP-RST攻击实现已经建立的TCP连接断开.

3. TCP会话劫持,劫持TCP会话,并实现反向Shell.

实验环境

1. 三台Linux系统主机,一台作为攻击者,一台作为受害者,一台作为观察者.

2. 为了简化TCP序列号和源端口号的“猜测”,实验处于同一局域网内,你可以使用嗅探器来获取受害者信息.

SYN-Flooding攻击

1. SYN-Flooding攻击原理

SYN-Flooding是DoS攻击的一种,攻击者向受害者的TCP端口发送很多SYN请求,但攻击者无意完成三次握手过程.

攻击者要么使用欺骗性的假的IP地址,要么不要继续完成整个三次握手过程.

通过这种攻击,攻击者可以淹没用于半连接的受害者队列,即已完成SYN,SYN-ACK但尚未得到最终ACK的连接.

当这个队列已满时,受害者不能再进行任何连接.

正常三次握手过程:

在Linux中,我们可以使用以下命令检查

我们可以使用命令“netstat -na”来检查队列的使用情况,即与监听端口相关联的半连接的数量.

这种半连接的状态是SYN-RECV。如果三次握手完成,则连接的状态将为ESTABLISHED.

在这个任务中,你需要演示SYN-Flooding攻击:

您可以使用Netwox来执行攻击,然后使用嗅探器捕获攻击性数据包.

在攻击发生时,在受害机器上运行“netstat -na”命令,并将结果与攻击前的结果进行比较.

2. Netwox 76简介

3. SYN Cookie防御机制

如果你的攻击看起来不成功,你可以检查是否启用了SYN cookie机制.

SYN cookie是抵抗SYN-Flooding的防御机制.

防御原理简介:

在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,

而是根据这个SYN包计算出一个cookie值.

在收到TCP ACK包时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性.

如果合法,再分配专门的数据区进行处理未来的TCP连接.

你可以使用sysctl命令打开/关闭SYN cookie机制:

4. 实验结果分析

比较 netstat -na 前后状态如下:

产生大量的TCP半连接,阻塞了队列,导致后续正常TCP连接无法建立!!

TCP-RST攻击

1. FTP协议

2. TELNET协议

3. SSH协议

4. Newox 78简介

5. 实验结果分析

-** FTP**

FTP服务器地址: 192.168.59.146/24

FTP客户端地址: 192.168.59.144/24

攻击者地址: 192.168.59.1/24

攻击者终端对受害者进行TCP-RST打击:

结果显示:已经建立的TCP连接断开.

Telnet服务器地址: 192.168.59.146/24

Telnet客户端地址: 192.168.59.144/24

攻击者地址: 192.168.59.1/24

攻击者终端对受害者进行TCP-RST打击:

结果显示:已经建立的TCP连接断开.

SSH服务器地址: 192.168.59.146/24

SSH客户端地址: 192.168.59.144/24

攻击者地址: 192.168.59.1/24

攻击者终端对受害者进行TCP-RST打击:

结果显示:已经建立的TCP连接断开.

TCP会话劫持

1. 会话劫持简介

TCP会话劫持攻击的目标是通过向该会话中注入恶意内容来劫持两名受害者之间的现有TCP连接(会话).

如果这个连接是一个telnet会话,攻击者可以在这个会话中注入恶意命令(例如删除重要文件),导致受害者执行恶意命令.

2. Wireshark简介

如果您使用Wireshark观察网络流量,当Wireshark显示TCP序列号时,

默认情况下会显示相对序列号,它等于实际序列号减去初始序列号.

如果想查看包中的实际序列号,则需要右键单击Wireshark输出的TCP部分,

然后选择"Protocol Preference". 在弹出窗口中,取消选"Relative Sequence Number"选项.

3. Netwox 40简介

4. 实验结果分析

Telnet服务器地址: 192.168.59.148/24

Telnet客户端地址: 192.168.59.146/24

攻击者地址: 192.168.59.1/24

攻击者终端对受害者进行TCP会话劫持:

我们要伪造发下一个包:

所以直接采用nextseq作为下一个包的ack,采用ack作为下一个包的seq.

最后一个Telnet数据包内容如下:

我们伪造向服务器 192.168.59.148 发送 ls 命令,

通过netwox构造我们的攻击指令如下:

在wireshark上显示抓包数据如下:

来创建我们的肉鸡~

现在我们来通过NC反弹一个Shell,来控制我们受害者:

首先是构造NC命令:

实验结果如图:

首先看结果:我们成功拿到了服务器上的用户gu的所有权限!

咱们再来看看抓包数据,通过抓包数据,你可以看到最后一条Telnet的TCP数据,通过这些数据,就可以很方便通过Netwox构造攻击语句了!!


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/762121.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-08-18
下一篇2023-08-18

发表评论

登录后才能评论

评论列表(0条)

    保存