FTZ를 공부하고 처음 pwnable 문제.
BoB에서 되게 유명해서 관심이 가 공부를 시작한다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
우선 모르는 것을 조사해보자.
argc : 메인함수에 전달되는 정보의 갯수
argv : 메인함수에 전달되는 실질적인 정보, 문자열의 배열
argv[0] : 항상 실행경로가 들어감
agrv[1] : 인자 삽입
atoi = char to int = 문자열을 정수 타입으로
ssize_t read(int fd, void *buf, n_bytes) - fd가 참조하는 파일의 오프셋에서 len 바이트만큼 buf로 읽어 들임
ssize_t : 파일 읽기 성공 - 0보다 큰수 // 읽을 데이터 없을때 - 0
fd : 데이터를 전송해 주는 대상을 가리키는 파일 디스크립터 (0 : 표준입력 1: 표준출력 2: 표준에러출력)
buf : 수신한 데이터를 저장할 버퍼를 가리키는 포인터 (저장할 메모리 공간)
nbytes : 수신할 최대 바이트 수 (읽을 데이터의 크기)
strcmp(const char* str1, const char* str2) : str1과 str2를 비교하는 함수 (string.h 필요)
1) str1 < str2 인 경우 : -1 반환
2) str1 > str2 인 경우 : 1 반환
3) str1 == str2 인 경우 : 0 반환
모르는 것이 많기도 하다;;;
여기서 중요한 것은 read 함수에서 fd를 0으로 만들었을 때 표준입력을 기다리는 함수로 바뀐다는 것이다.
그랬을 때 다시 입력받은 글자는 strcmp로 비교를 들어간다.
위 3)의 경우처럼 0을 반환하게 되지만 !0 이므로 true(=1)로 판단되어 if문을 실행하는 것이다.
신기하다...!
fd를 0으로 만들기 위해서는 0x1234에 주목해야 한다. 0x를 붙이면 16진수라는 것이다.
그래서 0x1234 == 4660 이다.
mommy! I think I know what a file descriptor is!!
이게 플래그 인거 같다.
머리싸매는 재미가 쏠쏠하다.
'pwnable' 카테고리의 다른 글
[Toddler's Bottle] col (0) | 2024.05.11 |
---|---|
[Toddler's Bottle] bof (0) | 2024.05.11 |
[Toddler's Bottle] flag (0) | 2024.05.11 |
[Toddler's Bottle] passcode (0) | 2024.05.11 |
[Toddler's Bottle] random (0) | 2024.05.11 |