티스토리 뷰
카테고리
Web (132 solved)
풀이
웹 사이트와 app.py 파일이 주어진다.
웹 사이트에서는 네 개의 입력 칸이 있고 submit 버튼을 누르면 입력한 문자열을 읽어주는 .wav 파일이 생성된다.
app.py 를 보면, 입력할 수 있는 tweet의 최대 개수(MAX_TWEETS)는 4개이고 하나의 tweet당 입력할 수 있는 문자의 최대 길이는 140이다.
- 취약점
`ls` 를 입력하면 ls 명령어가 실행되어 그 결과가 음성 파일로 만들어진다.
커맨드 인젝션이 가능하다.
이제 플래그가 있는 파일을 찾아야한다.
find 명령어를 사용해서 flag 파일의 경로를 찾을 수 있다.
하지만 음성을 알아듣기 어려운데, app.py 파일에서 docker_cmd 변수를 보면 -v 옵션으로 컨테이너에서 사용할 디렉토리를 지정한 것을 볼 수 있고, /share/flag를 음성으로 들어보면 일치하는 것을 확인할 수 있다.
따라서 flag 파일은 /share 디렉토리에 있다.
해당 flag 파일을 읽으려고 하면 Internal Server Error 가 뜬다.
원인을 분석하고 flag 파일을 읽으려면 문제에서 제공한 app.py 파일을 분석해야 한다.
- app.py 분석
이 웹 어플리케이션은 flask로 만들어졌다.
flag는 소스 파일 안에 정의되어 있고 이 값을 인코딩한 값을 flag 파일로 저장한다.
인코딩 과정은 process_flag 함수를 보면 알 수 있다.
flag의 한 글자마다 ascii 범위의 랜덤 문자를 64999개 생성하고 그 64999개의 문자와 flag 한 글자를 모두 xor 연산한다.
파일에는 64999개의 랜덤 문자가 기록되고 그 뒤에, 그 64999개의 문자들을 하나하나 xor 연산하고 그 결과를 flag의 한 문자와 xor 연산 한 값이 파일에 기록된다.
결국, flag 한 글자당 65000개의 바이트가 생기는 셈이고, len(flag) * 65000 길이의 flag 파일이 생성된다.
이 flag 파일을 음성으로 읽으려고 하면 읽지 못 하는 문자가 있기 때문에 에러가 발생한다.
읽는다 하더라도 64999개의 문자를 음성으로 듣고 xor 하기에는 무리가 있다.
따라서 그 과정을 python으로 코딩하는 작업이 필요하다.
그 코드는 다음과 같다.
위 코드를 사용하면 flag 파일을 읽고 디코딩하여 원래의 flag 값을 출력해준다.
하지만 음성으로 flag를 정확하게 알아듣기 힘드므로 한 글자씩 숫자로 반환하는 방법을 선택했다.
그 코드는 다음과 같고, flag의 첫 번째 글자를 디코딩하여 출력하게 했다.
이때, flag파일은 실행할 때마다 계속 바뀌기 때문에 한 번의 시도에 반드시 65000개의 바이트를 읽어 한 글자를 복호화해야 한다.
또한 하나의 tweet에 입력할 수 있는 문자열의 최대 길이는 140이므로 위 코드를 140자 안의 한 줄로 코딩해야 한다.
Tweet 칸이 총 네 개이므로 코드를 나누어서 다시 짰다.
코드의 길이를 줄이기 위해 첫 번째 tweet에서는 /share/flag 파일을 읽어서 r 파일에 저장한다.
두 번째 tweet에서는 r 파일을 읽어서 64999개의 문자를 서로 xor 하여 그 값을 int 값으로 반환한다.
세 번째 tweet에서는 /share/flag 파일의 65000번째 글자(64999:65000)를 읽어서 int 값으로 반환한다.
두 번째와 세 번째 tweet에 대한 음성 파일을 듣고 두 숫자를 xor 연산하면 플래그의 한 글자를 알 수 있다.
- exploit
첫 번째 tweet는 [:65000]부분을 [65000*1:65000*2], [65000*2:65000*3], … 등으로 바꿔가면 다음 글자들도 알 수 있다.
최종적으로 알아낸 flag는 PCTF{L15st3n_T0__reee_reeeeee_reee_la} 이다.
'해킹 > CTF' 카테고리의 다른 글
[2017 POX CTF 예선] simpleArch write-up (0) | 2017.10.26 |
---|---|
[DEF CON CTF Qual 2017] beatmeonthedl write-up (0) | 2017.05.04 |
[2016 POX CTF final] sombra1 (100) write-up (0) | 2016.11.12 |
[2016 POX CTF final] sombra2 (300) wirte-up (0) | 2016.11.12 |
[2016 POX CTF final] keygen (100) write-up (0) | 2016.11.12 |