cgy12306

[pwnable.kr] leg 본문

Wargame/pwnable.kr

[pwnable.kr] leg

cgy12306 2020. 1. 26. 22:24

[leg]

#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;
}

key값을 입력받고, key1() + key2() + key3() 을 더한 값과 같으면 플래그 값을 출력해주는 코드이다.

key1(), key2(), key3()의 어셈블리어 코드는 arm 문법이다.

  • OP Code Rd, Rn, Rm

  • 15개의 범용 레지스터(r0 ~ r12, sp, lr)

  • Rd : Destination Register. Register R0~R15만 올 수 있다. 연산작업의 결과값을 저장하는 레지스터이다.

  • Rn : Operand1 Register. 반드시 Register R0~R15만 올 수 있다.

  • Rm : Operand2, 레지스터뿐만 아니라 상수, 주소, 쉬프트 연산식 등 다양한 값을 사용할 수 있다.

  • #(상수), [ ](주소)

  • bl : Sub-Routin Call, 분기했다가 해당 명령이 끝나면 다시 복귀하는 명령어이다. 이 명령어를 사용하면 복귀할 주소(BL 다음 명령어의 주소)를 R14(lr) 레지스터에 저장한다.

  • str : 메모리 주소에 레지스터 값을 저장한다.

  • ldr : 해당 메모리 주소의 값을 레지스터에 저장한다.

  • pc 레지스터 : 다음 실행할 명령어가 담겨있음

CPU에서는 Fetch/ Decode/ Execution을 순서대로 일을 하게 되는데 효율적으로 처리하기 위해 pipe line을 이용한다.

Fetch/ Decode/ Execute를 pipe line을 사용하지 않는다면 2개의 opcode를 실행하는데 6번의 cycle이 걸리지만 pipe line을 이용하면 2개의 opcode를 실행하는데 4개의 cycle만 있으면 된다.

img

PC는 Fetch하고 있는 곳을 가리키게 된다. 이렇게 pipe line을 사용하게 되면 현재 PC값은 현재 실행중인 명령어 + 8을 가리키게 된다.

출처 : http://recipes.egloos.com/4982170

   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

main 함수 부분을 보면 key1을 호출하고 r0 값을 r4에 넣는다. 그리고 key2를 호출하고 r0 값을 r3에 넣는다.

이후 r4와 r3 값을 더해서 r4에 넣는다. key3도 호출하고 r0값을 r3에 넣어 r4와 r3를 더해 r2 레지스터에 넣는다.

  • r4 = key1

  • r3 = key2

  • r4 = r4 (key1)+ r3(key2)

  • r3 = key3

  • r2 = r4(key1 + key2) + r3(key3)

이렇게 된다. 그리고 입력한 key 값과 비교하게 된다.

(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

key1에서는 pc 값을 r3에 넣는다.

pc는 현재 명령어 + 8 이기 때문에 key1는 0x00008ce4가 된다.

(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

key2에서는 pc 값을 r3에 넣고, r3에 4를 더한다. pc 값은 0x00008d08이므로 r3에는 0x00008d0c가 된다.

즉 key2 값은 0x00008d0c가 된다.

(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

key3에서는 r3에 lr 값을 넣는다. lr은 복귀할 주소를 담고 있다. main+64에서 호출했기 때문에 main+68의 주소를 갖고있다.

key3는 0x00008d80이 된다.

key1, key2, key3을 모두 더하게 되면


108400이 된다.


'Wargame > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] shellshock  (0) 2020.01.26
[pwnable.kr] mistake  (0) 2020.01.26
[pwnable.kr] flag  (0) 2020.01.26
[pwnable.kr] bof  (0) 2020.01.26
[pwnable.kr] collision  (0) 2020.01.26
Comments