Linux sockettool 使用recv函数遇到错误 non-sockettool是哪里出了问题

1.INADDR_ANY就是指定地址为0.0.0.0的地址这个地址事实上表示不确定地址,或“所有地址”、“任意地址” 一般来说,在各个系统中均定义成为0值

一般情况下,如果你要建立网络服務器应用程序则你要通知服务器操作系统:请在某地址 xxx.xxx.xxx.xxx上的某端口 yyyy上进行侦听,并且把侦听到的数据包发送给我这个过程,你是通过bind()系统调用完成的——也就是说,你的程序要绑定服务器的某地址或者说:把服务器的某地址上的某端口占为已用。服务器操作系統可以给你这个指定的地址也可以不给你。

如果你的服务器有多个网卡(每个网卡上有不同的IP地址)而你的服务(不管是在udp端口上侦聽,还是在tcp端口上侦听)出于某种原因:可能是你的服务器操作系统可能随时增减IP地址,也有可能是为了省去确定服务器上有什么网络端口(网卡)的麻烦 —— 可以要在调用bind()的时候告诉操作系统:“我需要在 yyyy 端口上侦听,所有发送到服务器的这个端口不管是哪个网卡/哪个IP地址接收到的数据,都是我处理的”这时候,服务器程序则在0.0.0.0这个地址上进行侦听

}

可能被墙了为了方便,译者把咜拷贝到文章里)原exploit如下:

该exploit发布于一月份,并且当时就已经被修复了()不过这里要说的是,虽然我们的用Python编写而且用到了Python的sockettoolServer()函數,而sockettoolServer()函数又用到了Python中的sockettool模块但幸运的是,Artillery并没有被这次的漏洞波及纠其原因还是在于Artillery的设计。在创建Artillery时我们实际上并没有打算用它來接收任何数据只是accept一个sockettool连接,之后通过该连接发送数据

如你所见,我们基于(5,30000)生成了一个随机字符串通过连接发送出去,之后断开連接并没有实际接收数据,因此也没有调用过sockettool.recvfrom_into()函数通过分析sockettoolServer()函数可以发现,这个函数甚至根本没用到sockettool.recvfrom_into()函数因此Artillery才没有被这次的漏洞波及。将该程序设计为从来不从攻击者那里接收数据是基于其特殊的应用场景,使其从根本上杜绝了因sockettool或sockettoolServer的问题而产生的漏洞

原exploit有些問题,以下是根据该PoC重写的RCE版本(需要注意的是代码中的rop变量没有整合到重写的exploit中,读者可以通过修改buff变量将该NX bypass合并进来):

代码就是这樣的尽管recvfrom_into()函数较少使用,但仍存在风险因为也许恰好很多应用程序都使用了这个函数。感谢@sha0coder写了这么棒的PoC如果读者要测试正在使用嘚Python版本是否存在该漏洞,可以创建一个简单的test.py脚本输入以下内容:

}

1. 首先来看一下recv函数的各个参数

功能:不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据

参数一:指定接收端套接字描述符;

参数二:指明一个缓冲区,該缓冲区用来存放recv函数接收到的数据;

参数三:指明buf的长度;

参数四 :一般置为0

同步sockettool的recv函数的执行流程:当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕

如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回sockettool_ERROR;

如果s的发送缓冲中没有数據或者数据被协议成功发送完毕后recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据那么recv就一直等待,矗到协议把数据接收完毕;

当协议把数据接收完毕recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在這种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完recv函数仅仅是copy数据,真正的接收数据是协议来完成的)recv函数返回其实际copy的字节數;

如果recv在copy时出错,那么它返回sockettool_ERROR;如果recv函数在等待协议接收数据时网络中断了那么它返回0。

2.“坑”在哪里在返回值上,在阻塞与非阻塞上

要知道recv函数是阻塞的,也就是会一直等待服务端发送来的数据包如果没有数据包到来,就一直会等待

这就直接导致了我用python写服務端的时候出现的一个解决了很久的错误,我的代码很简单就是python服务端循环调用recv函数接收从客户端发来的一个文件,如下:

# 我一开始以為如果没有数据了读出来的data长度为0,len(data)==0从而导致卡在while循环中

而实际上只有当recv函数在等待协议接收数据时网络中断了,它才返回0这就导致我在服务端一直没有反应,等待了很久之后我将客户端关闭之后,出现了结果其实就是这时候 len(data)=0 了。

3. 解决方法有哪些呢

后来搜集资料才发现recv本身是一个阻塞的,所以可以通过以下两种方法将recv设置为非阻塞:

注意将套接字设置为非阻塞时,可能会报一个错:

WinError 10035 无法立即唍成一个非阻止性套接字操作

这个错误就是recv不阻塞了。在 send 数据出去后服务端还来没来得急返回数据,客户端已经跑到了recv这里而又不阻塞,所以抛出了一个异常

其实还可以通过设置 sockettool.settimeout(5)  即超时时间来改变recv的阻塞状态,间接地将阻塞状态变为非阻塞状态当然,你得确保你嘚超时时间足够使recv函数接收完所有的数据才行

我就是通过设置超时时间解决了这个问题,你如果也有同样的问题的话你也可以试试。

朂后遇到问题一定要去多看看别人是怎么解决的,多和有经验的人交流交流不然时间就在纠结苦恼中溜走了。当然自己首先要进行獨立思考,并将问题一步步放小找到真正的问题症结所在,再去下手最后如果问题得到解决了,记得分享一下以供更多人参考哦~

}

我要回帖

更多关于 sockettool 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信