逆向-attack之改写函数的返回地址

文章描述了一个C程序中利用栈溢出技巧,通过修改输入函数的返回地址,间接调用`breakout`函数并获取shell权限的过程。作者详细展示了x86和ARM架构下的汇编代码实现。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
 * 改写input()函数的返回地址,从而使得breakout()函数在没有直接调用的情况下获得执行
 */

void breakout()
{
    puts("Welcome. Have a shell...");
    system("/bin/sh");
}

void input()
{
    void *p;
    printf("Address of stack variable: %p\n", &p);
    printf("Something that looks like a return address on stack: %p\n", *((&p)+2));
    // Let's change it to point to the start of our sneaky function.
    *((&p)+2) = breakout;
}

int main()
{
    printf("main() code starts at %p\n",main);
    
    input();
    while (1) {
        puts("Hello");
        sleep(1);
    }

    return 0;
}

 

#if 0
/*
 * intel
 */

00000000000011c9 <breakout>:
    11c9:    f3 0f 1e fa              endbr64
    11cd:    55                       push   %rbp
    11ce:    48 89 e5                 mov    %rsp,%rbp
    11d1:    48 8d 3d 30 0e 00 00     lea    0xe30(%rip),%rdi        # 2008 <_IO_stdin_used+0x8>
    11d8:    e8 b3 fe ff ff           callq  1090 <puts@plt>      // puts
    11dd:    48 8d 3d 3d 0e 00 00     lea    0xe3d(%rip),%rdi        # 2021 <_IO_stdin_used+0x21>
    11e4:    e8 c7 fe ff ff           callq  10b0 <system@plt>    // system
    11e9:    90                       nop
    11ea:    5d                       pop    %rbp
    11eb:    c3                       retq   

00000000000011ec <input>:
    11ec:    f3 0f 1e fa              endbr64
    11f0:    55                       push   %rbp
    11f1:    48 89 e5                 mov    %rsp,%rbp
    11f4:    48 83 ec 10              sub    $0x10,%rsp
    11f8:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax
    11ff:    00 00
    1201:    48 89 45 f8              mov    %rax,-0x8(%rbp)
    1205:    31 c0                    xor    %eax,%eax
    1207:    48 8d 45 f0              lea    -0x10(%rbp),%rax     // rax=(rbp-0x10)'s address
    120b:    48 89 c6                 mov    %rax,%rsi            
    120e:    48 8d 3d 1b 0e 00 00     lea    0xe1b(%rip),%rdi        # 2030 <_IO_stdin_used+0x30>
    1215:    b8 00 00 00 00           mov    $0x0,%eax
    121a:    e8 a1 fe ff ff           callq  10c0 <printf@plt>    // printf
    121f:    48 8d 45 f0              lea    -0x10(%rbp),%rax     // rax=(rbp-0x10)'s address
    1223:    48 83 c0 10              add    $0x10,%rax           // rax=(rbp-0x10)'s address+0x10, [0, 8, 16]
    1227:    48 8b 00                 mov    (%rax),%rax          // rax=*((&p)+2)
    122a:    48 89 c6                 mov    %rax,%rsi
    122d:    48 8d 3d 1c 0e 00 00     lea    0xe1c(%rip),%rdi        # 2050 <_IO_stdin_used+0x50>
    1234:    b8 00 00 00 00           mov    $0x0,%eax
    1239:    e8 82 fe ff ff           callq  10c0 <printf@plt>    // printf
    123e:    48 8d 45 f0              lea    -0x10(%rbp),%rax     // rax=(rbp-0x10)'s address
    1242:    48 83 c0 10              add    $0x10,%rax           // rax=(rbp-0x10)'s address+0x10, [0, 8, 16]
    1246:    48 8d 15 7c ff ff ff     lea    -0x84(%rip),%rdx        # 11c9 <breakout>    // breakout's address
    124d:    48 89 10                 mov    %rdx,(%rax)          // *((&p)+2) = breakout;
    1250:    90                       nop
    1251:    48 8b 45 f8              mov    -0x8(%rbp),%rax
    1255:    64 48 33 04 25 28 00     xor    %fs:0x28,%rax
    125c:    00 00
    125e:    74 05                    je     1265 <input+0x79>
    1260:    e8 3b fe ff ff           callq  10a0 <__stack_chk_fail@plt>
    1265:    c9                       leaveq
    1266:    c3                       retq   

0000000000001267 <main>:
    1267:    f3 0f 1e fa              endbr64
    126b:    55                       push   %rbp
    126c:    48 89 e5                 mov    %rsp,%rbp
    126f:    48 8d 35 f1 ff ff ff     lea    -0xf(%rip),%rsi        # 1267 <main> // rsi=1267=main
    1276:    48 8d 3d 0c 0e 00 00     lea    0xe0c(%rip),%rdi        # 2089 <_IO_stdin_used+0x89>
    127d:    b8 00 00 00 00           mov    $0x0,%eax
    1282:    e8 39 fe ff ff           callq  10c0 <printf@plt>    // printf
    1287:    b8 00 00 00 00           mov    $0x0,%eax
    128c:    e8 5b ff ff ff           callq  11ec <input>         // input
    1291:    48 8d 3d 0b 0e 00 00     lea    0xe0b(%rip),%rdi        # 20a3 <_IO_stdin_used+0xa3>
    1298:    e8 f3 fd ff ff           callq  1090 <puts@plt>      // puts
    129d:    bf 01 00 00 00           mov    $0x1,%edi
    12a2:    e8 29 fe ff ff           callq  10d0 <sleep@plt>     // sleep(1)
    12a7:    eb e8                    jmp    1291 <main+0x2a>     // while(1)
    12a9:    0f 1f 80 00 00 00 00     nopl   0x0(%rax)

/*
 * arm
 */

000000000040064c <breakout>:
  40064c:    a9bf7bfd     stp    x29, x30, [sp, #-16]!
  400650:    910003fd     mov    x29, sp
  400654:    90000000     adrp    x0, 400000 <_init-0x4a0>
  400658:    911ec000     add    x0, x0, #0x7b0
  40065c:    97ffffb5     bl    400530 <puts@plt>               // puts
  400660:    90000000     adrp    x0, 400000 <_init-0x4a0>
  400664:    911f4000     add    x0, x0, #0x7d0
  400668:    97ffffa6     bl    400500 <system@plt>             // system
  40066c:    d503201f     nop
  400670:    a8c17bfd     ldp    x29, x30, [sp], #16
  400674:    d65f03c0     ret

0000000000400678 <input>:
  400678:    a9be7bfd     stp    x29, x30, [sp, #-32]!
  40067c:    910003fd     mov    x29, sp
  400680:    910063a1     add    x1, x29, #0x18
  400684:    90000000     adrp    x0, 400000 <_init-0x4a0>
  400688:    911f6000     add    x0, x0, #0x7d8
  40068c:    97ffffad     bl    400540 <printf@plt>     // printf(0x4007d8, x29+0x18)
  400690:    910063a0     add    x0, x29, #0x18
  400694:    91004000     add    x0, x0, #0x10           // x0=0x29+0x18+0x10
  400698:    f9400001     ldr    x1, [x0]
  40069c:    90000000     adrp    x0, 400000 <_init-0x4a0>    
  4006a0:    911fe000     add    x0, x0, #0x7f8
  4006a4:    97ffffa7     bl    400540 <printf@plt>     // printf
  4006a8:    910063a0     add    x0, x29, #0x18
  4006ac:    91004000     add    x0, x0, #0x10           // x0=0x29+0x18+0x10
  4006b0:    90000001     adrp    x1, 400000 <_init-0x4a0>
  4006b4:    91193021     add    x1, x1, #0x64c          // x1 = 40064c = breakout
  4006b8:    f9000001     str    x1, [x0]                // *((&p)+2) = breakout;
  4006bc:    d503201f     nop
  4006c0:    a8c27bfd     ldp    x29, x30, [sp], #32
  4006c4:    d65f03c0     ret

00000000004006c8 <main>:
  4006c8:    a9bf7bfd     stp    x29, x30, [sp, #-16]!
  4006cc:    910003fd     mov    x29, sp
  4006d0:    90000000     adrp    x0, 400000 <_init-0x4a0>
  4006d4:    911b2001     add    x1, x0, #0x6c8                  // x1=4006c8=main
  4006d8:    90000000     adrp    x0, 400000 <_init-0x4a0>
  4006dc:    9120e000     add    x0, x0, #0x838
  4006e0:    97ffff98     bl    400540 <printf@plt>             // printf
  4006e4:    97ffffe5     bl    400678 <input>                  // input
  4006e8:    90000000     adrp    x0, 400000 <_init-0x4a0>
  4006ec:    91216000     add    x0, x0, #0x858
  4006f0:    97ffff90     bl    400530 <puts@plt>               // puts
  4006f4:    52800020     mov    w0, #0x1                       // #1
  4006f8:    97ffff7e     bl    4004f0 <sleep@plt>          // sleep(1)
  4006fc:    17fffffb     b    4006e8 <main+0x20>          // while(1)


#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值