FTZ(21)
-
[FTZ] Level 20
[ Level 20 ] level20 로그인 ID : level20 PW : we are just regular guys 코드를 보면 /bin/sh를 실행하는 코드가 없다. 따라서 쉘 코드 환경변수를 만들어서 RET에 넣어서 실행시켜야 될 것 같다. 하지만 입력에 사용한 함수가 fgets이다. fgets는 Buffer Overflow공격에 취약하지 않다. 또한 입력을 받는 길이가 79로 정해져 있어서 RET로 접근할 수 없다. 그리고 코드에 이상한 점이 하나 있다. C언어 코딩을 할 때, printf함수를 사용한다면, 보통 printf("%s", bleh);처럼 서식지정자(format specifier)를 사용하여 printf함수를 작성한다. 하지만 힌트에 나온 attackme 코드에서는 서식지정자를 사..
2021.02.25 -
[FTZ] Level 19
[ Level 19 ] level19 로그인 ID : level19 PW : swimming in pink 힌트를 확인해보면, attackme의 코드를 볼 수 있다. 코드에서 /bin/sh를 실행하는 코드가 없기 때문에 RET를 덮어씌워 /bin/sh의 쉘 코드를 실행하면 될 것이다. RET에 쉘 코드를 넣기 위해 환경변수를 만들어 준다. ( RET는 4byte지만 쉘 코드는 4byte를 초과하기 때문에 쉘 코드를 환경변수로 만들어서 환경변수의 주소(4byte)를 대신 RET에 덮어 씌우는 것이다. ) 만들어준 환경변수의 주소를 알기 위해 getenv.c 파일을 만들어준다. getenv함수를 이용하여 SHELLCODE의 주소를 알아내고 %p를 이용하여 주소를 출력해주도록 한다. gcc명령어를 사용하여 실..
2021.02.23 -
[FTZ] Level 18
[ Level 18 ] level18 로그인 ID : level18 PW : why did you do it 힌트에 나온 코드를 보면, shellout이라는 함수에서 /bin/sh를 실행하는 것으로 보아, check변수의 값을 0xdeadbeef로 만들어주어 shellout함수를 실행시키도록 해야 하는 것 같다. shellout함수를 실행시키기 전 코드를 분석한다. 변수 string, check, x, count, fds를 선언하고, ※ fd_set 구조체 File Descriptor를 지정하는 구조체이다. 여러개의 fd(file descriptor)를 select함수에서 읽기/쓰기/오류에 대한 event발생 여부 체크 모록을 관리 (간단하게 배열로 여기면 편하다.) fflush로 출력 버퍼를 비운 다음..
2021.02.23 -
[FTZ] Level 17
[ Level 17 ] level17 로그인 ID : level17 PW : king poetic attackme의 소스코드를 보니 특별한 조건을 맞출 필요 없이 setreuid함수를 사용하여 level13의 권한을 사용할 수 있어 보이지만, 바로 다음으로 call함수를 호출한 후 프로그램이 끝나도록 되어있다. 따라서 /bin/sh를 따로 실행시켜주어야한다. 우선 환경변수에 /bin/sh 쉘 코드 환경변수를 추가한다. /bin/sh의 쉘 코드는 아래와 같다. \x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe..
2021.02.15 -
[FTZ] Level 16
[ Level 16 ] level16 로그인 ID : level16 PW : about to cause mass 힌트를 보니 attackme.c 파일의 소스코드가 나온 것 같다. level16에서는 main함수 외에도 함수가 있으며, 함수 포인터가 사용되었다. ※ 함수 포인터란? 특정 함수에 대한 메모리 주소를 담을 수 있는 것 [반환값자료형](*함수포인터이름)(); ex) void (*fp)(); // 반환값과 매개변수가 없는 함수 포인터 fp 선언 힌트에 있는 void (*call)()=printit;은 printit 함수의 메모리 주소를 함수 포인터 fp에 저장한 것과 같다. 따라서 이후에 call()을 사용하게 되면 printit함수가 실행된다. 이번 문제는 Buffer Overflow을 이용하여..
2021.02.15 -
[FTZ] Level 15
[ Level 15 ] level15 로그인 ID : level15 PW : guess what 힌트엔 attackme의 소스코드가 있다. int형 포인터 변수 check가 선언이 되어있고, check가 가리키는 것의 값이 0xdeadbeef와 같아야 한다. check는 포인터 변수이므로 무조건 주소가 들어가야 한다. 따라서 0xdeadbeef의 값이 들어있는 주소를 찾아 check에 넣어주면 check가 가리키는 값도 0xdeadbeef가 되기 때문에 if문 조건에 만족할 것이다. attackme를 gdb로 실행하고, disass main을 입력하여 어셈블리 코드를 확인한다. ( set disassembly-flavor intel로 어셈블리 문법을 intel로 변경해준다. ) 변수들을 선언하기 위해 0..
2021.02.15 -
[FTZ] Level 14
[ Level 14 ] level14 로그인 ID : level14 PW : what that nigga want? 이번에도 힌트에 attackme의 소스코드가 있다. 소스코드에서 system("/bin/sh"); 가 있으니 환경변수를 만들 필요는 없다. 힌트에 있는 소스코드를 복사해서 tmp에 attack이라는 이름의 파일을 만들어 붙여 넣어 준 뒤, gcc명령어를 이용하여 실행파일을 만들어 준다. gdb로 attack 실행파일을 실행시키고, set disassembly-flavor intel을 입력하여 어셈블리 문법을 intel로 설정해주고, disass main을 입력하여 main함수를 어셈블리 코드로 출력하도록 하였다. 위 어셈블리 코드를 보면, "sub esp, 0x38"로 변수를 선언할 공간을..
2021.02.15 -
[FTZ] Level 13
[ Level 13 ] level13 로그인 ID : level13 PW : have no clue 힌트를 확인하니 이번에도 attackme의 C언어 소스코드가 적혀있는 것 같다. 소스코드를 보니 i 변수의 값이 달라졌을 경우 "Warnning: Buffer Overflow!!!"를 출력하며, kill함수가 실행되는 것으로 보인다. ※ kill함수란? 헤더파일 signal.h 함수 원형 int kill(pid_t pid, int signo); 반환 성공 : 0 / 실패 : -1 pid 의미 양의 정수 지정한 프로세스 ID에만 시그널 전송 0 함수를 호출하는 프로세스와 같은 그룹에 있는 모든 프로세스에 시그널을 전송 -1 함수를 호출하는 프로세스가 전송할 수 있는 권한을 가진 모든 프로세스에 시그널을 전송..
2021.02.15 -
[FTZ] Level 12
[ Level 12 ] level12 로그인 ID : level12 PW : it is like this level12의 힌트도 level11과 동일하게 attackme의 C언어 코드가 나왔다. 이번에는 level11과 다르게 gets로 문자열을 입력받는다. 우선 level11과 동일하게 /bin/sh 쉘 코드의 환경변수를 만들어 준다. \x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80 힌트에 있는 코드를 복사하여 tmp 디렉터리로 ..
2021.02.15 -
[FTZ] Level 11
[ Level 11 ] level11 로그인 ID : level11 PW : what!@#$? 힌트를 확인해보니 c언어 코드가 나왔다. 아마 attackme의 소스코드인 듯하다. str배열을 strcpy로 입력받는 것을 보아 Buffer Overflow를 사용하는 것 같다. 우선 소스코드는 단순히 str을 입력받아 그대로 출력하는 것이 전부이다. 하지만 setreuid를 통해서 uid를 level12로 바꾸는 것을 확인할 수 있다. 또한 ls -la로 attackme의 권한을 확인해보면 소유권을 가진 사용자가 level12인 것을 확인할 수 있다. ※ setuid비트를 실행파일에 적용하면 실 사용자(프로그램을 사용하는 사용자)에서 프로그램의 소유자의 ID로 유효 사용자(EUID)가 바뀌게 된다. 따라서 ..
2021.02.15