pwnable.kr (fd)

c0wb3ll ㅣ 2020. 8. 26. 10:30

pwnable.kr (fd)

ftz 랑 LOB를 끝내고 다음 할 것을 찾다가 잊고있었던 포너블.kr을 꺼내본다..

pwnable.kr problem fd

문제이름이 fd 이다. 우선 제시해준 ssh 에 접속하도록 하자.

ssh fd@pwnable.kr -p2222 password : guest

접속하면 다음과 같은 화면이 나온다.

ls 명령어를 이용해 fd, fd.c, flag 파일이 존재하는것을 확인 할 수 있다.

cat flag

당연하겠지만 flag 를 읽으려고 하였더너 권한 거부가 뜬다.....

다른 파일을 먼저 확인해보자.

cat fd.c

fd.c 라는 파일을 읽어보았다.

집중할 부분에 빨간 박스를 처놓았다.

실행 과정을 보자.

  1. 파일을 실행할 때 인자를 입력받는다.
  2. 입력받은 인자를 숫자로 바꾼뒤 0x1234를 빼는 연산을 해준다.
  3. read함수에 연산을 마친 fd 변수가 들어간다.
  4. fd 값의 따른 결과 값을 buf에 32byte만큼 저장한다.
  5. buf값과 "LETMEIN\n"의 값이 같으면 /bin/cat flag 명령어를 실행한다.

대충 이 정도의 과정을 거친다.

그럼 여기서 필요한 지식에 대해 알아보자.

fd (file descriptor)

사용자가 파일을 사용하기위해 핸들을 얻어내는 것이다.

 

우리가 알아야 할 점은 리눅스, 유닉스 시스템에서는 일반적으로 0, 1, 2번 fd는 특수한 목적으로 사용된다는 점이다.

각각의 값들의 해당하는 내용은 아래 표와 같다.

file descriptor 0, 1, 2

  • 0번 : Standard input 표준 입력
  • 1번 : Standard output 표준 출력
  • 2번 : Standard error 표준 오류

fd.c line12

즉 위 read 함수 fd 값이 0이 된다면 우리가 원하는 내용을 buf에 쓸 수 있게 된다.

문제 풀이

실행 과정

  1. 파일을 실행할 때 인자를 입력받는다.
  2. 입력받은 인자를 숫자로 바꾼뒤 0x1234를 빼는 연산을 해준다.
  3. read함수에 연산을 마친 fd 변수가 들어간다. ==⇒ fd 값을 0으로 해주어야 한다.
  4. fd 값의 따른 결과 값을 buf에 32byte만큼 저장한다.
  5. buf값과 "LETMEIN\n"의 값이 같으면 /bin/cat flag 명령어를 실행한다.

실행 과정은 위에서도 말했듯이 다음과 같다.

 

따라서 fd 값을 0으로 해주어 "LETMEIN" 이라는 문자열을 buf에 저장하기만 하면 된다.

fd 값을 0으로 해주기 위해선 첫번째 인자인 argv[1]에서 0x1234를 빼는 연산이 있기 때문에 argv[1]에 0x1234를 입력해야 한다.

0x1234는 십진수로 4660이기 때문에 4660을 인자로 넘겨주면 된다.

./fd 4660

그 후 입력 대기 상태가 될 텐데 if문을 통과하기 위해 LETMEIN을 입력해주면 플래그를 뱉어준다.

Question

if 문 안에 strcmp에 !가 붙어있길래 !연산은 0을 1로 1을 0으로 바꿔주는 연산인데 왜 붙어있는지가 궁금했다.

strcmp 반환값에 대해 찾아본 결과 strcmp는 첫번째 인자와 두번째 인자를 비교하여 ascii코드값의 차이값을 뱉어내는 것을 알 수 있었다.

따라서 if 문을 통과하기 위해서는 참 즉 0이 아닌 다른 값이 와야하는데 strcmp는 첫번째 인자와 두번째 인자의 값이 같을 때 0을 뱉어내니 이 값을 참으로 만들어주기 위해 사용한 것임을 알 수 있었다.