ipwn

[tamuCTF] pwn5 본문

CTF's/tamuCTF

[tamuCTF] pwn5

ipwn 2018. 2. 27. 19:40


이번엔 pwn5문제다.



static linked 컴파일 되어있고 nx가 걸려있다.


휴 733kb이길래 갑자기 왜 이렇게 함수가 많아진거지 했는데, 그냥 스태틱 링킹 방식으로 컴파일 한거였다.

바로 풀러 가보자.


int __cdecl main(int argc, const char **argv, const char **envp)
{
  print_beginning();
  return 0;
}



print_beginning함수를 호출해준다.


int print_beginning()
{
  int result; // eax
  char v1; // [esp+Fh] [ebp-9h]
 
  puts("Welcome to the TAMU Text Adventure!");
  puts("You are about to begin your journey at Texas A&M as a student");
  puts("But first tell me a little bit about yourself");
  printf("What is your first name?: ");
  fgets(&first_name, 100, stdin);
  strtok(&first_name, "\n");
  printf("What is your last name?: ");
  fgets(&last_name, 100, stdin);
  strtok(&last_name, "\n");
  printf("What is your major?: ");
  fgets(major, 20, stdin);
  strtok(major, "\n");
  printf("Are you joining the Corps of Cadets?(y/n): ");
  v1 = getchar();
  corps = v1 == 121 || v1 == 89;
  printf("\nWelcome, %s %s, to Texas A&M!\n");
  if ( corps )
    result = first_day_corps();
  else
    result = first_day_normal();
  return result;
}



first_name, last_name, major을 입력받는데, 놀랍게도 모두 bss영역이다.


아무튼 저 corps변수가 참일 때 함수인 first_day_corps함수를 들여다보겠다.


int first_day_corps()
{
  int result; // eax
 
  printf(
    "You wake with a start as your sophomore yells \"Wake up fish %s! Why aren't you with your buddies in the fallout hole?\"\n");
  puts("As your sophomore slams your door close you quickly get dressed in pt gear and go to the fallout hole.");
  puts("You spend your morning excersizing and eating chow.");
  puts("Finally your first day of class begins at Texas A&M. What do you decide to do next?(Input option number)");
  puts("1. Go to class.\n2. Change your major.\n3. Skip class and sleep\n4. Study");
  getchar();
  result = (char)getchar();
  if ( result == '2' )
  {
    printf("You decide that you are already tired of studying %s and go to the advisors office to change your major\n");
    printf("What do you change your major to?: ");
    result = change_major();
  }
  else if ( result > '2' )
  {
    if ( result == '3' )
    {
      result = puts(
                 "You succumb to the sweet calling of your rack and decide that sleeping is more important than class at the moment.");
    }
    else if ( result == '4' )
    {
      puts(
        "You realize that the corps dorms are probably not the best place to be studying and decide to go to the library");
      result = printf(
                 "Unfortunately the queitness of the library works against you and as you are studying %s related topics "
                 "you start to doze off and fall asleep\n");
    }
  }
  else if ( result == '1' )
  {
    puts("You go to class and sit front and center as the Corps academic advisors told you to do.");
    printf(
      "As the lecturer drones on about a topic that you don't quite understand in the field of %s you feel yourself begin"
      "ning to drift off.\n");
    result = puts("You wake with a start and find that you are alone in the lecture hall.");
  }
  return result;
}



뭐가 막 길다.

getchar로 '2'를 입력받았을 때 호출하는 함수인 change_major함수를 한 번 들여다보자.


int change_major()
{
  char dest; // [esp+Ch] [ebp-1Ch]
 
  getchar();
  gets(&dest);
  strncpy(&dest, major, 0x14u);
  return printf("You changed your major to: %s\n");
}



바로 여기서 취약점이 터진다.


gets로 dest를 범위를 초과해서 입력을 받는다.


bss도 주어졌으니 system을 사용하면 될 것 같지만, 바이너리 내에서 system함수가 없기 때문에 그건 불가능하다.

근데 놀라운 사실이 있다.



mprotect함수가 바이너리 내에 존재한다.


이제그냥 exploit해주면 될 것 같다.


first_name이나 last_name 둘 중 하나를 골라서 shellcode를 때려박고, mprotect함수로 실행권한을 준 뒤에

ret을 그 곳으로 변조한다면 shell이 띄워질 것이다.





gigem{r37urn_0f_7h3_pwn}


정말 문제들이 아낌없이 주는 나무였다.


pwn5


'CTF's > tamuCTF' 카테고리의 다른 글

[tamuCTF] pwn4  (0) 2018.02.27
[tamuCTF] you can run, you can hide  (0) 2018.02.26
[tamuCTF] Bender  (0) 2018.02.26
[tamuCTF] Veggies  (0) 2018.02.26
[tamuCTF] pwn3  (0) 2018.02.26
Comments