coin1은 코드가 없다.


Mommy, I wanna play a game!

(if your network response time is too slow, try nc 0 9007 inside pwnable.kr server)


Running at : nc pwnable.kr 9007



라는 문자열만 주어져 있다.


연결하면


위조 동전을 찾아라. 라고 한다. 진짜 동전은 무게가 10이고, 위조동전은 9이다. 따라서 그리고 위조동전을 100개 찾으면 상을 준다고 한다. Flag이겠지..


나는

10 단위로 잘라 bruteforce를 해, 뒷자리가 9일 때 멈춘 후, 직접 찍어 맞추려고 했는데, 생각보다 찾을 확률이 너무 저조했다. 이 확률로 100번을 뚫을 수 있으면 그날에 로또를 사도 될 거라 생각할 정도였다.



from pwn import *

from operator import eq


context.log_level='debug'



flag=0


search='9'

search2 = "Correct! (0)"


r = remote("pwnable.kr", 9007)

print(r.recv(2048))

sleep(3.3)

r.recv(100)


i=20d

while 1:

payload=""

sleep(0.5)

for j in range(10):

payload += " " + str(i+j)

r.sendline(payload)

i+=10

weight = r.recv(10)

if search in weight :

i-=10

print i

break



r.interactive()




그래서 다른방법을 고민하다가 결국 다른 사람의 것을 참고했다.


위 스샷의 경우 N은 479이다. 479는 2^8과 2^9 의 사이이다. 즉 2로 나눠가면서 어느

쪽에 있는지만 찾아내면 된다.


밑의 코드는 (http://chaneyoon.tistory.com/192) 에 있다.


from pwn import *

import time

import sys


host = '0'

port = 9007


r = remote(host, port)

time.sleep(3)           # wait for 3 sec.


print r.recv()


cnt = 0

for i in range(100):

    r.recvuntil('N=')

    n = int( r.recvuntil(' ') )

    r.recvuntil('C=')

    c = int( r.recv() )

    

    st = 1

    des = n

    t = 0

    while(1):

        

        message = ''

        

        if(st > des):

            break

        

        message = ''

        for i in range(st, (st + des) // 2 + 1):

            message += '{0} '.format(i) 

        

        print "[-] guess : {0}".format(message)

        x = r.sendline(message)

        result = r.recv()

        

        print "[*] result : {0}".format(result)


        if result.find('Correct') > -1:

            t = 1

            break

        elif result[0] == 'N':

            des = n

        elif result.find('error') > -1:

            break

        elif result.find('time') > -1:

            print "\n\n[x] time expired.."

            sys.exit(1)

        elif int(result) % 10 != 0:

            des = (st + des)//2

        else:

            st = (st+des)//2 + 1

    if(t == 0):

        r.sendline(str(st))

        correctmsg = r.recv()

    cnt += 1

    print "[+] count : {0}\n".format(cnt)


flag = r.recv()

print "\n\n[*] FLAG : {0}".format(flag)




python코드가 너무 고급져서 해석하기 힘들다.


하지만 잘 보면, N=[] 부분에서 숫자를 받아와서, 그것을 message에 넣고, send로 보낸다.

그 후, recv를 통해 값을 받아오는데, 이것이 Correct, error, time 을 읿력받으면 break한다. 그렇지 않다면 2를 나눠가면서 계속 좁혀나간다.


한번 성공할때마다 cnt++를 하며 총 100번 되면 r.recv()를 통해서 FLAG를 받아온다.





내가 직접 코드를 짤 수 있게 될때까지 코드를 좀 더 분석해 봐야겠다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] lotto  (0) 2018.05.29
[Toddler's Bottle] blackjack  (0) 2018.05.29
[Toddler's Bottle] shellshock  (0) 2018.05.28
[Toddler's Bottle] mistake  (0) 2018.05.28
[Toddler's Bottle] leg  (0) 2018.05.28
블로그 이미지

천재보다는 범재

,