-
utumno0
和semtex4类似,这次的也是没有读权限。还是用xocopy把内容dump出来,elf地址用的是0x08048000。再用strings查看,发现类似是密码的内容 -
utumno1
会打开目录,检查包含的文件的文件名。必须要是以sh_开头;然后漏洞在run函数里面,会把d_name[3]的地址放到返回地址。所以把payload放在文件名sh_的后面即可。把shellcode放环境变量,然后payload是跳转到那里
$ touch `perl -e 'print "1/sh_" . "\xb8\xf3\xd8\xff\xff\xff\xe0"'` $ /utumno/utumno1 1
-
utumno2
有点类似于之前的vortex4,也是要求argc为0,只能把payload放到环境变量里。argv={NULL},所以argv+40就是env[9]。我们把shellcode放到env[0],env[9]放shellcode的地址,那么strcpy就会把返回地址重写。 在构造env时注意,在结束之前都不要包含NULL,否则会被认为env结束而忽略掉后面的内容
- utumno3
这里会一个个地读字符,在v2那里可以做到修改返回地址。为此,我们找到v2和返回地址的距离是0x2c,那么往v1里填的字符就应该是0x2c^0, 0x2d^3, 0x2e^6, 0x2f^9。我试了invoke shell,但没反应,加上cat也不行;所以只好用读文件的shellcode了$ perl -e 'print "\x2c\xc8\x2e\xd8\x28\xff\x26\xff"' | /utumno/utumno3
- utumno4
memcpy当然存在overflow,因为复制的大小是我们提供的;虽然对大小做了个检查,但是是把大小存到short里面再比较的。由于起始位置与返回地址相距0xff0e,我们只需提供大小为0x10000,那么就可以覆盖到返回地址,并且大小检查也符合$ /utumno/utumno4 65536 `perl -e 'print "A"x65294 . "\xef\xd8\xff\xff"'`
- utumno5
和utumno2类似,不过问题在函数hihi里。这次检查了字符串的长度,最多只能覆盖保存的ebp,但通过修改ebp,可以使main函数返回时的leave
跳到错误的地方,进而返回地址用我们提供的地址
- utumno6
malloc之后没有free,这点就很奇怪。于是通过v5=-1,可以修改v3的值为返回地址,那么接下来strcpy就可以修改返回地址了。$ /utumno/utumno6 -1 0xffffd6fc `perl -e 'print "\xf4\xd8\xff\xff"'`
-
utumno7
由于用的是exit,所以不能通过strcpy修改返回地址。由于jmp_buf保存在栈上,我们可以修改这个。具体地,setjmp会保存寄存器
也就是说,依次保存ebx,esi,edi,ebp,处理过的esp,处理过的eip。由于处理时会和$gs:0x18做xor,这就导致结果不确定了……我试了下,确实每次运的时候,第5、6个的值都不一样。
后来还是在网上搜了之后才发现的。ld.so的manual里是这么说的:
LD_POINTER_GUARD
(glibc since 2.4) Set to 0 to disable pointer guarding. Any other value enables pointer guarding, which is also the default.
Pointer guarding is a security mechanism whereby some pointers to code stored in writable program memory (return addresses saved by
setjmp(3) or function pointers used by various glibc internals) are mangled semi-randomly to make it more difficult for an attacker
to hijack the pointers for use in the event of a buffer overrun or stack-smashing attack.
也就是说,我们需要先
$export LD_POINTER_GUARD=0
这样,每次jmp_buf里的esp和eip就不随机了,但rotation还是有的。我们用python来计算rotation
由于跳转到shellcode后,要保证栈可读可写,我们让esp还是恢复到正确的值,只是eip到环境变量里的shellcode。通过jobs -l
获得进程的pid,再用kill -10 pid
来发送信号。要发两次,第一次后调用strcpy,覆盖eip,等第二次信号时,跳到我们给的eip。此外,可能是jump的原因,两次信号要用不同的,正好他设了两个handler,10和12。