[Wargame.kr] baskin game 풀이 (697p)
Wargame/wargame.kr

[Wargame.kr] baskin game 풀이 (697p)

 

baskin game 풀이

There is no vulnerability.
Just find the rules.
nc wargame.kr 10034

 

새벽 5시에 다 풀고 토나올거 같아서 한숨 자고 지금 올린다.

서버에 들어가면 우리가 알던 배스킨라빈스31 게임 예시가 주어진다.

root@kali:~# nc wargame.kr 10034

Welcome to STITCH's baskinrobbinsN game!
Your Purpose is to win Baskin Robbins31 game from AI.

Rule)
As you already know, it seems like real Baskin Robbins31 game. But maximum number is not 31.

ex) N=101 , count 10
It situation,  You can saying up to ten at a time of number. because count is 10.
if you speaking 101 faster than AI , you lose because N is 101

you will input smaller than count...
you will input the numbers in order.

----------------------------------
hint)
N = 31, count = 3
input your name -> ab
Hi! ab
user first!
input your number -> 1 2 3
user say -> 1 2 3
computer say -> 4 5 6
input your number -> 7
user say -> 7
computer say -> 8 9 10
input your number -> 11 12 13
user say -> 11 12 13
computer say -> 14
input your number -> 15 16
user say -> 15 16
computer say -> 17 18
input your number -> 19 20 21
user say -> 19 20 21
computer say -> 22
input your number -> 23
user say -> 23
computer say -> 24 25 26
input your number -> 27 28
user say -> 27 28
computer say -> 29 30
AI win!
----------------------------------

**** Timeout is 150sec... ****
**** Total 31 round... ****
Good luck~



N = 3974, count = 201
N = 3974, count = 201
input your name ->

게임의 규칙은 다음과 같다.

1. 총 31번의 게임을 진행하고 제한 시간은 150초이다.

2. 끝 숫자 N, 최대 부를 수 있는 숫자 count가 주어진다.

3. 무조건 내가 숫자를 먼저 부른다

4. 끝 숫자를 부르는 쪽이 진다.

 

우리가 알던 배라31 게임이지만, N=31, count=3이 아닌, 매우 큰 숫자가 주어진다.

31번을 전부 이겨야하니, 당연히 운빨로는 못이기고 필승 공식을 찾아야 한다.


일반 배라31 게임에서는, 내가 숫자를 먼저 부른다고 가정 시, 2를 부르고 6,10,14,18,22,26,30을 부르면 이긴다고 한다.

이 점을 이용하여 규칙을 찾아보았다. (끝 숫자 = $N$, 최대 부를 수 있는 숫자 = $C$)

 

반복 횟수:  $repeat\,=\,int((N-1)/(C-1))$   필승 초항: $first\,=\,(N-1)\bmod(C-1)$

내가 마지막으로 불러야 하는 숫자의 리스트: $depart\,=\,first\,,first+C+1\,,first+2(C+1)...$

결론은, 내가 필승 초항을 부르고 $depart[i]$번째 까지 숫자를 부른다면? 마지막 숫자는 $N-1$이므로, 무조건 내가 이긴다.

 

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

from pwn import *

p = remote('wargame.kr', 10034)

p.recvuntil('luck')
for replay in range(0,31):
	p.recvuntil('N = ')
	N = int(p.recvuntil(',')[:-1])
	p.recvuntil('count = ')
	C = int(p.recvline())

	repeat = int((N-1)/(C+1))
	first = int((N-1)%(C+1))

	depart_arr = []
	depart_dict = []
	depart_arr.append(str(first))
	for i in range(1, repeat+1):
	    depart_arr.append(str(int(depart_arr[i-1]) + C+1))
	depart_dict = ' '.join(depart_arr)
	print 'depart_arr -> ' + depart_dict
	print 'N -> ' + str(N) + ' C -> ' + str(C)
	print str(repeat) + ' ' + str(first)
	p.recvuntil('input your name -> ')
	p.sendline('bjloed')

	p.recvuntil('input your number ->')

	arr = []
	for cho in range(0,first):
	    arr.append(str(cho+1))
	payload = ' '.join(arr)

	print 'payload -> ' + payload
	p.sendline(payload)

	for w in range(0,repeat+1):
		p.recvline() #user say
	        if(w == repeat):
	            break
		p.recvuntil('computer say -> ')
		com_say = p.recvline()
		print 'comsay -> ' + com_say
		space_cnt = int(com_say.count(' ')) + 1 #숫자 간 공백을 이용해 불러야 하는 숫자 설정
	        print 'space_cnt -> ' + str(space_cnt)
		com_end = first + space_cnt
		first = com_end 

		print 'first -> ' + str(first)
		arr = []
		print 'depart 1st ' + str(depart_arr[w+1])

		for i in range(first,int(depart_arr[w+1])):
	            first += 1
		    arr.append(str(i+1))
		payload = ' '.join(arr)

		print payload
		p.sendline(payload)
print p.recvline()
print p.recvline()