일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 오라클
- 자바스크립트 prototype
- 자바스크립트
- oracle db
- 보안뉴스한줄요약
- 자바스크립트 jQuery
- Oracle SQL
- 자바스크립트 API
- 자바스크립트 node
- 다크웹
- 자바스크립트 element api
- 자바스크립트 객체
- 카카오프로젝트
- 랜섬웨어
- 깃허브
- 보안뉴스 요약
- javascript
- php
- GIT
- python
- 카카오프로젝트 100
- 파이썬
- oracle
- ES6
- 자바스크립트 기본 문법
- 보안뉴스요약
- numpy
- 보안뉴스 한줄요약
- 보안뉴스
- 카카오프로젝트100
- Today
- Total
FU11M00N
[pwnable] pwnable.kr 1번 fd 풀이 본문
먼저 http://pwnable.kr/play.php# 사이트에 들어가서
1번 문제 fd를 클릭하여 들어가 봐요!
putty를 통해서 들어가거나 리눅스 환경에서 들어가거나 하시면 됩니다.
저는 우분투로 접속을 해보겠습니다.
사진 1-3와 같이 입력하시고 비밀번호는 guest를 입력하시면 접속이 완료됩니다!
ls 명령어를 입력하면 현재 디렉터리에 있는 내용을 볼 수 있지만,
ls -l 명령어를 입력하여 자세한 내용을 출력해보겠습니다! 여기서 자세한 내용은
펄미션(권한), 포함된 파일수, 소유자, 그룹, 파일크기, 수정 일자, 파일 이름을 뜻합니다!
현재 저희는 fd그룹에 속해져 있기때문에,
fd 파일은 그룹 권한이 r-x 이기 때문에 읽기와 실행이 가능합니다.
fd.c 파일은 파일 소유자가 root이고, other는 r-- 이기때문에 저희는 읽을 수만 있는 권한입니다.
flag 파일은 소유자가 root이고 other는 아무런 권한이 없기 때문에 저희는 읽을 수도 쓸 수도 실행할 수도 없습니다.
그럼 vim fd.c 를 입력하여
fd.c 파일을 읽어보겠습니다.
C 언어로 구성되어있고
main함수의에서 자주 쓰이는 인자인
argc(argument count) - 인자의 개수
argc(argument vecotr) - 인자의 벡터 즉 문자열의 배열이므로 백터의 테이블 형태입니다.
또 이 문제를 풀기위해 알아야하는 개념이 몇가지 있습니다.
파일 디스크립터란?
-
시스템으로부터 할당받은 파일을 대표하는 0이 아닌 정수의 값입니다.
프로세스에서 실행되는 파일들의 목록을 관리해주는 테이블의 인덱스 값입니다.
-
리눅스/유닉스는 모든 장치를 파일로 관리하는데, 일반 파일과 내부/외부 모든 장치도 파일로 취급합니다.
이 파일을 관리하는 것이 파일 디스크립터라고 부릅니다
프로세스마다 0,1,2번으로는 아래의 표로 사전 배정이 되어있고 그 뜻은 아래와 같습니다.
그러하여 하나의 파일을 생성하게 되면 3번부터 시작하여 파일 디스크립터가 부여됩니다.
번호 |
설명 |
이름 |
파일스트림 |
0 |
표준 입력 |
STDIN_FILENO |
stdin |
1 |
표준 출력 |
STDOUT_FILENO |
stdout |
2 |
표준 에러 |
STDERR_FILENO |
stderr |
atoi(ascii to int) 함수?
atoi 함수는 10진 정수 문자열을 정수로 변환하는 함수입니다.
1 문자열에서 10진 정수 숫자 문자 뒤의 일반 문자는 취소되며, 10진 정수 숫자 문자까지만 숫자로 변환됩니다.
10진 정수 숫자 문자 앞의 공백 문자는 자동 제거되어 10진 정수 숫자 문자까지만 숫자로 변환됩니다.
공백 및 10진 정수 문자가 아닌 문자로 시작하면 0을 반환합니다.
read 함수?
read함수는 open() 함수로 열기를 한 파일의 내용을 읽는 것입니다.
형태는 ssize_t read (int fd , void *buf , size_t nbytes)
인자는 int fd void *buf size_t nbytes입니다.
strcmp 함수?
strcmp 함수는 매개변수로 들어온 두 개의 문자열을 비교하여 문자열이 같다면 0을 반환하고
다르면 1 을 반환
같으면 0을 반환하는 함수입니다.
- 그럼 위의 내용을 인지하고 문제를 다시 봅시다.
atoi(argc [1])의 인자는 int로 반환되어 0x1234와 뺄셈을 하여 fd변수에 값이 들어갑니다.
그 후 read함수가 실행이 되고
read함수에서는 (int fd, void *buf , size_t nbytes) 인자이기 때문에
첫 번째에는 파일 디스크립터가 들어가고
두 번째 인자에는 저장할 버퍼의 포인터
세 번째는 버퍼의 바이트 길이입니다.
그럼 read함수 첫 번째 인자 fd에 0이란 값이 들어가면 표준 입력으로 인식되어,
키보드로 입력하는 값을 buf안에 값을 저장하게 됩니다.
16진수 0X1234를 10진수로 변환하면 4660이 나오기 때문에
인자로 4660을 넘겨주면 입력이 가능해집니다!
./fd 4660을 하면 무언가를 입력할 수 있게 됩니다.
그럼 코드를 더 살펴보자면
아래 strcmp 함수를 통해 문자열을 비교하는데,
같으면 0 다르면 1을 반환합니다.
하지만 strcmp 앞에! 이 붙어 부정이 돼버려서
같으면 1 다르다면 0이 됩니다. 즉
LETMEWIN\N과 buf를 비교하여 같다면 조건 달성을 하여
flag에 접근할 수 있습니다!
아까 무언가를 입력할 수 있는 곳에 good job 이 출력되고
flag 값인 mommy! I think I know what a file descriptor is!! 를 알려줍니다!
* 참고로 C언어 문자열 배열에선 마지막에 \n이 자동적으로
추가가 되기 때문에 LETMEWIN\N을 입력하는 것이 아닌 LETMEWIN만 입력하면 됩니다.
플래그 값을 넣어주면 fd 클리어!!