input 문제의 디렉토리를 확인해보니
flag, input 실행파일, input.c 소스코드가 들어있다.
input 파일을 실행해보았지만 별다른 소득을 얻지 못했다.
input.c 파일을 읽어보았는데 긴 코드가 들어있다.
차근차근 파악을 해보자면, 선언되어 있는 함수는 main 함수 하나이다.
Stage 1 [ argv ]
argc를 통해서 검사하는 전체 인자의 갯수는 100개여야함.
argv[ 'A' ] 는 "\x00"이여야 함 // argv[ 'A' ] = argv[65]
argv[ 'B' ]는 "\x20\x0a\x0d"여야 함 // argv[ 'B' ] = argv[66]
Stage 2 [ stdio ]
chat 형의 buf 리스트를 4byte 만큼 선언한다.
read로 읽어온 buf[0] 4byte의 값이 "\x00\x0a\x00\xff"여야 함.
read로 읽어온 buf[2] 4byte의 값이 "\x00\x0a\x02\xff"여야 함.
Stage 3 [ env ]
getenv 함수로 "\xde\xad\xbe\xef" 주소에 있는 값을 가져와
"\xca\xfe\xba\xbe"의 값과 비교했을 때 동일해야 함.
Stage 4 [ file ]
fopen 함수로 "\x0a" 파일을 값을 read 하여 buf에 입력함.
memcmp 함수로 buf의 값과 "\x00\x00\x00\x00"의 값이 일치하는지 확인함.
Stage 5 [ network ]
소캣 프로그래밍을 하고 있는 부분임.
소켓의 port 번호를 argv[ 'C' ] = argv [ 67 ] 의 인자 값으로 설정함.
이 소켓에서 4byte 만큼 값을 받아오고 이 값이 "\xde\xad\xbe\xef"의 값과 일치해야함.
* atoi 함수
- 문자 스트링(입력값은 string)을 정수값(반환값은 int)으로 변환
- NULL이나 숫자 값으로 해석될 수 있는 첫 번째 문자에서 입력 스트링 읽기를 종료
- 입력을 int형으로 변환할 수 없는 경우 리턴값은 0
* htons 함수
- 2byte 데이터에 대해 호스트 바이트 순서를 빅 엔디안 바이트 순서로 변환
- htonal은 기능은 동일하나 4byte 데이터를 사용하는 차이 가짐
- ntohs는 2byte 데이터에 대해 호스트 바이트 순서를 리틀 엔디안 바이트 순서로 변환 [ ntohl ]
- Big endian : 시작 주소에 데이터의 최상위 비트(MSB)가 오도록 저장 [ 네트워크 통신에 사용 ]
- Little endian : 시작 주소에 최하위 비트(LSB)가 오도록 저장 [ 연산이 빠르다는 장점, PC ]
- 전송하는 측은 빅 엔디안으로 전송하나 받는 측에서는 리틀 엔디안으로 읽음
리틀 엔디안을 빅 엔디안으로 처리하는 것은 read(), write() 함수 내부에 구현됨
* accept 함수
- 연결지향 소켓 타입에서 사용
- 대기하고 있는 큐에서 제일 처음 연결된 연결을 가져와 새로운 연결 소켓을 만듬
- 성공시 소켓을 위한 파일 지정 번호, 에러시 -1 반환
코드를 분석을 마쳤으니
작성 권한이 있는 tmp 디렉토리로 이동하여 Stage 1 ~ 5까지를 만족하는 코드를 작성했다.
혼자 작성해보고 싶었는데 하다가 하다가 안돼서 다른분의 포스트를 참고했다 :)..
* pwntool
- from pwm import *를 통해서 import
- process: 로컬 바이너리에 대하여 익스플로잇을 할 때 사용하는 함수
- remote: 원격 서버를 대상으로 실제 익스플로잇을 작동시킬 때 사용하는 함수
- ssh: ssh를 통하여 접속할 때 사용하는 함수
- send: 페이로드를 보낼 때 사용 하는 함수 [ send, sendline, sendafter, sendlineafter ]
- recv: 프로그램이 출력하는 값을 보기 위한 함수 () 안에 받아오는 최대 바이트 지정
- recvline() : 출력하는 데이터 중 개행문자를 만날 때 까지 저장
- recvn(): ()에 지정한 바이트 만큼만 받아와서 저장
- recvall(): 연결이 끊어지거나 프로세스가 종료될 때 까지 받아서 저장
- interactive(): 쉘 접속, 익스플로잇 파일과 프로세스의 연결을 stdin/sidout에서 process로 바뀌줌
: pwntool의 동작이 끝난 뒤에 $ 표시가 나오는 이유도 이때문
python으로 실행해보았으나 각 단계를 통과한 이후에 EOF 오류가 난다.
나는 코드를 /tmp/yujeong 디렉토리로 이동하여 작성하였으나 flag는 여전히 본래 디렉토리에만 존재하기 때문이다.
flag 파일에 심볼릭 링크를 걸어주고, 한 번 실행한 이후에 생성된 파일들을 삭제하였다.
다시 test.py 파일을 실행하여 flag 값을 얻을 수 있었다.
Mommy! I learned how to pass various input in Linux :)
끝 !