마지막의 ssh fd@pwnable.kr -p2222 와 password로 guest 를 입력해 접속한다.
ls -l 명령어를 입력해 현재 디렉토리에서 권한, 파일 수, 소유자, 그룹, 파일 크기, 수정 일자, 파일 이름 등 자세한 내용을 출력한다.
우리는 fd 그룹에 속해 있어 fd 파일의 그룹 권한이 r-x 이기 때문에, 읽기와 실행이 가능하다.
fd.c 파일은 파일 소유자가 root라서 우리는 others에 속하기 때문에 r-- 즉, 읽기 밖에 할 수 없다.
flag 파일도 소유자가 root라서 others는 아무 것도 할 수 없다.
vim fd.c 로 fd.c 파일을 읽어보자.
C 언어로 작성되었다.
argc (argument count) : 인자의 개수
argv (argument vector) : 인자의 벡터 즉, 문자열의 배열이므로 벡터의 테이블 형태
파일 디스크립터
- 시스템으로부터 할당받은 파일을 대표하는 0이 아닌 정수의 값
- 프로세스에서 실행되는 파일들의 목록을 관리해주는 테이블의 인덱스 값
- 리눅스/유닉스에서 일반 파일은 물론 내, 외부 장치들을 모두 파일로 취급해 관리하는 파일 관리자
프로세스마다 아래의 표로 0, 1, 2번은 사전 배정되어 있으며, 파일을 생성하면 3번부터 파일 디스크립터가 부여된다.
번호 | 설명 | 이름 | 파일스트림 |
0 | 표준 입력 | STDIN_FILENO | stdin |
1 | 표준 출력 | STDOUT_FILENO | stdout |
2 | 표준 에러 | STDERR_FILENO | stderr |
atoi (ascii to int) 함수
10진 정수 문자열을 정수로 변환하는 함수.
read 함수
open() 함수로 연 파일 내용을 읽는 함수.
형태 : ssize_t read (int fd , void *buf , size_t nbytes)
인자 : int fd void *buf size_t nbytes
strcmp 함수
매개변수로 들어온 두 개의 문자열을 비교하여
같으면 0을 반환, 다르면 1을 반환.
위의 개념들을 토대로 위의 함수를 보면,
atoi(argc [1])의 인자는 int로 반환되어 0x1234와 뺄셈을 하고 fd변수에 값이 들어간다.
그 후 read 함수가 실행이 되는데, read 함수에서는 (int fd, void *buf , size_t nbytes) 가 인자이기 때문에
첫 번째 - 파일 디스크립터
두 번째 - 저장할 버퍼의 포인터
세 번째 - 버퍼의 바이트 길이
위의 순서로 인자가 들어간다.
그럼 read 함수 첫 번째 인자 fd에 0이란 값이 들어가면 표준 입력으로 인식되어,
키보드로 입력하는 값을 buf 안에 값을 저장하게 된다.
16진수 0x1234를 10진수로 변환하면 4660이 나온다.
./fd 4660 으로 4660을 인자로 넘겨주면 뭔가 입력할 수 있게 된다.
코드에서 위의 부분을 보면,
strcmp 함수를 통해 문자열을 비교하고 같으면 0, 다르면 1을 반환한다.
하지만 strcmp 앞에 부정 의미인 ! 이 붙기 때문에 같으면 1, 다르면 0을 반환한다.
LETMEWIN\N 과 buf 를 비교해서 같으면 flag가 나온다는 것이다.
C 언어 문자열 배열에선 마지막에 \N 이 자동 추가되기 때문에 입력창에 LETMEWIN만 입력하면 된다.
mommy! I think I know what a file descriptor is!!
플래그다!
'Wargame > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] unlink (0) | 2023.11.19 |
---|---|
[pwnable.kr] bof (0) | 2023.09.17 |