Story of CowHacker

Pwnable_input 본문

공부/Pwnable

Pwnable_input

Cow_Hacker 2020. 8. 13. 20:34
728x90

pwnable.kr 사이트 문제 중 input이라는 문제를 풀어볼 것이다.

 

문제사진

출처 : http://pwnable.kr/play.php

 

http://pwnable.kr/play.php

 

pwnable.kr

 

문제 서버에 접속을 해봤다.

 

문제서버 사진

드래그 한 부분에 대충 /tmp 아래에 파일은 언제든 지울 수 있고, /tmp 아래에 나의 디렉터리를 만들라는 소리인 거 같았다.

 

 

다음은 문제 서버에 c파일이 있길래 열어 봤다.

 

문제의 c파일 1
문제의 c파일 2

c파일의 내용은 엄청 길었다.

 

중간중간에 Stage 1 clear!라고 위 코드를 만족시키면 클리어를 시켜 주는 듯했다.

총 5개 보였다.

 

먼저 나는 Stage 1 위에 printf 문을 봤다.

 

 

 

 

 

 

printf

 

papago 번역기

출처 : https://papago.naver.com/

 

네이버 파파고

번역을 부탁해 파파고

papago.naver.com

 

프로그램에 입력하는 방법을 아냐는 것과

정확한 입력을 하면 flag를 얻을 수 있다는 말이 있는 걸로 보아

 

내가 추측한 것처럼 Stage 마다 만족 코드를 입력하면 되는 것 같았다.

 

이제 첫 번째 Stage를 봤다.

 

 

 

 

 

Stage 1

코드 해석을 해보면

1. main함수에 100개의 인자 개수를 전달하라는 것 같았다.

2. argv ['A']가 \x00 이여야 하는 것 같았다.

3. argv ['B']가 \x20\x0a\x0d 이여야 하는 것 같았다.

 

이제 이걸 어떻게 만족하는 코드를 입력해줘야 할까 하다 구글링을 해봤다.

 

처음에 봤던 /tmp 파일 밑에 내 파일을 만들어 거기에 파이썬 코드를 짜서 입력을 줘야 되는 걸 알게 되었다.

 

 

 

 

 

 

파일 만들기

 

 

나는 이 사실을 알고 난 후 " 프로그램에 입력하는 방법을 아냐 "라는 질문을 한 printf 문을 다시 한번 생각하게 됐다.

이것이 바로 프로그램에 입력하는 방법이구나 라고 말이다.

 

 

 

 

 

 

Stage 1 만족 코드

포 너블 서버에서 파일을 실행할 때 from pwn import * 를 명시해둬야 한다고 구글에 나와있어서 명시해놨다.

 

argvs라는 리스트를 만들고

그 리스트 안에 타입은 문자열로 100개를 넣었다.

그리고 ord라는 함수를 써

argvs ( ' A ' )에 \x00와

argvs ( ' B ' )에 \x20\x0a\x0d를 넣었다.

 

여기서 사용한 ord는 문자의 아스키코드 값을 돌려주는 함수다.

 

 

 

 

 

 

 

다음은 stage 2를 봤다.

Stage2

 

두 번째 문제는 표준 스트림에 대해 알아야 하는 문제였다.

 

read ( 0, buf, 4 ); 에서 숫자 0은 

표준 스트림에서 stdin을 뜻하고

 

두 번째 read ( 2, buf, 4 ); 에서 숫자 2는

표준 스트림에서 sterr를 뜻한다.

 

이제 이것을 해석해보면

 

stdin에 \x00\x0a\x00\xff을 주고 sterr에 \x00\x0a\x02\xff을 줘야 된다는 걸 알 수 있다.

그런데 여기서는 일단 sterr에만 값을 주기로 한다.

그 이유는 stage 5를 풀떄 나온다.

 

 

Stage2 만족코드

 

 

 

 

 

 

 

 

다음은 Stage 3문제를 봤다.

Stage3

getenv가 뭔지 구글링을 해보니 환경 변수를 뜻했다.

\xde\xad\xbe\xef라는 환경변수가 strcmp 즉, \xca\xfe\xba\xbe이어야 한다는 말 같았다.

 

 

 

 

 

 

Stage3 만족 코드

 

 

 

 

 

 

 

다음은 Stage 4를 봤다.

Stage4

먼저 \x0a라는 파일을 연다는 걸 볼 수 있었다.

 

그리고 if ( fread ( buf, 4, 1, fp )!= 1 ) return 0;

에서 보면 첫 번째  값이

if ( memcmp ( buf, "\x00\x00\x00\x00", 4 ) ) return 0;

\x00\x00\x00\x00 이여야 하는 것 같았다.

 

 

 

 

 

 

Stage 4 만족 코드

 

 

 

 

 

 

 

다음은 Stage 5를 보겠다.

 

마지막 Stage 5번.... 구글의 힘을 좀 많이 썼다.

 

atoi(argv ['C'])를 정수형으로 변환한 값을 포트번호로 소켓 서버를 열고

이후에 4바이트 문자열을 입력받아 \xde\xad\xbe\xef 와같으면 stage 5가 클리어 된다.

 

Stage 5 만족코드

argvs [ ord ( ' C ' ) ] = '55555'

여기서 정수형으로 변환한 값을 포트 번호로 소켓 서버를 열었다.

 

target = process (target = process(executable='/home/input2/input', argv=argvs, stderr=open('./stderr'), env=envVal)

여기서는 인자를 argv에 전달해주고 stderr파일을 열고 환경변수도 설정해주는 작업을 한다.

 

target.sendline('\x00\x0a\x00\xff')

그리고 바로 여기서 Stage 2의 stderr의 값을 넣어준다.

 

 

conn = remote('localhost''55555')

conn.send("\xde\xad\xbe\xef")

target.interactive()

마지막으로 내가 설정한 5555 포트를 열어

\xde\xad\xbe\xef이라는 값을 넘겨줬다.

 

이제 내가 만든 파일을 실행을 해봤다.

 

 

내가 만든 코드

 

 

 

 

 

 

실행1

그런데 클리어는 뜨는데 flag는 뜨지 않았다.

 

머지해서 봤는데 내가 만든 이 파일 안에는 flag가 없었다.

구글링 해보니 내 파일에 flag의 심볼릭 파일을 하나 만들고 실행을 해야 한다는 걸 알았다.

 

 

실행2

클리어가 뜨고 마지막에 flag가 보였다.

 

728x90

'공부 > Pwnable' 카테고리의 다른 글

Pwnable_Random  (2) 2020.07.24
Pwnable_Passcode  (0) 2019.12.16
Pwnable_Flag  (0) 2019.11.30
Pwnable_Bof  (0) 2019.11.29
Pwnable_collision  (0) 2019.11.24
Comments