쉽고 깔끔하게

[pwnable.kr] Toddler's Bottle 1번 fd 문제풀이 본문

Pwnable/pwnable.kr

[pwnable.kr] Toddler's Bottle 1번 fd 문제풀이

찐무 2021. 6. 9. 18:30
728x90
반응형

© PWNABLE.KR SINCE 2014 - ALL RIGHTS RESERVED.

 


문제

http://pwnable.kr/play.php

엄마! 리눅스에서 file descriptor가 무엇인가요?


터미널을 이용하여 ssh fd@pwnable.kr -p2222에 접속합니다. (password : guest)

ls -l 명령어를 통해 현재 디렉터리에 존재하는 파일들의 정보를 확인합니다.

[ fd ] 파일의 속성은 -r-sr-x---로 SetUID가 설정되어 있으며 실행 시 파일 소유자(fd_pwn)의 권한으로 실행됩니다.

[ fd.c ] 파일은 유일하게 아무 곳에도 속하지 못한 제 3자(other)가 파일을 읽을 수 있는 권한(-rw-r--r--)을 가지고 있습니다.

[ flag ] 파일은 파일 소유자인 fd_pwn나 root만이 해당 파일을 읽을 수 있습니다.

▶︎ 따라서 SetUID가 설정된 [ fd ] 파일이 실행되는 동안에는 [ flag ] 파일을 읽을 수 있습니다.

 

cat 명령어를 통해 [ fd.c ] 파일의 내용을 확인합니다.

해당 코드를 살펴보면,

 

  • Code 1
if(argc<2){
    printf("pass argv[1] a number\n");
    return 0;
}

인자의 갯수가 2보다 작으면(argc<2) 'pass argv[1] a number'을 출력하고 프로그램을 종료합니다.

즉, [ fd ] 파일 실행 시 인자값을 주지 않으면 'pass argv[1] a nunber'이라는 문구와 함께 프로그램이 강제 종료됩니다.

▶︎ 따라서 [ fd ] 파일 실행 시 ./fd 인자값 과 같은 형태로 실행해야 합니다.

 

  • Code 2
int fd = atoi(argv[1] - 0x1234);

※ atoi() 함수 : ascii to int라는 뜻으로 ascii(문자형)값을 int(정수형)값으로 변환해주는 함수

▶︎ 따라서 main에서 char*로 들어온 인자값(argv[1])을 정수형으로 변환하여 16진수인 0x1234가 4660이 되고, 이를 뺀 값을 fd에 저장합니다.

 

  • Code 3
len = read(fd, buf, 32);

※ read() 함수 : 파일을 읽는 함수

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t nbytes);
int fd 읽을 파일의 디스크립터 (file descriptor)
void *buf 읽어드린 데이터를 저장할 버퍼
size_t nbytes 읽어들일 데이터의 최대 크기
 file descriptor란?
: 프로세스에서 열린 파일의 목록을 관리하는 테이블의 인덱스

file descriptor에서 0, 1, 2는 프로세스가 메모리에서 실행을 시작할 때 기본적으로 할당되는 인덱스 값입니다.

0 표준 입력 stdin
1 표준 출력 stdout
2 표준 에러 stderr

▶︎ 따라서, ⭐️fd의 값을 0을 만들어준다면 입력을 통해 원하는 값을 buf에 저장할 수 있게 됩니다.

 

  • Code 4
if(!strcmp("LETMEWIN\n", buf) {
    printf("good job :)\n");
    system("/bin/cat flag");
    exit(0);
}
printf("learn about Linux file IO\n");
return 0;

※ strcmp() 함수 : 인자값1과 인자값2를 비교하여 동일하다면 0, 다르다면 1을 반환하는 함수

그러나 해당 코드는 !strcmp()이기 때문에 두 인자값이 동일하다면 1을 반환한다.

▶︎ 따라서,

  1. LETMEWIN이라는 문자열과 buf에 저장되어 있는 문자열이 동일하다면 if문의 조건이 참(1)이 되어 flag 파일을 열 수 있습니다.
  2. LETMEWIN과 동일하지 않다면 if문의 조건이 거짓(0)이 되어 'learn about Linux file IO'라는 문자열이 출력되며 프로그램이 종료됩니다.
결과적으로,

code 1) [ fd ] 파일 실행 시, ./fd 인자값 형태로 실행하기
code 2,3) file descriptor 값을 0(표준입력)으로 만들기 위해 argv[1]의 값을 4660(0x1234)로 만들어주기 
code 4) if문의 조건을 참(1)으로 만들어 주기 위해 LETMEWIN 문자열을 입력해주기

 

<정답>

▶︎ flag : mommy! I think I know what a file descriptor is!!

728x90
반응형

'Pwnable > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] Toddler's Bottle 2번 collision 문제풀이  (0) 2021.06.10