포스트

Pwnable.kr [fd]

Pwnable.kr [fd]


Pwnable.kr [fd]

Pwnable.kr이란?

시스템 해킹을 실습으로 배울 수 있는 아주아주아주 유용한 사이트이다.

사이트에 접속해보면, 각 파트별로 몬스터의 사진과 이름이 있다.

몬스터의 이름은 해당 문제에서 실습해볼 수 있는 분야와 연관이 있다.

​

나는 시스템 해킹에 대해 아는게 없다.

그렇기에,

내 글들은 하나하나 공부해나가는

일련의 과정이라는 점 참고하여 읽어주었으면 한다.

​ 사진1

오늘은 이 친구를 잡아보자.

​ 사진2

첫 번째 친구이다 보니, ssh 접속 정도의 튜토리얼이지 않을까 싶다.

​

‘Powershell’이나 ‘Ubuntu’에 위 명령어를 입력하여 ssh 접속을 해보자.

​ 사진3 ​

게임을 시작하기 앞서, 어떻게 플레이해야 하는지 알아보자.

포너블 게임의 최종목표는 ‘Flag’라는 무기를 찾아내 몬스터를 처치하는 것이다.

어떻게든 ‘Flag’ 파일을 찾아서 읽어낸 뒤,

사이트에 있는 Flag? 부분에 입력하면 몬스터을 수 있는 것이다.

​

모두 다같이 레벨업 하러 가보도록 하자.

1
ls -al

​

위 명령어를 이용하여 해당 디렉토리에 있는 모든 파일들을 한번 살펴보자.

​ 사진4

flag 파일이 있다!

​ 사진5

튜토리얼 일지라도 쉽게 잡혀주지는 않는다…

​

​

그렇다면, 우리가 실행할 수 있는 유일한 파일인 fd 파일을 이용해야

‘Flag’를 획득할 수 있다.

​

​

우선, fd.c 파일을 읽어보자.

1
vi fd.c

사진6

이게 머선 소리고?

​

0x1234라는 값이 보이니 이를 10진수로 변경해서 실행해보자!

​ 사진7 ​

1
./fd 4660

사진8

어? 뭔가 입력하는 칸이 뜬다!

fd.c에서 “LETMEWIN” 문자열과 일치하는지 확인하는 코드가 있었기 때문에

한번 입력을 해보자.

​ 사진9

띠용?

이게 되네?

​

코드를 하나하나 분석해보면서, 왜 된건지 어떠한 원리인건지 알아보자…!

​

먼저, 이름에 대해서 알아보자.

시스템해킹에서 fd(File Descriptor = 파일 서술자)는

유닉스 계열 운영체제에서 파일이나 네트워크 자원에 접근할 때 사용하는 고유 번호라고 한다.

​

1
int main(int argc, char* argv[], char* envp[])

위 코드에서 ‘argc’는 프로그램을 실행할 때, 전달된 ‘인자의 개수’를 의미한다.

그렇기에, 우리가 ./fd ? 로 실행했을 때, ?가 입력되는 부분은 ‘argv’ 부분이다.

​

1
if(argc<2)

“입력된 인자가 1개 이하일 때”를 가정하는 것이라는 것만 인지하고 패스~ ​

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

atoi() 함수는 내부 문자열을 정수로 바꿔주는 함수이다.

즉, 해당 코드는 우리가 입력한 정수 값에서 0x1234를 뺀 값을 ‘fd’에 입력하는 것이다.

​

1
len = read(fd, buf, 32);

위 코드의 뜻은 “fd에서 32바이트까지 읽은 뒤, 해당 문자열을 ‘buf’에 저장하고, 문자열의 길이는 ‘len’에 저장하라” 이다.

​

1
if(!strcmp("LETMEWIN\n", buf))

​

‘strcmp(A,B)’는 A==B이면 0을, 그렇지 않으면 1을 반환한다.

따라서, 우리는 ‘buf’에 ‘LETMEWIN’을 입력해야 한다. ​

“LETMEWIN”을 16진수로 변환하면, ‘0x4C45544D4557494E’이다. 혹시나 하고, 여기에 0x1234를 더하고 입력해보았지만, 되진 않았다. ㅎㅎ

‘fd’는 위에서 말했듯, ‘File Descriptor’이다.

‘fd’는 번호에 따라 이름과 역할이 아래처럼 존재한다.

번호 (FD)이름설명
0stdin ( 표준 입력 )키보드 입력
1stdout ( 표준 출력 )모니터 출력
2stderr ( 표준 에러 )에러 로그 출력

​

우리는 ‘buf’에 “LETMEWIN”을 입력해야되기 때문에,

‘fd = 0’을 만족시켜줘야 한다.

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

0x1234를 입력하게 되면, 위의 코드로 인해 ‘fd = 0’이 된다.

​

0x1234 = 4660 ( 10 )

1
2
./fd 4660
LETMEWIN

‘4660’을 넣어,

입력모드로 변경한 후에 “LETMEWIN”을 입력하면

‘Flag’가 출력된다~!

​

​

끗

이 글은 모든 권리 보유 입니다. 출처를 밝힌 게시글 링크 공유만 가능하며, 전문 복제·전재는 허용되지 않습니다.