VolgaCTF 2019 Qualifier Writeup

この大会は2019/3/30 0:00(JST)~2019/4/1 0:00(JST)に開催されました。
今回もチームで参戦。結果は550点で414チーム中120位でした。
自分で解けた問題をWriteupとして書いておきます。

Shadow Cat (crypto 100)

shadowファイルがあるので、それを解析するところから始める。
パスワードが設定されているところだけ切り出し、passwdファイルも適当に作成する。

$ cat passwd
jr:x:1000:1000:,,,:/home/jr:/bin/bash
z:x:1001:1000:,,,:/home/jr:/bin/bash
a:x:1002:1000:,,,:/home/jr:/bin/bash
x:x:1003:1000:,,,:/home/jr:/bin/bash
q:x:1004:1000:,,,:/home/jr:/bin/bash
l:x:1005:1000:,,,:/home/jr:/bin/bash
v:x:1006:1000:,,,:/home/jr:/bin/bash
e:x:1007:1000:,,,:/home/jr:/bin/bash
f:x:1008:1000:,,,:/home/jr:/bin/bash
b:x:1009:1000:,,,:/home/jr:/bin/bash
r:x:1010:1000:,,,:/home/jr:/bin/bash
g:x:1011:1000:,,,:/home/jr:/bin/bash
n:x:1012:1000:,,,:/home/jr:/bin/bash
o:x:1013:1000:,,,:/home/jr:/bin/bash
p:x:1014:1000:,,,:/home/jr:/bin/bash
s:x:1015:1000:,,,:/home/jr:/bin/bash
c:x:1016:1000:,,,:/home/jr:/bin/bash
w:x:1017:1000:,,,:/home/jr:/bin/bash
d:x:1018:1000:,,,:/home/jr:/bin/bash
t:x:1019:1000:,,,:/home/jr:/bin/bash
h:x:1020:1000:,,,:/home/jr:/bin/bash
m:x:1021:1000:,,,:/home/jr:/bin/bash
k:x:1022:1000:,,,:/home/jr:/bin/bash
i:x:1023:1000:,,,:/home/jr:/bin/bash
y:x:1024:1000:,,,:/home/jr:/bin/bash
j:x:1025:1000:,,,:/home/jr:/bin/bash
u:x:1026:1000:,,,:/home/jr:/bin/bash
$ cat shadow
jr:$6$jKcSVswg$AWA/PLZVcOcQb6404vSsjmyJzgtC97R3iRDXSOBshuYmCcDVDhaIS6C4fVZnOI6EGhaUnrUWK2Y3jYhQ4vcmu0:17792:0:99999:7:::
z:$6$AEqLtEqq$1ojEoCgug5dzqeNfjGNE9p5SZFwIul8uOFp9vMZEz50oiUXOVFW3lw1S0fuvFY5ggi5CfbfoWaMDr2bvtSNRC/:17930:0:99999:7:::
a:$6$9Eg69bYI$q75YWUVWb4MYzkcExXukpt.VJ3fX458iZJm1ygpTLwX.CgroHpmeSG88By.zQmKyOHCvBHoA0Q001aBqbkVpg/:17930:0:99999:7:::
x:$6$5TF0Txe3$APSNzUSjFmMbsmrkCS9qE84qfu4AI2dNEjqm2PRKgSjncBTI4lECXofQ8abdAtYX6tST6FGCgOdvLlDYQTCJx0:17930:0:99999:7:::
q:$6$I3iqZL0m$nxHWvcLz7lg/ZKoKfX9dq5k0uqkOtKgLdyREAQxQkfPkVvbNHPfQaoCFfnXl1BoX1vgOcEDghVPvfRUrs6dGp1:17930:0:99999:7:::
l:$6$n8iJWaW/$M1Od8seiEL6h3L.egHubBYAk.cd8/LUctESIm69/r.gvP0eqabusN5/D1rNu1qDHOkgRpHf8PWGSb8zoxrgrp1:17930:0:99999:7:::
v:$6$GatagTHS$I1UfNfn3NGP5Vre0z7s3DGqFpjN5Pw2XhAHSw6ZSMwaMAsf8IteFedXovNlHLuIXvR9ezeya89XEOq2We7CcW1:17930:0:99999:7:::
e:$6$ZO6YiExi$7DBV0zMIqf8iy.zVTL7gbHetCmJ3LL4ROEYG/UME4Tmym82vZYkFWjiNpCGapvF83QNJKFJOjkhXMgFLfkhza.:17930:0:99999:7:::
f:$6$HXoF2OZ1$onkVfp52IRdd2OipQv3rPPsGr7QradAFTFnmXv5c9xkGy4xcgJFkoaSJzMQCtfWuU2FQ3BN3lyL47SyoIoPmy0:17930:0:99999:7:::
b:$6$I9Uq9PRG$euVEYx5TR2lUFe/k7s0e8us8xgl7j/cbiYRnvba.eFfMSSPsm5I.gcShqOLqAa58m5VISomkPpHlJ1xLgCRxw/:17930:0:99999:7:::
r:$6$J.qms5y0$YOMnlR0V.WQjqAyik3nU7TDdy8hZQZWfhF8CTJHJtd/0mrANrxBvULoXNiJnvX.yn5T3QBFu4wk3xrFye.uus1:17930:0:99999:7:::
g:$6$b4GkIuzQ$j/prK.Jy304eu6W/NG0Yz4mHDOc3BavkYRBomdjVG.fAksRM/xIDRoWcKcJw66YZmVGcV51YkIwVZHVfA//KU.:17930:0:99999:7:::
n:$6$f2QD.cIu$n70jbCSe0QVz7M48SVE2Z..IPDV0QjIfZ8D40oQOO9smt0ZeA2I0sSO927VIr1SJwupjZairVR0T/pKQ0QG3N1:17930:0:99999:7:::
o:$6$qyBGOX79$OAvGVjmH69C.0ZfObcJ0DcKzoSWHhBBt9sPVjbIJtYmT4nV/TU/zCiKgCkSQaQJ.n.vTjAScdh9htzjBzTwOT/:17930:0:99999:7:::
p:$6$EW1gOlyH$omuxKElrI3DeVoxrLet3OW3MfuFPwLwefVxOr62E.wo7szQ6.swTec1edCFiKnPc42XxMRGsrNJn36mkc2dgH/:17930:0:99999:7:::
s:$6$TXxh4vV5$v1vF49YZQnonSZrKwBWNp7rpxIRoQY/ooEODqjsdwwdoY8sso.y/EOsoC3GFlpCLYnEY./n/1BuNID5njg0CV.:17930:0:99999:7:::
c:$6$IYxRoIyR$eEmGTNPNd6HPQibc/UBdQ5zgR/dGQ1dtCuSl0lUmvmbrSKbYEf/SEDlX4fgP.JQXlyFqEgu4NOBiu2eozpAM.0:17930:0:99999:7:::
w:$6$RmCyBroe$EovezmWQJVvQFGd6.ei2.SfzGJG22CsV47tTnyfKx30TbuG1VMgsk0de6NOQ04bKNML9fbuMu0Pw3TMf82zye1:17930:0:99999:7:::
d:$6$..CK41Sn$36X19X0jrviLxVVk.KtR9zbHMML0mg1XzMNQgP7eOpGMF1JYSbZHAyReDhNVkm1WaNn3lfO2CsAww14fZZads1:17930:0:99999:7:::
t:$6$zVFV5HoW$q9WyP6/D0kPL.n7s.FvPcOSRfvcUFQu5QMPps6VbQUD5RMozQsP14GtUiOa/H2V2pU6c6OxcgRqruaLejPaES1:17930:0:99999:7:::
h:$6$S1RnJ8DK$F/FWFf9En/mn6YqZ67/gOnMT0WdSuaEyn2OArTJbG1IGHd0pUs9TiGDE9P.PhRB6XyHUgA5l/LBmBW8PpJg9M.:17930:0:99999:7:::
m:$6$SqkKQRak$nZHDrq3vdnajdLzotrW3J9kYzUvzPaUrs6NZaKkkcVN0KiCfUhJfgM6WJvZjZR7hBGWkfIwhZymko7wtsq49s1:17930:0:99999:7:::
k:$6$ZLCr2itT$tZ0.u7TsXPc3nAntIOepETGkhqfVG1IKaiuW0mAH5QROVuc7fonE43qEhUFT2LHMftYDdTQRAMHpRNMM8Yn1c1:17930:0:99999:7:::
i:$6$ZlWmheB2$DBLJQPLVhhEdA/iATrOYiqFv4i5TcmBUSX6.tZDo63YP4dcdlAuBnFU65xXIRP1tpNsCS7kc6Fu6jPMS2F7aP1:17930:0:99999:7:::
y:$6$rIoO6U2u$c5usMXbFP9S75qmDyBBWz1QZuyGH0MGq3mXN32kYipoL5XCFEHjmTRVcuZkmed5OzAopV0CgyA49QzILz5Rmq/:17930:0:99999:7:::
j:$6$Gpavrajq$me1yxZQ0OiJFedrTmxFsyP5zwOePuFJmgujUWun0h5bCOIVeuJuaIUTDHGCYxkT6mw41BTjlx9c3QvdsG8o0o.:17930:0:99999:7:::
u:$6$0w3EeszD$bUDQorjCKku1sjtCWMQfJ3ZRmsC5N.LN7CQnjvyCbcq5wSD33x2t/TVXA6jnjtajv8nIZc.Aj.oY80lm44Dhy0:17930:0:99999:7:::
underscore:$6$RVUCQJFr$fsKkPUT9Pp5QlsZblSLJ4yKkfBxNMWN0TS.q7ticuEr/HQFdEbyiwK5JmaKKS9UDFzUsY6mhe1knnRbwy7K0s/:17930:0:99999:7:::
underscore:x:1027:1000:,,,:/home/jr:/bin/bash
$ unshadow passwd shadow > passwd_shadow
$ john --single passwd_shadow 
Warning: detected hash type "sha512crypt", but the string is also recognized as "crypt"
Use the "--format=crypt" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 28 password hashes with 28 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
n                (n)
a                (a)
d                (s)
g                (d)
t                (u)
r                (y)
6g 0:00:01:28 DONE (2019-03-30 04:27) 0.06815g/s 1102p/s 1104c/s 1104C/s jrl1901..jl1900
Use the "--show" option to display all of the cracked passwords reliably
Session completed

一部しか解析できない。すべて一文字のパスワードとみて、辞書ファイルを作成して試してみる。

$ john --wordlist=words.txt passwd_shadow 
Warning: detected hash type "sha512crypt", but the string is also recognized as "crypt"
Use the "--format=crypt" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 28 password hashes with 28 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 AVX 2x])
Remaining 22 password hashes with 22 different salts
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
p                (h)
o                (t)
i                (e)
s                (j)
y                (p)
k                (b)
j                (f)
z                (underscore)
h                (v)
u                (k)
q                (m)
x                (o)
f                (w)
b                (x)
m                (g)
e                (c)
c                (q)
1                (jr)
l                (r)
v                (i)
w                (l)

この結果をもとにユーザ名が暗号文、パスワードが平文として、暗号文を置換してみる。

vaff_iafi_mpamxcns_iafimak_ayrahf_ybpxf_cn_kiq_fiajurf

意味が通らない。zと_以外、平文と暗号文の関係を逆にしてみる。

import string

table = string.maketrans('nasduyhtejpbfzvkmowxgcqJril', 'nadgtrpoisykj_huqxfbmec1lvw')

with open('encrypted.txt', 'r') as f:
    enc = f.read()

flag = enc.translate(table)
print flag
flag = flag.replace('J', 'jr')
print flag
pass_hash_cracking_hashcat_always_lurks_in_the_shadows
VolgaCTF{pass_hash_cracking_hashcat_always_lurks_in_the_shadows}

Blind (crypto 200)

RSAのsigningの問題。実行したいコマンドはcat flag。cat flagの整数値mが素因数分解できたら、分解したもののsignatureからcat flagのsignatureを算出できる。

m = m1 * m2
sig1 = m1**d % n
sig2 = m2**d % n
sig = (m1**d * m2**d) %d = (sig1 * sig2) % d

m = 7161132565001953639
$ python -m primefac 7161132565001953639
7161132565001953639: 103 408479 170205956447

このことからcat flagを実行して、フラグを表示させる。

import socket
import base64
from Crypto.Util.number import *

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

n = 26507591511689883990023896389022361811173033984051016489514421457013639621509962613332324662222154683066173937658495362448733162728817642341239457485221865493926211958117034923747221236176204216845182311004742474549095130306550623190917480615151093941494688906907516349433681015204941620716162038586590895058816430264415335805881575305773073358135217732591500750773744464142282514963376379623449776844046465746330691788777566563856886778143019387464133144867446731438967247646981498812182658347753229511846953659235528803754112114516623201792727787856347729085966824435377279429992530935232902223909659507613583396967

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('blind.q.2019.volgactf.ru', 7070))

sign = '1'
cmd = 'ls'
send_msg = sign + ' ' + cmd
data = recvuntil(s, ':')
print data + send_msg
s.sendall(send_msg + '\n')

cmd = 'cat flag'
cmd_int = int(cmd.encode('hex'), 16)
## factor(cmd_int) = 103 * 408479 * 170205956447
cmd1_int = 408479
cmd2_int = cmd_int / cmd1_int

sign = '1'
cmd = 'sign'
send_msg = sign + ' ' + cmd
data = recvuntil(s, ':')
print data
print send_msg
s.sendall(send_msg + '\n')

cmd1 = base64.b64encode(long_to_bytes(cmd1_int))
data = recvuntil(s, ':')
print data + cmd1
s.sendall(cmd1 + '\n')

sign = '1'
cmd = 'sign'
send_msg = sign + ' ' + cmd
data = recvuntil(s, ':')
print data
print send_msg
s.sendall(send_msg + '\n')

signature1 = int(data.split('\r\n')[1])

cmd2 = base64.b64encode(long_to_bytes(cmd2_int))
data = recvuntil(s, ':')
print data + cmd2
s.sendall(cmd2 + '\n')

data = recvuntil(s, ':')
print data

signature2 = int(data.split('\r\n')[1])

sign = str((signature1 * signature2) % n)
cmd = 'cat flag'
send_msg = sign + ' ' + cmd
print  send_msg
s.sendall(send_msg + '\n')

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

実行結果は以下の通り。

Enter your command:1 ls

flag
private_key.py
server.py

Enter your command:
1 sign

Enter your command to sign:Bjuf

17638787469642039435318581385618808297268376774234879657983959486588488518602104982122891156593317044292766030845687731228499038739756875964186679785382736177049112662098526726358737509567429436403098863630151350780807034720456854963415607468739968754202506998385349296290129607434002404738918120538229071656978017808466596814950226784314700317088934348540608219987543730472643691009060755872926833135443517648919261924577246564970061451282151317589401229797945517104524760889684000361260339607131828972845536284354091935086720068566032733497050626156914558343862499749490577165803099065730472936347462992778753796941
Enter your command:
1 sign

Enter your command to sign:D/HNwQU5

25546621042567021743921441656485106150773028771975739792395292839524991698929912254223690969899881717956277954181362001941084170643987790900354897720201198641241865168483559029881918212009804506724025449021632061776772429841832820822248791924286727129159693622880243660612170666428534633987262142793095526136680155894125768641992318145581399148611597046840862019696663630366704554135979924498320452192198270792856017753126515861945695789558862132300276176002546820728010847776307161844028813344882966643480384082356366425666269055026587464161965878493074595945942518737289891784899462357520515374555016064334840465912
Enter your command:
24276592954466402792157532919706447334355948690098023035375614012157378412616233865544533025515869836447793226406373271083160180523082800598281266834619631704245143244545577613294590334637358684061108293899492468337030535564036215463887905645938530571058038030943037016298964167966109577883005551522062164917343818964991120441652232394288629520079832539360872798332983684006902802429243645009242747601354050053448137191986860769673762567997572657102990869994555786984110522299362261357652756180804304984027320764350120137457095771345729635881422070403269427999652221843885023772233721400195669139542781850847904777323 cat flag

VolgaCTF{B1ind_y0ur_tru3_int3nti0n5}
VolgaCTF{B1ind_y0ur_tru3_int3nti0n5}