본문 바로가기

IT(개발, 보안)/pwnable

[Pwnable 풀이] 3. coin1

세번째 문제로는 coin1을 시도해보았다. 

문제의 nc 명령어 사용을 위해 윈도우에 netcat을 까는 것 부터 시작했다, 그런데 결론적으로 말하면 netcat을 설치할 필요는 없었다.

 

netcat 설치 방법은 나동빈 선생님의 블로그 링크를 첨부하겠다

https://ndb796.tistory.com/85

 

네트워크 통신을 위한 넷캣(Netcat) 설치 및 사용법

네트워크 상에서 특정한 컴퓨터와와 통신하기 위한 유틸리티(Utility)로 넷캣(Netcat)을 사용할 수 있습니다. TCP/UDP 프로토콜을 이용하는 환경에서는 범용적으로 적용이 가능하다는 점에서 간단한

ndb796.tistory.com

 

netcat을 설치하고 cmd에서 문제의 nc 명령어를 살펴보니 다음과 같은 게임 설명이 보여졌다.

간략하게 요약하자면, N개의 코인 중 위조 코인이 하나 존재하고 해당 코인의 무게만 9 다른 코인들은 10일 때 저울을 C번 사용하여 위조 코인을 찾아내는 게임이다.

 

처음엔 직접 손으로 숫자를 입력해서 하는 건가 싶었지만 N의 크기와 입력해야하는 숫자의 갯수를 생각해보면 전혀 아닌 것 같아서 파이썬을 활용해야겠다고 생각했다.

 

그리고 접속하면 Ready? 문장 뒤에 3초정도 대기 후 N과 C값이 주어지기 때문에 N하고 C를 받기 위해서 3~4초정도 sleep하고 입력값을 받아야 하나 생각했었다.

하지만 풀이를 하면서 알게된 사실이긴 하지만 60초라는 시간 안에 100번 이상의 게임을 진행해야지만 플래그 값을 얻을 수 있기 때문에 sleep하는 방법보다는 계속해서 입력 받기를 대기하고 있는 편이 시간을 절약할 수 있을 것 같았다.

 

파이썬에는 pwntools라는 라이브러리가 존재해 편리하게 익스플로잇을 작성할 수 있도록 도와준다. pwntools에 관한 설명과 설치 방법은 구글링으로 찾은 분의 블로그의 링크를 첨부하겠다.

https://security-nanglam.tistory.com/155

 

[python] pwntools 모듈 정리

[pwntools] pwntools 설치- cmd[관리자 권한] 에서 pip install pwntools라고 입력해서 설치를 하면 된다.- 만약 설치가 안된다면 pip 환경변수 설정이 안되있는 것이므로 환경변수를 설정하자. [python]환경변수

security-nanglam.tistory.com

 

나의 경우에는 vscode를 사용해 파이썬 개발을 진행하고 있기 때문에 터미널 상에서 pip install을 사용하고 vscode를 재시작해야지 라이브러리를 사용할 수 있었다.

 

from pwn import *
from parse import *

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

for i in range(150): #100번 게임 승리시 플래그 출력
    while(1):
        tmp = p.recvline().decode('ascii')
        print(tmp)
        if len(tmp) != 0 and tmp[0] == 'N': #첫번째 문자가 N일 경우 와일문 탈출
            break

    t = parse('N={} C={}',tmp)

    N, C = map(int,t)

    print('N의 값은',N,'C의 값은',C)

    head = 0 
    tail = N

    for i in range(C):
        sep = (head + tail) // 2
        if sep == head:
            sep+=1
        val = ''
        for i in range(head,sep):
            val += str(i) + ' '

        p.sendline(val)
        print('client says',val)

        tmp = p.recvline().decode('ascii')
        print(tmp)

        if int(tmp) % 10 == 9:
            tail = sep
        else:
            head = sep


    print('가짜코인은: ',head)
    p.sendline(str(head))
    tmp=p.recvline().decode('ascii') #결과값 받기
    print(tmp)

 

가장 먼저 해야하는 건 N과 C의 값을 받아오는 건데 문자열 parsing을 위해 parse 라이브러리를 사용했다. 해당 라이브러리 설치법과 사용법은 또 구글링을 통해 찾은 개발자 분의 블로그 링크를 첨부하겠다.

https://hiseon.me/python/python-string-parse/

 

Python 문자열 파싱 - HiSEON

Python 문자열 파싱 Python에서 문자열 파싱 방법에 대해서 설명드립니다. 추출하고자 하는 데이터가 문자열 안에 포함되어 있을 경우 편리하게 추출하는 방법입니다. 추출하고자 하는 값에 이름을

hiseon.me

 

또한 문자열을 받아오는 과정에서 파이썬이 recvline()으로 받아온 값이 byte 값이라고 자꾸 warning을 띄우고 출력할 때에도 b'~~~' 이런 식으로 귀찮게 만들기 때문에 일반적인 문자열 처리를 위해 recvline() 뒤에 decode('ascii') 메쏘드를 사용해서 ascii값을 문자열로 변환하는 과정을 수행했다. 

 

N과 C의 값을 성공적으로 받아왔다면 이제 무게를 측정하는 과정을 수행한다.

 

총 C번의 수행을 하기 때문에 for 문으로 C번 반복을 구현하고 탐색과정은 이진 탐색을 사용했다. head와 tail로 총 탐색하는 범위를 지정하고 sep은 항상 head와 tail 사이의 구간을 반으로 나누어서 저울에 올릴 코인들을 지정했다.

 

저울에 올릴 코인들을 val에 저장해서 입력값으로 서버에 전송해주면 서버의 출력값(측정한 무게)를 받아서 측정한 코인들 중에 위조 코인이 있는지 확인하고 (10으로 나눈 나머지가 9인지 아닌지) head와 tail의 값을 조정해 탐색의 범위를 1/2 씩 좁혀나가는 방법을 사용한다.

 

head와 tail이 1 차이나는 경우 위조코인을 찾은것이고 이때 sep은 head와 동일하기 때문에 range(head,sep)은 빈 배열을 반환해서 sep이 head가 동일할 때 sep을 1 증가시켜주는 if 문을 추가했는데 지금 생각해보니 필요 없는 것 같다, 어차피 비교가 끝나고 저장되는 head의 값은 동일하니까. 

 

C번의 수행이 끝난 후에는 위조 코인의 번호는 head에 저장된 값이므로 이를 서버에 전송하면 Correct!(0)라는 결과값을 받을 수 있다. 괄호 안의 숫자는 수행한 횟수를 나타내는데 99가 되어야지 flag값을 출력하므로 나는 넉넉하게 for문으로 전체과정을 150번 정도 반복하게 했다.

 

가짜코인은:  708
Correct! (29)

N=663 C=10

N의 값은 663 C의 값은 10
client says 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
3309

client says 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
1649

client says 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
820

client says 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122     
409

client says 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
200

client says 102 103 104 105 106 107 108 109 110 111
100

client says 112 113 114 115 116 
49

client says 112 113
20

client says 114
9

client says 114
9

가짜코인은:  114
Correct! (30)

N=735 C=10

N의 값은 735 C의 값은 10
client says 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
3670

client says 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
time expired! bye!

 

그런데 나는 flag값을 얻지 못했다^^ 아무리 속도를 높이려고 해봐도 60초 동안 최대 38번 정도 반복밖에 할 수 없었다. 하지만 좌절하지는 않은 것이 현재 해외에서 공부하고 있기 때문에 서버와 거리가 멀어서 그런것이라 생각하기로 했다 ㅎㅎ

 

속도를 높이기 위해서 decode도 사용안해보고 parsing도 라이브러리 안스고 해봤는데 안되더라 ㅎㅎㅎ 혹시 국내에서 해당 코드 실행해주실 수 있는 분 계시다면 해보고 결과 알려주세요....ㅎ

반응형

'IT(개발, 보안) > pwnable' 카테고리의 다른 글

[Pwnable 풀이] 6. flag  (0) 2022.11.19
[Pwnable 풀이] 5. cmd1  (0) 2022.11.15
[Pwnable 풀이] 4. shellshock  (0) 2022.11.10
[Pwnable 풀이] 2. col  (0) 2022.11.09
[Pwnable 풀이] 1. fd  (0) 2022.11.09