Wargame/pwnable.xyz

[pwnable.xyz] executioner trick(?)

bjloed 2021. 7. 1. 19:25

🧡 executioner 문제 소개

int __cdecl main(int argc, const char **argv, const char **envp)
{
  _QWORD *v4; // rax
  int i; // [rsp+0h] [rbp-20h]
  int fd; // [rsp+4h] [rbp-1Ch]

  setup();
  solve_pow();
  puts("Shellcode executioner");
  fd = open("/dev/urandom", 0);
  if ( fd != -1 )
  {
    read(fd, key, 0x7FuLL);
    close(fd);
    printf("Input: ", key);
    read(0, inpt, 0x7FuLL);
    for ( i = 0; i < strlen(inpt); ++i )
      inpt[i] ^= key[i];
    v4 = mmap(0LL, 0x1000uLL, 7, 34, 0, 0LL);
    *v4 = *(_QWORD *)inpt;
    v4[1] = qword_202288;
    v4[2] = qword_202290;
    v4[3] = qword_202298;
    v4[4] = qword_2022A0;
    v4[5] = qword_2022A8;
    v4[6] = qword_2022B0;
    v4[7] = qword_2022B8;
    v4[8] = qword_2022C0;
    v4[9] = qword_2022C8;
    v4[10] = qword_2022D0;
    v4[11] = qword_2022D8;
    v4[12] = qword_2022E0;
    v4[13] = qword_2022E8;
    v4[14] = qword_2022F0;
    v4[15] = qword_2022F8;
    JUMPOUT(__CS__, v4);
  }
  puts("error");
  return 1;
}

내가 입력한 쉘코드의 길이만큼 XOR 연산을 수행하고 메모리를 mapping 하여 그 장소로 jump 하는 문제이다.

 

🧡 executioner trick

사실 트릭이라고 할 것도 없이 strlen은 '\x00' byte를 기준으로 문자열의 길이를 판단하기 때문에 앞에 널바이트 몇 개를 넣어주고 쉘코드를 작성해주면 된다. 내가 적으려던 것은 이게 아니라 내가 이 문제를 풀고 다른 분들의 풀이를 구경해봤는데 내가 비교적? 간단하게 한 것 같아서 적어보려고 한다. 물론 64bit /bin/sh code를 사용하신 분도 계셨다.

나는 main에서 mapping된 memory로 jump 할때 r12가 _start를 가리키고 있다는 점을 이용해 add instruction을 이용하여 문제를 해결하였다.