오늘은 Pwnable.kr coin1을 풀어보겠습니다.

귀여운 귀신 일러스트네요

이 문제는 접속 방식이 ssh가 아니라 nc 방식이네요. 한번 접속해보겠습니다.

이렇게 나오고 가만히 기다리다 보니 time expired! bye!라고 뜨면서 세션이 종료가 됩니다.

 

잘 읽어보니 대충 가짜 동전을 찾아내는 게임인것 같습니다.

 

N은 동전의 수, C는 얼마나 시도 할 수 있는지를 나타내는 수입니다.

 

진짜 동전은 10의 무게를 가지고 있고 가짜 동전은 9의 무게를 가지고 있습니다.

 

(N)을 보내면 N+1 번째 동전의 무게를 알려줍니다

 

a,b,c,d,e를 보낸다고 치면 a,b,c,d,e 번째 동전 무게의 합을 알려줍니다.

 

특정 구간의 합을 알아내 무게가 10의 배수가 안되면 그 구간에 가짜 동전이 있다는 얘기입니다.

 

전체 동전 구간을 반으로 나누어서 무게를 구해보고 그 중 10 배수가 아닌 구간을 또 반으로 그중에서 또 반으로 하면서 범위를 좁혀나가는 식으로 풀어보겠습니다.

 

from pwn import *
import re
 
#무게의 합이 10의 배수인지 아닌지 
def check (start, end, weight) :
    num = (end - start)
    print ("[!] check : num is %d" % num)
    if (10 * num == weight) :
        return 1
    else :
        return 0
 
def main () :
    r = remote("pwnable.kr", 9007)
    data = r.recvuntil("sec... -\n")
    print data
    sleep(3)
    r.recv(1024)
    # start game!
    for i in range (0, 100) :
        print ("[+] recving data..."),
        sleep(0.1)
        #    r.recv(1024)
        data = r.recv(1024)
        print (": Done, data is %s" % data),
        print ("[*] data parsing..."),
        arr = re.findall("\d+", data)
        N = int(arr[0])
        C = int(arr[1])
        print (": Done, N is %d, C is %d" % (N, C))
        # data has been parsed
 
        start = 0
        end = N
        while (start <= end) :
            msg = ""
            mid = (start + end) / 2
            print ("[+] sending msg start...")
            for j in range (start, mid + 1) :
                msg += str(j) + " "
            msg += '\n'
            r.send(msg)
            print ("[*] msg : %s" % msg),
            dt = r.recv(100)
            print ("[*] dt : %s" % dt),
            if (dt.find("Correct") != -1) :
                break
            #    sleep(3)
            weight = int(dt)
            print ("[+] weight : %d" % weight)
            #    sleep(3)
            ck = check(start, mid+1, weight)
            if (ck == 1) :
                print ("[*] counterfeit coin not found")
                start = mid + 1
            elif (ck == 0) :
                print ("[*] counterfeit coin found")
                end = mid
        print ("[+] Done, counterfeit coin has been found")
    while True :
           data = r.recvline ()
        print data
        if (data.find("bye!") != -1) :
            break
 
if __name__ == "__main__" :
    main ()

참고 : https://github.com/crater0516/pwnable.kr/blob/master/Todddlers_Bottle/coin1/solve.py

 

FLAG : b1NaRy_S34rch1nG_1s_3asy_p3asy

 

반응형
복사했습니다!