문제는 이렇다. 힌트가 될만한 건 없어보임.
들어가기에 앞서서,
이 문제는 pwntools의 소소한 사용법들을 많이 익힐 수 있었던 문제이다.
접속 후에 파일 목록을 보면 이렇다.
C 소스를 주었다.
그 전에 우선 input 바이너리를 실행시켜보자.
문제에서는 프로그램에 input을 올바르게 넣으면 플래그를 준다고 한다.
C소스를 보러가자.
우선 소스 맨 아래에 flag를 출력 시켜주는 함수 구문이 있다. 여기에 도달해야하는게 최종목표이다.
도달하기 까지 총 5단계의 과정이 있다.
첫 번째 단계이다. 바이너리에 argv 인자의 형태로 input을 잘 넣을 수 있는지 보는 과정이다.
우선 인자의 개수는 바이너리경로 포함 100개의 argv를 갖고있어야한다. (argc != 100)
그리고 argv['A'] == argv[65] 에는 NULL 값이,
argv['B'] == argv[66] 에는 "\x20\x0a\x0d" 값이 들어가있어야 stage1 이 클리어된다.
두 번째 단계이다. 표준 입출력으로 input을 잘 넣을 수 있는지 보는 과정이다.
read(0, buf, 4); 의 표준 입력 형태의 read는 아무 문제 없지만,
read(2, buf, 4); 의 표준 에러 형태의 read는 어떻게 해결해야할까?
pwntools 의 process 함수에는 일반 executable 바이너리 경로 외에도 여러가지
인자들을 넣을 수 있음을 알 수 있었다.
http://docs.pwntools.com/en/stable/tubes/processes.html
(pwntools process 함수의 원형 및 설명 원문)
일단은 리다이렉션을 이용하여 stderr 파일을 자신의 작업공간에 만들어주자.
python -c'print "\x00\x0a\x02\xff"' > stderr |
그 결과, 만들어진 stderr 파일을 어떻게 써먹느냐?
s = process(executable="/home/input2/input", stderr=open("./stderr")) |
이런 식으로 stderr가 ./stderr의 바이너리를 참조할 수 있도록 지정해주면
stage 2 단계도 넘어갈 수 있다.
세 번째 단계이다. 환경변수 형태의 input을 잘 넣을 수 있는지 확인하는 과정이다.
getenv로 "\xef\xbe\xad\xde" 에 있는 변수 값을 "\xca\xfe\xba\xbe" 와 같은지 비교하고
같으면 stage 3를 클리어 시킨다.
여기에서도 pwntools의 process 가 쓰인다.
우선, 환경변수를 딕셔너리 형태로 저장하자.
envV={"\xef\xbe\xad\xde" : "\xca\xfe\xba\xbe"} s=process(executable="/home/input2/input", stderr=open("./stderr"), env=envV} |
위 처럼 process의 env에는 환경변수를 지정해줄 수 있다.
이로써 stage 3 단계도 넘어갈 수 있다.
네 번째 단계이다.
파일을 이용한 input 입력을 할 수 있는지 확인하는 과정이다.
buf에는 "\x00\x00\x00\x00" 가 담겨있어야 stage 4 가 클리어 될 것이다.
일단 buf는 \x0a 라는 이름을 가진 파일에서 4바이트를 읽어올 버퍼이다.
그러면 일단 지금의 exploit 코드가 있는 디렉토리에 "\x00\x00\x00\x00" 의 데이터를 가진 \x0a 파일이
있어야한다.
그래서 처음에는 stage 2 처럼 리다이렉션으로 \x0a 파일을 만들어서 하려 했으나
\(백슬래시) 부분이 생략되는 과정때문에 python 코드로 처리 하기로 하였다.
with open("./\x0a","a") as f: f.write("\x00\x00\x00\x00") |
이렇게 하면 백슬래시 생략없이 \x0a 파일을 만들 수 있다.
마지막 단계이다. 이 부분은 소켓을 공부하지않아서 오래걸렸는데,
socket 함수로 얻어낸 소켓을 bind 함수로 saddr에 넣는다.
방식은 AF_INET(TCP) 이며 포트는 argv['C'] = argv[67]에 있는 값을 가져온다.
그리고 그 포트로 된 소켓서버를 열고 거기에 "\xde\xad\xbe\xef" 데이터를 보내주면통과!
[exploit code]
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from pwn import *
argvs=[str(i) for i in range(100)]
argvs[ord('A')]="\x00"
argvs[ord('B')]="\x20\x0a\x0d"
argvs[ord('C')]="9439"
envV={"\xde\xad\xbe\xef":"\xca\xfe\xba\xbe"}
with open("./\x0a","a") as f:
f.write("\x00\x00\x00\x00")
s=process(executable="/home/input2/input",argv=argvs,stderr=open("./stderr"),env=envV)
s.sendline("\x00\x0a\x00\xff")
tmp=remote("127.0.0.1",9439)
tmp.sendline("\xde\xad\xbe\xef")
s.interactive()
|
'<Wargame & CTF> > Pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] blukat (0) | 2021.05.30 |
---|---|
[Pwnable.kr] asm (0) | 2021.05.29 |
[Pwnable.kr] memcpy (0) | 2021.05.29 |
[Pwnable.kr] Unlink (0) | 2020.09.22 |
[Pwnable.kr]shellshock (0) | 2019.05.11 |