Learn every moment to make deepen me :D
http://pwnable.kr/play.php < 이 곳으로 접속해서 진행할 수 있다.
http://pwnable.kr/play.php
pwnable.kr
귀여운 얼굴에 그렇지 못한 태도...
English Attack...
엄마! Linux에 있는 file descriptor가 무엇인가요?!
(나도 모른다 아들아....)
Linux의 파일 디스크립터 관련한 문제인 것 같다.
내 OS는 친근한 windows 이므로 문제를 풀기 위해서는 가상머신으로 Linux를 돌려 터미널로 들어가거나 putty를 이용하면 되는데 후자를 택하도록 한다.
오랜만에 하는 Putty ^_^
을 보면 (argc<2) 가 참이면, pass argv[1] a number\n 라는 문구를 출력하고 프로그램을 종료하도록 되어 있다.
여기서 C언어의 main 함수 인자 int argc와 char* argv[]는 인수 갯수와 인수 값을 의미로 쓰인다.
이 부분은 C언어 파트에서 자세히 알아보도록 하자. 갈길이 멀다!
리눅스에서는 파일을 실행할 때 ./fd 의 형태로 실행할 수 있는데 옆에 인자값을 줄 수 있다.
./fd 12345 를 입력하게 되면 main 함수가 실행될 때 12345를 argv[]의 값으로 받게 되는 것.
즉, fd 파일을 실행할 때 인자값을 주지 않으면 인자값을 입력하라는 문구와 함께 프로그램 강제 종료시켜버리는 코드인 것이다.
atoi 함수 : ascii to int , ascii 값을 int 값으로 치환해 주는 함수이다.
argv[]는 main에서 char* 타입으로 받게 되어 있어 우리가 숫자를 입력해도 ascii 형태의 숫자값으로 들어오게 된다.
atoi 함수를 써서 치환한 argv[1]의 값에 0x1234를 뺀 정수 값을 fd에 대입한다.
※16진수 0x1234는 10진수 4660이다.
0001 0010 0011 0100 -> 4096 + 512 + 32 + 16 + 4 = 4660
read 함수 : 쉽게 말해서 파일을 읽는 함수인데 파일 디스크립터(File Descriptor)가 여기서 등장한다.
read 함수의 인자는 다음 3가지이다.
여기서 file descriptor란, 윈도우에서의 핸들(Handle)과 동일한 개념으로
리눅스에서 프로세스가 파일에 접근할 때 사용하기 위한 인덱스라고 볼 수 있다.
이 인덱스 값 중 미리 예약된 값이 있는데 다음과 같다.
0 = 표준 입력(키보드) / 1 = 표준 출력(모니터) / 2 = 표준 에러(모니터)
즉 ★fd 값이 0이라면, 키보드를 통해 원하는 값을 입력하여 buf 에 저장할 수 있다는 의미이다.
드디어 flag에 대한 코드가 나온다!
strcmp 함수 : 인자로 받은 두 문자열을 비교하여 동일하면 0을 반환, 다르면 1을 반환하는 함수이다.
그러나 위의 코드에서는 if문 실행을 위해 앞에 !(not)이 붙었으므로 동일하면 1을 반환하도록 되어 있다.
LETMEWIN 이라는 문자열과 buf에 저장된 문자열이 동일해야 flag 파일을 열 수 있다는 뜻!
따라서 이 문제의 해결 조건은,
(1) fd 값이 0이 되게 하여 표준 입력을 받을 수 있도록 하기
(2) 그러려면, ./fd 명령어 실행 시 인자값을 주어야 하고 (첫번째 if문 거짓되도록)
(3) ./fd 인자값이 0x1234여야 한다. (0x1234 - 0x1234 = 0)
(4) 마지막으로, LETMEWIN 문자열을 입력하여 !strcmp() 반환값이 1이 되도록 하여야 한다.
포스팅을 위해 한번 더 풀었더니 아래의 메시지가 뜬다;; 1점 이미 받았기에...
Pwnable 1번 [fd]
http://pwnable.kr/play.php < 이 곳으로 접속해서 진행할 수 있다.
문제 1번 - [fd]
엄마! Linux에 있는 file descriptor가 무엇인가요?!
(나도 모른다 아들아....)Linux의 파일 디스크립터 관련한 문제인 것 같다.
내 OS는 친근한 windows 이므로 문제를 풀기 위해서는 가상머신으로 Linux를 돌려 터미널로 들어가거나 putty를 이용하면 되는데 후자를 택하도록 한다.
오랜만에 하는 Putty ^_^
1) putty 접속
2) pw 입력
3) ls 명령으로 파일, 디렉토리 list 확인
4) fd.c 파일 읽기
5) 코드 분석
첫번째, 상단의 if문 조건식
을 보면 (argc<2) 가 참이면, pass argv[1] a number\n 라는 문구를 출력하고 프로그램을 종료하도록 되어 있다.
여기서 C언어의 main 함수 인자 int argc와 char* argv[]는 인수 갯수와 인수 값을 의미로 쓰인다.
이 부분은 C언어 파트에서 자세히 알아보도록 하자. 갈길이 멀다!리눅스에서는 파일을 실행할 때 ./fd 의 형태로 실행할 수 있는데 옆에 인자값을 줄 수 있다.
./fd 12345 를 입력하게 되면 main 함수가 실행될 때 12345를 argv[]의 값으로 받게 되는 것.
즉, fd 파일을 실행할 때 인자값을 주지 않으면 인자값을 입력하라는 문구와 함께 프로그램 강제 종료시켜버리는 코드인 것이다.
두번째, int fd = atoi(argv[1]) - 0x1234;
atoi 함수 : ascii to int , ascii 값을 int 값으로 치환해 주는 함수이다.
argv[]는 main에서 char* 타입으로 받게 되어 있어 우리가 숫자를 입력해도 ascii 형태의 숫자값으로 들어오게 된다.
atoi 함수를 써서 치환한 argv[1]의 값에 0x1234를 뺀 정수 값을 fd에 대입한다.
※16진수 0x1234는 10진수 4660이다.
0001 0010 0011 0100 -> 4096 + 512 + 32 + 16 + 4 = 4660
세번째, len = read(fd, buf, 32);
read 함수 : 쉽게 말해서 파일을 읽는 함수인데 파일 디스크립터(File Descriptor)가 여기서 등장한다.
read 함수의 인자는 다음 3가지이다.
여기서 file descriptor란, 윈도우에서의 핸들(Handle)과 동일한 개념으로
리눅스에서 프로세스가 파일에 접근할 때 사용하기 위한 인덱스라고 볼 수 있다.
이 인덱스 값 중 미리 예약된 값이 있는데 다음과 같다.
0 = 표준 입력(키보드) / 1 = 표준 출력(모니터) / 2 = 표준 에러(모니터)
네번째, 하단의 if문
드디어 flag에 대한 코드가 나온다!
strcmp 함수 : 인자로 받은 두 문자열을 비교하여 동일하면 0을 반환, 다르면 1을 반환하는 함수이다.
그러나 위의 코드에서는 if문 실행을 위해 앞에 !(not)이 붙었으므로 동일하면 1을 반환하도록 되어 있다.
따라서 이 문제의 해결 조건은,
6) flag 찾아 입력하기
포스팅을 위해 한번 더 풀었더니 아래의 메시지가 뜬다;; 1점 이미 받았기에...'Wargame > pwnable.kr' 카테고리의 다른 글