ipwn
[tamuCTF] pwn5 본문
이번엔 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}
정말 문제들이 아낌없이 주는 나무였다.
'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