엄마!! 저는 게임을 하고싶어요!(만약 네트워크 응답이 너무 길면  0 9007로 접속)

게임을 하고싶다는 문제가 나와있고 nc로 접속할 수 있는 포트가 하나 주어진다. 접속해보자.

 

…. 일단 해석을 해볼까?

나한테 몇 개의 금화가 주어진다고 한다. 근데 여기에는 위조 금화가 있다고 한다!! 가짜 금화랑 진짜는 겉으로 보기에는 똑같이 생겼지만 무게가 다르다. 진짜 금화는 무게가 10이고 가짜 금화는 9이다. 그니까 가짜 금화 100개를 찾으면 된다!! (시간은 60초 주어진다.)

 

<게임 방법>

1.     N개의 금화와 C번의 기회가 주어진다.

2.     무게를 잴 금화 더미(인덱스)를 선택한다.

3.     무게를 알아낼 수 있다.

4.     2~3번의 C번을 반복하고 답을 말하면 된다!

 

위에 게임 예시도 나와있다.

바이너리가 따로 안 주어진 것으로 보아하니까 진짜로 그냥 푸는 문제인 것 같다. 걍 코딩문제네…. 이 문제를 풀기 위해서 얼마 전 자료구조론 시간에 배운 binary search를 사용해보자!!!!

(https://dongdd.tistory.com/145 이분을 참고하였다!)

 

1.     배열의 처음을 low, 배열의 끝을 high로 설정하고 (low + high) / 2mid를 설정한다.

2.     Low mid값을 서버에 보내서 얻은 무게 값을 mod 10의 값이 0인지 9인지를 확인한다.

3.     mod값이 0이면 범위 내에 가짜 금화가 없다는 뜻이므로 lowmid + 1(가짜 금화가 배열의 끝에 있을 때도 고려)로 설정하고 mod값이 9이면 범위 내에 가짜 금화가 있다는 뜻이므로 highmid로 설정하고 위 과정을 반복한다.

 

이렇게 해서 스크립트를 짜보자.

 

#!usr/bin/python

from pwn import *

context.log_level='debug'

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

p.recv()

for i in range(100):
	p.recvuntil("N=")
	n = int(p.recvuntil(" "))
	print(n)

	p.recvuntil("C=")
	c = int(p.recvuntil("\n"))
	print(c)

	count = 0
	low = 0
	high = n

	while count != c:
		count = count + 1
		mid = (low + high) / 2
		s = ' '
		for i in range(low, mid):
			s += str(i)
			s += ' '
		s += str(mid)
		p.sendline(s)
		weight = int(p.recv())

		if weight % 10 == 0:
			low = mid + 1
		else:
			high = mid

	mid = (low + high) / 2
	p.sendline(str(mid))
	p.recv()

p.recv()

이렇게 해주면 성공한다! 근데.... 자꾸 타임아웃이 걸린다.

아까 문제에서 설명해줬던 것처럼 sshpwnable.kr 접속해서 서버 내부에서 스크립트를 실행시켜보자.

ssh fd@pwnable.kr -p2222 (pw:guest) 여기에 접속하자.

 

엄청 빠르게 성공하긴 했는데….플래그가 따로 안 나온다….. 뭘 더 받아야 하는건가…?

p.recv()를 마지막에 써줘서 한번 더 받아보자.

 

성공!!!! 플래그는 b1NaRy_S34rch1nG_1s_3asy_p3asy

'pwnable > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] lotto  (0) 2019.06.26
[pwnable.kr] blackjack  (0) 2019.06.26
[pwnable.kr] shellshock  (0) 2019.02.27
[pwnable.kr] mistake  (0) 2019.02.24
[pwnable.kr] leg  (0) 2019.02.20

+ Recent posts