Wargame/wargame.kr

[Wargame.kr] plz variable 풀이 (644p)

bjloed 2020. 8. 5. 00:00
nc wargame.kr 10004 plz variable

Can you find the solution quickly in polynomials?

이번 문제도 삽으로 열심히 팠다.

 

먼저 서버에 들어가면 연립방정식 문제가 주어진다.

Submit format은 a,b,c,d... 를 오름차순 한 거고..

a,b,c,d... 는 정수고, $ 100\leq a,b,c,d... \leq1000 $란다.

참고로 미지수의 범위를 정해주지 않으면 푸는데 시간이 오래 걸린다.

우리 머리로 저런 연립방정식은 당연히 못 푸니까.. 파이썬한테 시켜보자.

 

연립방정식을 풀어주는 파이썬 라이브러리 numpy, z3중 z3를 선택했다.

대충 적어본 z3로 연립방정식을 푸는 튜토리얼이다.

from z3 import *

a = Int('a')
b = Int('b')
ss = Solver()

ss.add(a + b == 10)
ss.add(a - b == 4)

ss.check() #해를 구하는 데 성공 시, 'sat' return
print ss.model() #해 출력
rroot@kali:~/wargame.kr/plz# python ttest.py
[a = 7, b = 3]

이 정도면 대충 감이 오지 않는가?

여기서 주의해야 할 점은, 문제에서 주어지는 format은 다음과 같다.

h + f - d * e - c + b - g + a = -536765

add 함수에는 str type이 아니라 수식을 넣어야 한다.

또한, =이 아닌 ==을 넣어야 하기 때문에, pwn 라이브러리의 recvuntil을 잘 이용해보자.

 

나는 정작 답은 구해놓고 괜히 어렵게 생각해 삽질한 케이스다.

분명히 문제에서는 오름차순으로 정렬해 send 하라고 했는데..

만약 정렬 전 값이, a:1, b:3, c:2면 1,2,3을 send 하라는 줄 알고.. 아니면 a,c,b를 보낸다던가..

알고 보니, 그냥 알파벳 순서대로 보내란 거였다.

 

풀이에 사용한 코드는 다음과 같다. 원래 썼던 주석은 모두 삭제하고 올리도록 하겠다.

from pwn import *
from z3 import *

p = remote('wargame.kr', 10004)
ss = Solver()

for i in range(0,7):
    p.recvline()

for w in range(0,30):
	a = Int('a')
	b = Int('b')
	c = Int('c')
	d = Int('d')
	e = Int('e')
	f = Int('f')
	g = Int('g')
	h = Int('h')
	ss.add(a >= 100 , a<=1000)
	ss.add(b >= 100 , b<=1000)
	ss.add(c >= 100 , c<=1000)
	ss.add(d >= 100 , d<=1000)
	ss.add(e >= 100 , e<=1000)
	ss.add(f >= 100 , f<=1000)
	ss.add(g >= 100 , g<=1000)
	ss.add(h >= 100 , h<=1000)
	arr = []
	r_arr = []

	tmp_arr = p.recvuntil('=')
	tmp_sum = p.recvline()[1:]

	cnt = 0
	cnt += tmp_arr.count('+')
	cnt += tmp_arr.count('-')
	cnt += tmp_arr.count('*')

	com_arr = tmp_arr + '= ' + tmp_sum
	ss.add(eval(com_arr))
	print com_arr
	for i in range(0,cnt):
	    tmp_arr = p.recvuntil('=')
	    tmp_sum = p.recvline()[1:]
	    com_arr = tmp_arr + '= ' + tmp_sum
	    print com_arr
	    ss.add(eval(com_arr))

	print "Calculating..."
	ss.check()

	for i in range(0,cnt+1):
	    arr.append(str(ss.model()[eval(chr(97+i))]))
        
	arr = ','.join(arr)
	p.recvuntil('Answer ->')
	print arr
	p.sendline(arr)
        p.recvline()
	ss.reset()
    
print p.recvline()
print p.recvline()