【Writeup】Pwnable.kr 0x08 leg

0x08 leg

題目描述

Daddy told me I should study arm.
But I prefer to study my leg!

Download : http://pwnable.kr/bin/leg.c
Download : http://pwnable.kr/bin/leg.asm

ssh leg@pwnable.kr -p2222 (pw:guest)

題目代碼

c代碼

#include <stdio.h>
#include <fcntl.h>
int key1(){
    asm("mov r3, pc\n");
}
int key2(){
    asm(
    "push   {r6}\n"
    "add    r6, pc, $1\n"
    "bx r6\n"
    ".code   16\n"
    "mov    r3, pc\n"
    "add    r3, $0x4\n"
    "push   {r3}\n"
    "pop    {pc}\n"
    ".code  32\n"
    "pop    {r6}\n"
    );
}
int key3(){
    asm("mov r3, lr\n");
}
int main(){
    int key=0;
    printf("Daddy has very strong arm! : ");
    scanf("%d", &key);
    if( (key1()+key2()+key3()) == key ){
        printf("Congratz!\n");
        int fd = open("flag", O_RDONLY);
        char buf[100];
        int r = read(fd, buf, 100);
        write(0, buf, r);
    }
    else{
        printf("I have strong leg :P\n");
    }
    return 0;
}

匯編代碼

(gdb) disass main
Dump of assembler code for function main:
   0x00008d3c <+0>: push    {r4, r11, lr}
   0x00008d40 <+4>: add r11, sp, #8
   0x00008d44 <+8>: sub sp, sp, #12
   0x00008d48 <+12>:    mov r3, #0
   0x00008d4c <+16>:    str r3, [r11, #-16]
   0x00008d50 <+20>:    ldr r0, [pc, #104]  ; 0x8dc0 <main+132>
   0x00008d54 <+24>:    bl  0xfb6c <printf>
   0x00008d58 <+28>:    sub r3, r11, #16
   0x00008d5c <+32>:    ldr r0, [pc, #96]   ; 0x8dc4 <main+136>
   0x00008d60 <+36>:    mov r1, r3
   0x00008d64 <+40>:    bl  0xfbd8 <__isoc99_scanf>
   0x00008d68 <+44>:    bl  0x8cd4 <key1>
   0x00008d6c <+48>:    mov r4, r0
   0x00008d70 <+52>:    bl  0x8cf0 <key2>
   0x00008d74 <+56>:    mov r3, r0
   0x00008d78 <+60>:    add r4, r4, r3
   0x00008d7c <+64>:    bl  0x8d20 <key3>
   0x00008d80 <+68>:    mov r3, r0
   0x00008d84 <+72>:    add r2, r4, r3
   0x00008d88 <+76>:    ldr r3, [r11, #-16]
   0x00008d8c <+80>:    cmp r2, r3
   0x00008d90 <+84>:    bne 0x8da8 <main+108>
   0x00008d94 <+88>:    ldr r0, [pc, #44]   ; 0x8dc8 <main+140>
   0x00008d98 <+92>:    bl  0x1050c <puts>
   0x00008d9c <+96>:    ldr r0, [pc, #40]   ; 0x8dcc <main+144>
   0x00008da0 <+100>:   bl  0xf89c <system>
   0x00008da4 <+104>:   b   0x8db0 <main+116>
   0x00008da8 <+108>:   ldr r0, [pc, #32]   ; 0x8dd0 <main+148>
   0x00008dac <+112>:   bl  0x1050c <puts>
   0x00008db0 <+116>:   mov r3, #0
   0x00008db4 <+120>:   mov r0, r3
   0x00008db8 <+124>:   sub sp, r11, #8
   0x00008dbc <+128>:   pop {r4, r11, pc}
   0x00008dc0 <+132>:   andeq   r10, r6, r12, lsl #9
   0x00008dc4 <+136>:   andeq   r10, r6, r12, lsr #9
   0x00008dc8 <+140>:           ; <UNDEFINED> instruction: 0x0006a4b0
   0x00008dcc <+144>:           ; <UNDEFINED> instruction: 0x0006a4bc
   0x00008dd0 <+148>:   andeq   r10, r6, r4, asr #9
End of assembler dump.
(gdb) disass key1
Dump of assembler code for function key1:
   0x00008cd4 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008cd8 <+4>: add r11, sp, #0
   0x00008cdc <+8>: mov r3, pc
   0x00008ce0 <+12>:    mov r0, r3
   0x00008ce4 <+16>:    sub sp, r11, #0
   0x00008ce8 <+20>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008cec <+24>:    bx  lr
End of assembler dump.
(gdb) disass key2
Dump of assembler code for function key2:
   0x00008cf0 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008cf4 <+4>: add r11, sp, #0
   0x00008cf8 <+8>: push    {r6}        ; (str r6, [sp, #-4]!)
   0x00008cfc <+12>:    add r6, pc, #1
   0x00008d00 <+16>:    bx  r6
   0x00008d04 <+20>:    mov r3, pc
   0x00008d06 <+22>:    adds    r3, #4
   0x00008d08 <+24>:    push    {r3}
   0x00008d0a <+26>:    pop {pc}
   0x00008d0c <+28>:    pop {r6}        ; (ldr r6, [sp], #4)
   0x00008d10 <+32>:    mov r0, r3
   0x00008d14 <+36>:    sub sp, r11, #0
   0x00008d18 <+40>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008d1c <+44>:    bx  lr
End of assembler dump.
(gdb) disass key3
Dump of assembler code for function key3:
   0x00008d20 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008d24 <+4>: add r11, sp, #0
   0x00008d28 <+8>: mov r3, lr
   0x00008d2c <+12>:    mov r0, r3
   0x00008d30 <+16>:    sub sp, r11, #0
   0x00008d34 <+20>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008d38 <+24>:    bx  lr
End of assembler dump.
(gdb) 

題目分析

拿到題目之后,心中是無限的難受,主要是作為一個萌新,x86匯編還沒有搞明白呢,結果題目竟然是ARM的,沒辦法,本著學習的精神還是要硬著頭皮做的,剛好之前在安全客上看到有個ARM速成教程,正好看了一邊,對ARM有了一定的認識,再看這道題也就游刃有余了。這里推薦一下安全客的ARM學習教程,講的還是很不錯的:http://bobao.360.cn/learning/detail/4070.html(這是個系列課程,截至2017/8/2一共7部分)
回到本題,觀察一下,發現有main函數、key1函數、key2函數、key3函數,想要獲得flag就得讓key1、key2、key3的返回值相加等于我們需要輸入的key,那么思路就是計算各個函數的返回值,相加得到的數就是我們要輸入的數字。

解題步驟

part 1

首先是看一下key1函數

(gdb) disass key1
Dump of assembler code for function key1:
   0x00008cd4 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008cd8 <+4>: add r11, sp, #0
   0x00008cdc <+8>: mov r3, pc
   0x00008ce0 <+12>:    mov r0, r3
   0x00008ce4 <+16>:    sub sp, r11, #0
   0x00008ce8 <+20>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008cec <+24>:    bx  lr
End of assembler dump.

這里返回值是r0,分析得出,r0等于r3的值,r3等于pc的值。pc是程序計數寄存器。程序計數器是一個在程序指令執行時自增的計數器。它的大小在ARM模式下總是4字節對齊,在Thumb模式下總是兩字節對齊。當執行一個分支指令時,PC存儲目的地址。在程序執行中,ARM模式下的PC存儲著當前指令加8(兩條ARM指令后)的位置,Thumb(v1)模式下的PC存儲著當前指令加4(兩條Thumb指令后)的位置。因此,這里pc的值就是0x8cdc + 0x8、

part 2

然后看一下key2函數

(gdb) disass key2
Dump of assembler code for function key2:
   0x00008cf0 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008cf4 <+4>: add r11, sp, #0
   0x00008cf8 <+8>: push    {r6}        ; (str r6, [sp, #-4]!)
   0x00008cfc <+12>:    add r6, pc, #1
   0x00008d00 <+16>:    bx  r6
   0x00008d04 <+20>:    mov r3, pc
   0x00008d06 <+22>:    adds    r3, #4
   0x00008d08 <+24>:    push    {r3}
   0x00008d0a <+26>:    pop {pc}
   0x00008d0c <+28>:    pop {r6}        ; (ldr r6, [sp], #4)
   0x00008d10 <+32>:    mov r0, r3
   0x00008d14 <+36>:    sub sp, r11, #0
   0x00008d18 <+40>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008d1c <+44>:    bx  lr
End of assembler dump.

這里r3是返回值。然后再看一下地址 0x00008d00 <+16>這里,有個bx r6,而r6等于pc+1即0x8d05,最低為為1,所以執行bx r6之后會進入thumb模式,這樣就會變成2字節對齊,pc存儲著當前指令加4的位置,如此一來,下面的mov r3,pc中,r3等于0x8d04+0x4。下一條為adds r3,#4,表示r3 = r3 + 4后更新標志位,因此r3 = 0x8d04 + 0x4 + 0x4。

part 3

最后看一下key3函數

(gdb) disass key3
Dump of assembler code for function key3:
   0x00008d20 <+0>: push    {r11}       ; (str r11, [sp, #-4]!)
   0x00008d24 <+4>: add r11, sp, #0
   0x00008d28 <+8>: mov r3, lr
   0x00008d2c <+12>:    mov r0, r3
   0x00008d30 <+16>:    sub sp, r11, #0
   0x00008d34 <+20>:    pop {r11}       ; (ldr r11, [sp], #4)
   0x00008d38 <+24>:    bx  lr
End of assembler dump.

這里r0是返回值。lr中存放的是函數的返回地址,mov r3,lr mov r0,r3 最終,r3的值等于lr的值,即函數返回地址,到main函數一看,函數的返回地址就是0x8d80。

總結

最后,將以上得到的三個數值相加即可得到key

#/usr/bin/python

key1 = 0x8cdc + 0x8
key2 = 0x8d04 + 0x4 + 0x4
key3 = 0x8d80

key = key1 + key2 + key3

print key

運行./leg,輸入key即可得到flag


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 原文地址 一、Hopper中的ARM指令ARM處理器就不多說了,ARM處理器因為低功耗等原因,所以大部分移動設備上...
    顏值不夠才華來湊閱讀 1,169評論 0 4
  • 前言 本文翻譯自iOS Assembly Tutorial: Understanding ARM 翻譯的不對的地...
    桃紅宿雨閱讀 18,207評論 7 198
  • 對于 HTTP 協議而言,HTML、CSS、JS、JSON 的本質都是什么? 1.對于HTTP協議而言,html、...
    azure_1122閱讀 307評論 0 0
  • 殘月凄凄照無眠, 流鶯聲里聽孤雁。 寒風橫掃窗前雨, 冷葉斜飄陌上煙。 醉里看箋何有淚, 心底為公本無怨。 利刃相...
    桂山花石草廬閱讀 568評論 0 6
  • 孤獨如影,不離不棄,永伴相隨。
    高能磷酸閱讀 157評論 0 0