ubuntu@WSL2:~/CTF/pwnable.kr/flag$ wget http://pwnable.kr/bin/flag --2023-06-19 05:18:03-- http://pwnable.kr/bin/flag Resolving pwnable.kr (pwnable.kr)... 128.61.240.205 Connecting to pwnable.kr (pwnable.kr)|128.61.240.205|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 335288 (327K) Saving to: ‘flag’ flag 100%[=================================================>] 327.43K 432KB/s in 0.8s 2023-06-19 05:18:05 (432 KB/s) - ‘flag’ saved [335288/335288] ubuntu@WSL2:~/CTF/pwnable.kr/flag$ file flag flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header
x86-64 아키텍처로 컴파일된 리눅스에서 돌아가는 바이너리다.
ubuntu@WSL2:~/CTF/pwnable.kr/flag$ ./flag I will malloc() and strcpy the flag there. take it.
실행하면 매개변수 받는거 상관없이 “I will malloc() and strcpy the flag there. take it.”를 출력하고 종료한다.
풀이
strings [옵션] [파일]
위 명령어로 파일의 인쇄 가능한 문자열을 추출할 수 있다.
옵션은 다음과 같다.
- -a, –all 데이터 섹션뿐만 아니라 파일 전체를 스캔합니다 [기본값]
- -d, –data 파일에서 데이터 섹션만 스캔한다.
- -f, –print-file-name 각 문자열 앞에 파일 이름을 인쇄한다.
- -n <숫자> 최소한 <숫자> 개의 문자로 이루어진 연속된 문자열을 찾아 출력한다.
- –bytes=<숫자> 표시 가능한 문자의 개수를 지정한다. (기본값은 4).
- -t, –radix={o,d,x} 문자열의 위치를 8진수, 10진수 또는 16진수로 출력한다
- -w, –include-all-whitespace 모든 공백을 유효한 문자로 포함한다
- -o –radix=o와 동일
- -T, –target= 이진 파일 형식을 지정한다
- -e, –encoding={s,S,b,l,B,L} 문자 크기와 엔디안을 선택한다. s = 7비트, S = 8비트, {b,l} = 16비트, {B,L} = 32비트
- –unicode={default|show|invalid|hex|escape|highlight}
- -U {d|s|i|x|e|h} UTF-8 인코딩된 유니코드 문자의 처리 방법을 지정한다.
- -s, –output-separator=<문자열> 출력에서 문자열을 구분하는 데 사용할 문자열을 지정한다.
추출하면 UPX로 패킹된 바이너리인걸 알 수 있다.
ubuntu@WSL2:~/CTF/pwnable.kr/flag$ strings -tx ./flag b4 UPX! ... 4a656 $Info: This file is packed with the UPX executable packer http://upx.sf.net $ 4a6a5 $Id: UPX 3.08 Copyright (C) 1996-2011 the UPX Team. All Rights Reserved. $ ... 51d8c UPX! 51d94 UPX!
바이너리를 언패킹하기 위해 upx -d <파일> 명령어를 입력한다.
ubuntu@WSL2:~/CTF/pwnable.kr/flag$ upx -d ./flag Ultimate Packer for eXecutables Copyright (C) 1996 - 2020 UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020 File size Ratio Format Name -------------------- ------ ----------- ----------- 883745 <- 335288 37.94% linux/amd64 flag Unpacked 1 file.
그리고 정적 분석을 하면 된다.
undefined8 main(void) { char *__dest; puts("I will malloc() and strcpy the flag there. take it."); __dest = (char *)malloc(100); strcpy(__dest,flag); return 0; }
flag 006c2070 28 66 49 addr s_UPX...?_sounds_like_a_delivery_s_00496628 = "UPX...? sounds like a deliver 00 00 00 00 00 006c2078 00 ?? 00h 006c2079 00 ?? 00h 006c207a 00 ?? 00h
s_UPX...?_sounds_like_a_delivery_s_00496628 00496628 55 50 58 ds "UPX...? sounds like a delivery service :)" 2e 2e 2e 3f 20 73