이번에는 nc로 접속해서 원격으로 풀어야 한다.
접속해보니 다음과 같은 내용들을 확인할 수 있다.
root@root:~$ nc pwnable.kr 9007
---------------------------------------------------
- Shall we play a game? -
---------------------------------------------------
You have given some gold coins in your hand
however, there is one counterfeit coin among them
counterfeit coin looks exactly same as real coin
however, its weight is different from real one
real coin weighs 10, counterfeit coin weighes 9
help me to find the counterfeit coin with a scale
if you find 100 counterfeit coins, you will get reward :)
FYI, you have 60 seconds.
- How to play -
1. you get a number of coins (N) and number of chances (C)
2. then you specify a set of index numbers of coins to be weighed
3. you get the weight information
4. 2~3 repeats C time, then you give the answer
- Example -
[Server] N=4 C=2 # find counterfeit among 4 coins with 2 trial
[Client] 0 1 # weigh first and second coin
[Server] 20 # scale result : 20
[Client] 3 # weigh fourth coin
[Server] 10 # scale result : 10
[Client] 2 # counterfeit coin is third!
[Server] Correct!
- Ready? starting in 3 sec... -
N=972 C=10
뭐 특별히 공격할 수 있는 게 떠오르지 않아서 게임이라도 풀어보자! 하고 풀어보았다.
처음에 한번 맞추는 코드는 금방 짰는데 돌리고 보니까 100번을 찾아야 하는 것이었다.
그래서 몇 줄 추가했더니 코드가 금방 맛이 가버려서.. 꼬여져서! 다시 푸는 법을 알았으니 정리해서 풀었다!
문제 자체는 특별히 어려운 것이 아니었다.
주어진 0 ~ N-1의 범위에서 9의 무게를 갖는 번호를 찾으면 되는 것이기 때문에, 바로 반씩 나눴다.
반쪽의 합을 구해서 10의 배수이면 반대쪽에 9가 있을 것이고 1의 자릿수가 9라면 합을 구한 쪽에 9가 있기 때문이다! 그리고 특별한 점이 없나 여러 번 접속해본 결과 웬만하면 C의 횟수 안에 N을 찾을 것처럼 보였기 때문에 바로 코드를 짰다.
그러나 또 막혔다... 크기가 N인 배열을 주고 subarray로 슬라이싱 해가면서 찾아가려 했는데, 제한시간 60초 때문에 계속 막혔다. 그래서 리스트 생성에 시간이 오래 걸릴 것 같아 배열이 아닌 숫자로 인덱싱 하기로 했다.
하지만 어림도 없지 ㅋㅋ! 또 시간 초과가 뜬다.. virtualbox가 문제인 것일까 하고 환경을 바꿔보기로 했다!
흠.. 듀얼 뷰티인 우분투로 해도 안된다....
그래서 혹시나 네트워크 문제 있는가 하고 다른 블로그들 write up에 올라온 것도 찾아서 돌려봤는데 마찬가지로 time exipired가 발생한다.
노트북으로 무선 네트워크를 사용하고 있는데 조금 이따가 동생 컴퓨터를 뺏어서 유선 네트워크에서 시도해봐야겠다.
일단 짠 코드는 다음과 같다.
from pwn import *
r = remote("pwnable.kr", 9007)
r.recvuntil('- Ready?')
for k in range(100):
r.recvuntil('N=')
N = int(r.recvuntil(' '))
r.recvuntil('C=')
C = int(r.recvuntil('\n'))
print("N : {} C : {}".format(N, C))
low = 0
high = N - 1
for t in range(C):
mid = low + (high - low) // 2
payload = ""
for i in range(low, mid + 1):
payload += str(i) + " "
r.sendline(payload)
ret = int(r.recvline())
if ret % 10 == 9:
high = mid
elif ret % 10 == 0:
low = mid + 1
r.sendline(str(high))
print(r.recvline())
r.interactive()
r.close()
from pwn import *
r = remote("pwnable.kr", 9007)
r.recvuntil('- Ready?')
for k in range(100):
r.recvuntil('N=')
N = int(r.recvuntil(' '))
r.recvuntil('C=')
C = int(r.recvuntil('\n'))
print("N : {} C : {}".format(N, C))
low = 0
high = N - 1
for t in range(C):
mid = low + (high - low) // 2
payload = ""
for i in range(low, mid + 1):
payload += str(i) + " "
r.sendline(payload)
ret = int(r.recvline())
if ret % 10 == 9:
high = mid
elif ret % 10 == 0:
low = mid + 1
r.sendline(str(high))
print(r.recvline())
r.interactive()
r.close()
++ 유선으로 연결해도 마찬가지였다. 단지 네트워크 문제인 것 같으니 위에서 말한 대로 pwnable.kr 내부에서 돌리기로 했다.
사실 여기서 엄청 헤맸다. pwnable.kr에 어떻게 들어가는지 몰랐는데.. 다른 write up들을 보니 그냥 이전 문제들 중 pwnable.kr안에 접속하는 것 아무거나 이용하라는 것이었다........ 허탈..
일단 시도해보았다!
첫 번째 문제인 fd로 pwnable.kr에 접속해 보았다.
/tmp/SURI에다가 작성해보겠다.
여기서는 내부에서 실행하기 때문에 주소를 127.0.0.1로 해주었다.
N : 118 C : 7
Correct! (97)
N : 578 C : 10
Correct! (98)
N : 902 C : 10
Correct! (99)
[*] Switching to interactive mode
Congrats! get your flag
b1NaRy_S34rch1nG_1s_3asy_p3asy
$
와우... 어마 무시하게 빨라버렸다..
다 풀어놓고 이래저래 방황해버렸다.
짜고 보니 사실상 이진 탐색방법의 원격 코드를 짜기 위한 목적의 문제였는지 궁금해졌다.
잘못된 점이나 부족한 점 지적해주시면 감사하겠습니다
'pwnable > pwnable.kr' 카테고리의 다른 글
[pwnable.kr Toddler's Bottle] memcpy write up (0) | 2019.08.25 |
---|---|
[pwnable.kr Toddler's Bottle] uaf write up (0) | 2019.08.22 |
[pwnable.kr Toddler's Bottle] blackjack write up (0) | 2019.08.22 |
[pwnable.kr Toddler's Bottle] shellshock write up (0) | 2019.08.17 |
[pwnable.kr Toddler's Bottle] mistake write up (0) | 2019.08.17 |