この大会は2021/9/24 18:00(JST)~2021/9/26 18:00(JST)に開催されました。
今回もチームで参戦。結果は4244点で1594チーム中56位でした。
自分で解けた問題をWriteupとして書いておきます。
Discord (misc)
Helpページを見ると、Discordに関する説明が書いてある。Discordに入り、#rulesチャネルに旗の絵文字の反応をすると、たくさんのチャネルが現れる。#request-supportチャネルのメッセージを見ると、フラグが書いてあった。
DUCTF{if_you_are_having_challenge_issues_come_here_pls}
The Introduction (misc)
適当な名前で、「50 4r3 y0u 4c7u4lly 4 h4ck3r?」の質問にyesと答えたら、フラグが表示された。
$ nc pwn-2021.duc.tf 31906
wh47 15 y0ur n4m3 h4ck3r? nora
Here are some wise words nora:
Another one got caught today, it's all over the papers. "Teenager
Arrested in Computer Crime Scandal", "Hacker Arrested after Bank Tampering"...
Damn kids. They're all alike.
But did you, in your three-piece psychology and 1950's technobrain,
ever take a look behind the eyes of the hacker? Did you ever wonder what
made him tick, what forces shaped him, what may have molded him?
I am a hacker, enter my world...
Mine is a world that begins with school... I'm smarter than most of
the other kids, this crap they teach us bores me...
Damn underachiever. They're all alike.
I'm in junior high or high school. I've listened to teachers explain
for the fifteenth time how to reduce a fraction. I understand it. "No, Ms.
Smith, I didn't show my work. I did it in my head..."
Damn kid. Probably copied it. They're all alike.
I made a discovery today. I found a computer. Wait a second, this is
cool. It does what I want it to. If it makes a mistake, it's because I
screwed it up. Not because it doesn't like me...
Or feels threatened by me...
Or thinks I'm a smart ass...
Or doesn't like teaching and shouldn't be here...
Damn kid. All he does is play games. They're all alike.
And then it happened... a door opened to a world... rushing through
the phone line like heroin through an addict's veins, an electronic pulse is
sent out, a refuge from the day-to-day incompetencies is sought... a board is
found.
"This is it... this is where I belong..."
I know everyone here... even if I've never met them, never talked to
them, may never hear from them again... I know you all...
Damn kid. Tying up the phone line again. They're all alike...
You bet your ass we're all alike... we've been spoon-fed baby food at
school when we hungered for steak... the bits of meat that you did let slip
through were pre-chewed and tasteless. We've been dominated by sadists, or
ignored by the apathetic. The few that had something to teach found us will-
ing pupils, but those few are like drops of water in the desert.
This is our world now... the world of the electron and the switch, the
beauty of the baud. We make use of a service already existing without paying
for what could be dirt-cheap if it wasn't run by profiteering gluttons, and
you call us criminals. We explore... and you call us criminals. We seek
after knowledge... and you call us criminals. We exist without skin color,
without nationality, without religious bias... and you call us criminals.
You build atomic bombs, you wage wars, you murder, cheat, and lie to us
and try to make us believe it's for our own good, yet we're the criminals.
Yes, I am a criminal. My crime is that of curiosity. My crime is
that of judging people by what they say and think, not what they look like.
My crime is that of outsmarting you, something that you will never forgive me
for.
I am a hacker, and this is my manifesto. You may stop this individual,
but you can't stop us all... after all, we're all alike.
+++The Mentor+++
50 4r3 y0u 4c7u4lly 4 h4ck3r? yes
nora, y0u w1ll n33d 7h15 0n y0ur duc7f j0urn3y 7h3n
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DUCTF{w3lc0m3_70_7h3_duc7f_7hund3rd0m3_h4ck3r}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__
/ \--..____
\ \ \-----,,,..
\ \ \ \--,,..
\ \ \ \ ,'
\ \ \ \ ``..
\ \ \ \-''
\ \ \__,,--'''
\ \ \.
\ \ ,/
\ \__..-
\ \
\ \
\ \
\ \
\ \
\ \
\ \
\ \
\ \
DUCTF{w3lc0m3_70_7h3_duc7f_7hund3rd0m3_h4ck3r}
General Skills Quiz (misc)
計算などのQuizに答えていく。
Q1: 足し算
Q2: 16進数→10進数
Q3: 16進数→文字
Q4: URLエンコードのデコード
Q5: base64デコード
Q6: base64エンコード
Q7: rot13デコード
Q8: rot13エンコード
Q9: 2進数→10進数
Q10: 10進数→2進数
Q11: ベストCTF(結果的には"DUCTF"で通った)
import socket
import base64
import codecs
from urllib.parse import unquote
from Crypto.Util.number import *
def recvuntil(s, tail):
data = b''
while True:
if tail in data:
return data.decode()
data += s.recv(1)
FAKE_COORDS = 5754622710042474278449745314387128858128432138153608237186776198754180710586599008803960884
p = 13318541149847924181059947781626944578116183244453569385428199356433634355570023190293317369383937332224209312035684840187128538690152423242800697049469987
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('pwn-2021.duc.tf', 31905))
data = recvuntil(s, b'...')
print(data)
s.sendall(b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'?\n').rstrip()
print(data)
q = data.split(' ')[-1].split('=')[0]
ans = eval(q)
print(ans)
s.sendall(str(ans).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = int(q, 16)
print(ans)
s.sendall(str(ans).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = chr(int(q, 16))
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = unquote(q)
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = base64.b64decode(q).decode()
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = base64.b64encode(q.encode()).decode()
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = codecs.decode(q, 'rot-13')
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = codecs.encode(q, 'rot-13')
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = int(q, 2)
print(ans)
s.sendall(str(ans).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
q = data.split(' ')[-1]
ans = bin(int(q))
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
ans = 'DUCTF'
print(ans)
s.sendall(ans.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
for _ in range(32):
data = recvuntil(s, b'\n').rstrip()
print(data)
実行結果は以下の通り。
Welcome to the DUCTF Classroom! Cyber School is now in session!
Press enter when you are ready to start your 30 seconds timer for the quiz...
Woops the time is always ticking...
Answer this maths question: 1+1=?
2
Well I see you are not a bludger then.
Decode this hex string and provide me the original number (base 10): 0xf6
246
You're better than a dog's breakfast at least.
Decode this hex string and provide me the original ASCII letter: 62
b
Come on this isn't hard yakka
Decode this URL encoded string and provide me the original ASCII symbols: %2A%5D%25
*]%
You haven't gone walkabout yet. Keep going!
Decode this base64 string and provide me the plaintext: dGltZWxpbmVfcHJlcGFyaW5nX2Jyb2FkY2FzdF9sb3Jk
timeline_preparing_broadcast_lord
That's a fair crack of the whip.
Encode this plaintext string and provide me the Base64: ferry_void_variety_bruce
ZmVycnlfdm9pZF92YXJpZXR5X2JydWNl
Fair dinkum! That's not bad.
Decode this rot13 string and provide me the plaintext: ubheyl_nhgbzngvba_wnpxrg_fvzvyneyl
hourly_automation_jacket_similarly
Don't spit the dummy yet!
Encode this plaintext string and provide me the ROT13 equilavent: natural_engine_wed_receiving
angheny_ratvar_jrq_erprvivat
You're sussing this out pretty quickly.
Decode this binary string and provide me the original number (base 10): 0b111111001000
4040
Crikey, can you speak computer?
Encode this number and provide me the binary equivalent: 8907
0b10001011001011
You're better than a bunnings sausage sizzle.
Final Question, what is the best CTF competition in the universe?
DUCTF
Bloody Ripper! Here is the grand prize!
.^.
(( ))
|#|_______________________________
|#||##############################|
|#||##############################|
|#||##############################|
|#||##############################|
|#||########DOWNUNDERCTF##########|
|#||########(DUCTF 2021)##########|
|#||##############################|
|#||##############################|
|#||##############################|
|#||##############################|
|#|'------------------------------'
|#|
|#|
|#|
|#|
|#|
|#|
|#|
|#|
|#|
|#|
|#|
|#| DUCTF{you_aced_the_quiz!_have_a_gold_star_champion}
|#|
|#|
|#|
//|\\
DUCTF{you_aced_the_quiz!_have_a_gold_star_champion}
rabbit (misc)
さまざまな圧縮方式で何重にも圧縮されているので、fileコマンドで確認しながら、解凍していく。
import subprocess
import os
import time
cmd_file = 'file %s'
cmd_tar = 'tar xvf %s'
cmd_zip = 'unzip %s'
cmd_bz2 = 'bzip2 -d %s'
cmd_gz = 'gzip -d %s'
cmd_xz = 'xz -d %s'
filename_base = 'flag'
filename_txt = 'flag.txt'
filename_tar = 'flag.tar'
filename_zip = 'flag.zip'
filename_bz2 = 'flag.bz2'
filename_gz = 'flag.gz'
filename_xz = 'flag.xz'
i = 1
while True:
print '%d times' % i
cmd = cmd_file % filename_txt
ret = subprocess.check_output( cmd.split(" ") )
print ret
if 'Zip archive' in ret:
os.rename(filename_txt, filename_zip)
os.system(cmd_zip % filename_zip)
os.remove(filename_zip)
elif 'bzip2 compressed' in ret:
os.rename(filename_txt, filename_bz2)
os.system(cmd_bz2 % filename_bz2)
os.rename(filename_base, filename_txt)
elif 'gzip compressed' in ret:
os.rename(filename_txt, filename_gz)
os.system(cmd_gz % filename_gz)
os.rename(filename_base, filename_txt)
elif 'XZ compressed' in ret:
os.rename(filename_txt, filename_xz)
os.system(cmd_xz % filename_xz)
time.sleep(2)
os.rename(filename_base, filename_txt)
else:
break
i += 1
実行結果は以下の通り。
:
990 times
flag.txt: Zip archive data, at least v2.0 to extract
Archive: flag.zip
inflating: flag.txt
991 times
flag.txt: Zip archive data, at least v1.0 to extract
Archive: flag.zip
extracting: flag.txt
992 times
flag.txt: bzip2 compressed data, block size = 900k
993 times
flag.txt: bzip2 compressed data, block size = 900k
994 times
flag.txt: Zip archive data, at least v2.0 to extract
Archive: flag.zip
inflating: flag.txt
995 times
flag.txt: Zip archive data, at least v1.0 to extract
Archive: flag.zip
extracting: flag.txt
996 times
flag.txt: bzip2 compressed data, block size = 900k
997 times
flag.txt: gzip compressed data, was "flag.txt", last modified: Thu Sep 9 11:25:28 2021, from Unix
998 times
flag.txt: XZ compressed data
xz: flag: ファイルのパーミッションを設定できません: 定義されたデータ型に対して値が大きすぎます
999 times
flag.txt: gzip compressed data, was "flag.txt", last modified: Thu Sep 9 11:25:28 2021, from Unix
1000 times
flag.txt: bzip2 compressed data, block size = 900k
1001 times
flag.txt: ASCII text
1000回解凍した後に展開されるflag.txtにはbase64文字列が書いてある。
RFVDVEZ7YmFidXNoa2FzX3YwZGthX3dhc19oM3IzfQ==
$ echo RFVDVEZ7YmFidXNoa2FzX3YwZGthX3dhc19oM3IzfQ== | base64 -d
DUCTF{babushkas_v0dka_was_h3r3}
DUCTF{babushkas_v0dka_was_h3r3}
no strings (reversing)
$ strings --encoding=l nostrings
DUCTF{stringent_strings_string}
DUCTF{stringent_strings_string}
Retro! (forensics)
$ exiftool og.jpg | grep DUCTF
Artist : DUCTF{sicc_paint_skillz!}
XP Author : DUCTF{sicc_paint_skillz!}
Creator : DUCTF{sicc_paint_skillz!}
DUCTF{sicc_paint_skillz!}
Do the loop! (forensics)
Audacityで開き、スぺクトログラムを見ると、モールス信号が見える。はっきりとは見えないので、英文になるよう調整しながら、デコードする。
ICOULDLISTENTOTHISONLOOPALLDAY
How to pronounce GIF (forensics)
アニメーションGIFをフレームごとに分割する。10個のQRコードになりそうなので、結合する。
from PIL import Image
WIDTH = 300
HEIGHT = 22
ROWS = 12
for i in range(1, 11):
output_img = Image.new('RGB', (WIDTH, HEIGHT * ROWS), (255, 255, 255))
for j in range(ROWS):
fname = 'div/challenge_%03d.gif' % (i + j * 10)
input_img = Image.open(fname).convert('RGB')
output_img.paste(input_img, (0, HEIGHT * j))
qr_fname = 'qr%02d.gif' % i
output_img.save(qr_fname)
QRコードをデコードする。
1:
The princess is in another castle
2:
https://bit.ly/3Afouex -> https://www.youtube.com/watch?v=gfkts0u-m6w
3:
f0ll0w 7h3 wh173 r4bb17
4:
https://bitly.com/98K8eH -> https://www.youtube.com/watch?v=dQw4w9WgXcQ
5:
(\(\
( -.-)
o_(")(")
6:
RFVDVEZ7YU1
7:
https://bit.ly/2YOdoPM -> https://www.youtube.com/watch?v=jQE66WA2s-A
8:
fMV9oYVhYMHJfbjB3P30=
9:
( )( )
(O.O)
o_(")(")
10:
https://www.youtube.com/watch?v=N1AL2EMvVy0
6番目と8番目の文字列を結合して、base64デコードする。
>>> ('RFVDVEZ7YU1' + 'fMV9oYVhYMHJfbjB3P30=').decode('base64')
'DUCTF{aM_1_haXX0r_n0w?}'
DUCTF{aM_1_haXX0r_n0w?}
Want to Play a Game? (forensics)
$ volatility -f JacobsPC.raw imageinfo
Volatility Foundation Volatility Framework 2.6.1
INFO : volatility.debug : Determining profile based on KDBG search...
Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418
AS Layer1 : WindowsAMD64PagedMemory (Kernel AS)
AS Layer2 : FileAddressSpace (/mnt/hgfs/Shared/work/JacobsPC.raw)
PAE type : No PAE
DTB : 0x187000L
KDBG : 0xf80002848120L
Number of Processors : 1
Image Type (Service Pack) : 1
KPCR for CPU 0 : 0xfffff8000284a000L
KUSER_SHARED_DATA : 0xfffff78000000000L
Image date and time : 2021-09-13 12:11:28 UTC+0000
Image local date and time : 2021-09-13 22:11:28 +1000
$ volatility -f JacobsPC.raw --profile=Win7SP1x64 pstree
Volatility Foundation Volatility Framework 2.6.1
Name Pid PPid Thds Hnds Time
-------------------------------------------------- ------ ------ ------ ------ ----
0xfffffa80018c1b00:wininit.exe 408 340 3 76 2021-09-12 17:45:40 UTC+0000
. 0xfffffa800475d150:lsm.exe 516 408 10 160 2021-09-12 17:45:40 UTC+0000
. 0xfffffa8002ae5b00:services.exe 488 408 7 226 2021-09-12 17:45:40 UTC+0000
.. 0xfffffa80047deb00:svchost.exe 640 488 10 373 2021-09-12 17:45:40 UTC+0000
... 0xfffffa80051feb00:WmiPrvSE.exe 2880 640 5 120 2021-09-12 17:46:25 UTC+0000
.. 0xfffffa80049d3b00:svchost.exe 1216 488 16 316 2021-09-12 17:45:43 UTC+0000
.. 0xfffffa80022cf060:taskhost.exe 4216 488 7 156 2021-09-13 12:09:50 UTC+0000
.. 0xfffffa80050b5340:mscorsvw.exe 780 488 6 81 2021-09-12 17:47:45 UTC+0000
.. 0xfffffa80048bdb00:svchost.exe 900 488 30 639 2021-09-12 17:45:41 UTC+0000
... 0xfffffa8004de6060:dwm.exe 1028 900 3 114 2021-09-12 17:45:51 UTC+0000
.. 0xfffffa8004a8e550:spoolsv.exe 1180 488 14 276 2021-09-12 17:45:43 UTC+0000
.. 0xfffffa80048f05f0:svchost.exe 932 488 12 387 2021-09-12 17:45:41 UTC+0000
.. 0xfffffa8004b72310:svchost.exe 1320 488 10 148 2021-09-12 17:45:43 UTC+0000
.. 0xfffffa80043a3060:msiexec.exe 4988 488 7 545 2021-09-12 17:51:42 UTC+0000
... 0xfffffa8001f98b00:msiexec.exe 4488 4988 0 ------ 2021-09-12 17:58:37 UTC+0000
... 0xfffffa8001ee5b00:msiexec.exe 3688 4988 0 ------ 2021-09-12 17:55:54 UTC+0000
... 0xfffffa8001d98b00:msiexec.exe 5376 4988 0 ------ 2021-09-12 17:58:46 UTC+0000
... 0xfffffa80044329e0:msiexec.exe 3680 4988 0 ------ 2021-09-12 17:52:32 UTC+0000
... 0xfffffa8001da9b00:msiexec.exe 3600 4988 0 ------ 2021-09-12 17:55:59 UTC+0000
... 0xfffffa800450eb00:msiexec.exe 4688 4988 0 ------ 2021-09-12 17:57:31 UTC+0000
.. 0xfffffa800489b060:svchost.exe 816 488 21 594 2021-09-12 17:45:41 UTC+0000
... 0xfffffa80049e1370:audiodg.exe 364 816 5 126 2021-09-12 17:45:42 UTC+0000
.. 0xfffffa80019b5570:mscorsvw.exe 3252 488 6 75 2021-09-12 17:47:45 UTC+0000
.. 0xfffffa8004389060:taskhost.exe 1336 488 5 95 2021-09-12 17:52:33 UTC+0000
.. 0xfffffa8004c14600:SearchIndexer. 1140 488 14 760 2021-09-12 17:45:58 UTC+0000
... 0xfffffa8004f1b400:SearchProtocol 2744 1140 8 284 2021-09-13 12:10:41 UTC+0000
... 0xfffffa800233c060:SearchFilterHo 5272 1140 5 93 2021-09-13 12:10:42 UTC+0000
.. 0xfffffa8002aeab00:VBoxService.ex 700 488 13 125 2021-09-12 17:45:40 UTC+0000
.. 0xfffffa8004efab00:wmpnetwk.exe 2052 488 23 539 2021-09-12 17:45:58 UTC+0000
.. 0xfffffa8004900710:svchost.exe 960 488 36 1197 2021-09-12 17:45:41 UTC+0000
... 0xfffffa8001b30060:taskeng.exe 2824 960 4 82 2021-09-12 17:51:58 UTC+0000
.. 0xfffffa8004d7eb00:taskhost.exe 1996 488 9 264 2021-09-12 17:45:51 UTC+0000
.. 0xfffffa80051b0b00:jenkins.exe 4644 488 8 185 2021-09-12 17:58:59 UTC+0000
... 0xfffffa80046294a0:java.exe 5528 4644 36 552 2021-09-12 17:59:00 UTC+0000
.. 0xfffffa8004632b00:sppsvc.exe 3280 488 4 143 2021-09-12 17:47:45 UTC+0000
.. 0xfffffa8001b11320:svchost.exe 3320 488 12 373 2021-09-12 17:47:46 UTC+0000
.. 0xfffffa8004b8c370:svchost.exe 1368 488 18 280 2021-09-12 17:45:43 UTC+0000
.. 0xfffffa8004a2a400:svchost.exe 1060 488 18 523 2021-09-12 17:45:43 UTC+0000
.. 0xfffffa80047b7b00:svchost.exe 756 488 8 328 2021-09-12 17:45:41 UTC+0000
.. 0xfffffa8004f92060:svchost.exe 2296 488 7 303 2021-09-12 17:45:59 UTC+0000
. 0xfffffa800475eb00:lsass.exe 508 408 7 797 2021-09-12 17:45:40 UTC+0000
0xfffffa80029163e0:csrss.exe 356 340 9 516 2021-09-12 17:45:39 UTC+0000
. 0xfffffa80023a4820:conhost.exe 5952 356 2 33 2021-09-12 17:59:00 UTC+0000
0xfffffa8001d1d060:firefox.exe 2080 3584 64 950 2021-09-13 11:37:20 UTC+0000
. 0xfffffa80050c2670:firefox.exe 5524 2080 18 294 2021-09-13 11:37:21 UTC+0000
. 0xfffffa8004512640:firefox.exe 5512 2080 8 189 2021-09-13 11:37:22 UTC+0000
. 0xfffffa8001f8a240:firefox.exe 3344 2080 14 267 2021-09-13 11:37:33 UTC+0000
. 0xfffffa8001f8a7a0:firefox.exe 2036 2080 19 327 2021-09-13 11:37:21 UTC+0000
. 0xfffffa8001d9a600:firefox.exe 3536 2080 18 293 2021-09-13 11:37:22 UTC+0000
. 0xfffffa800462d9d0:firefox.exe 2156 2080 27 294 2021-09-13 11:37:21 UTC+0000
0xfffffa8002b45b00:chrome.exe 3660 3132 34 1008 2021-09-12 17:48:44 UTC+0000
. 0xfffffa8005208110:chrome.exe 2952 3660 14 250 2021-09-12 17:48:45 UTC+0000
. 0xfffffa8001e33b00:chrome.exe 2736 3660 12 191 2021-09-12 17:48:46 UTC+0000
. 0xfffffa80050d3500:chrome.exe 2512 3660 7 149 2021-09-12 17:48:45 UTC+0000
. 0xfffffa8001a63640:chrome.exe 6060 3660 9 170 2021-09-12 17:52:58 UTC+0000
. 0xfffffa8002092b00:chrome.exe 5016 3660 14 252 2021-09-12 17:51:47 UTC+0000
. 0xfffffa800437d5a0:chrome.exe 6120 3660 14 218 2021-09-13 11:36:18 UTC+0000
. 0xfffffa8004604480:chrome.exe 4724 3660 14 325 2021-09-13 11:36:27 UTC+0000
0xfffffa8004df95b0:explorer.exe 1148 2024 36 1006 2021-09-12 17:45:51 UTC+0000
. 0xfffffa8004561690:soffice.exe 3748 1148 1 67 2021-09-12 17:57:02 UTC+0000
.. 0xfffffa80045d0920:soffice.bin 5228 3748 11 443 2021-09-12 17:57:02 UTC+0000
. 0xfffffa8004e35b00:VBoxTray.exe 1620 1148 15 149 2021-09-12 17:45:52 UTC+0000
. 0xfffffa8004f98b00:iexplore.exe 2516 1148 11 586 2021-09-12 17:46:12 UTC+0000
.. 0xfffffa80029f65f0:iexplore.exe 2280 2516 30 723 2021-09-12 17:46:47 UTC+0000
... 0xfffffa8001ad0b00:ie_to_edge_stu 3444 2280 0 ------ 2021-09-12 17:47:55 UTC+0000
0xfffffa8001e9eb00:drpbx.exe 3628 1152 4 128 2021-09-13 12:10:19 UTC+0000
0xfffffa80018b1040:System 4 0 90 576 2021-09-12 17:45:36 UTC+0000
. 0xfffffa8002a14040:smss.exe 272 4 2 29 2021-09-12 17:45:36 UTC+0000
0xfffffa800466f060:winlogon.exe 472 400 3 113 2021-09-12 17:45:40 UTC+0000
0xfffffa8004244b00:csrss.exe 416 400 12 780 2021-09-12 17:45:40 UTC+0000
0xfffffa80043b3220:Discord.exe 1828 3552 34 691 2021-09-12 17:52:32 UTC+0000
. 0xfffffa80020593b0:Discord.exe 5396 1828 30 580 2021-09-12 17:52:38 UTC+0000
. 0xfffffa80043127d0:Discord.exe 4408 1828 13 315 2021-09-12 17:52:33 UTC+0000
. 0xfffffa8001dd2060:Discord.exe 4908 1828 8 120 2021-09-12 17:52:33 UTC+0000
. 0xfffffa8002093060:Discord.exe 5572 1828 10 168 2021-09-12 17:52:41 UTC+0000
. 0xfffffa8004ada6a0:Discord.exe 5288 1828 8 210 2021-09-12 17:52:34 UTC+0000
$ volatility -f JacobsPC.raw --profile=Win7SP1x64 cmdline
Volatility Foundation Volatility Framework 2.6.1
************************************************************************
System pid: 4
************************************************************************
smss.exe pid: 272
************************************************************************
csrss.exe pid: 356
Command line : %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
************************************************************************
wininit.exe pid: 408
************************************************************************
csrss.exe pid: 416
Command line : %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16
************************************************************************
winlogon.exe pid: 472
Command line : winlogon.exe
************************************************************************
services.exe pid: 488
Command line : C:\Windows\system32\services.exe
************************************************************************
lsass.exe pid: 508
Command line : C:\Windows\system32\lsass.exe
************************************************************************
lsm.exe pid: 516
Command line :
************************************************************************
svchost.exe pid: 640
Command line : C:\Windows\system32\svchost.exe -k DcomLaunch
************************************************************************
VBoxService.ex pid: 700
Command line : C:\Windows\System32\VBoxService.exe
************************************************************************
svchost.exe pid: 756
Command line : C:\Windows\system32\svchost.exe -k RPCSS
************************************************************************
svchost.exe pid: 816
Command line : C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted
************************************************************************
svchost.exe pid: 900
Command line : C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
************************************************************************
svchost.exe pid: 932
Command line : C:\Windows\system32\svchost.exe -k LocalService
************************************************************************
svchost.exe pid: 960
Command line : C:\Windows\system32\svchost.exe -k netsvcs
************************************************************************
audiodg.exe pid: 364
Command line : C:\Windows\system32\AUDIODG.EXE 0x248
************************************************************************
svchost.exe pid: 1060
Command line : C:\Windows\system32\svchost.exe -k NetworkService
************************************************************************
spoolsv.exe pid: 1180
Command line :
************************************************************************
svchost.exe pid: 1216
Command line : C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
************************************************************************
svchost.exe pid: 1320
Command line : C:\Windows\System32\svchost.exe -k utcsvc
************************************************************************
svchost.exe pid: 1368
Command line : C:\Windows\system32\svchost.exe -k LocalServiceAndNoImpersonation
************************************************************************
taskhost.exe pid: 1996
Command line : "taskhost.exe"
************************************************************************
dwm.exe pid: 1028
Command line :
************************************************************************
explorer.exe pid: 1148
Command line : C:\Windows\Explorer.EXE
************************************************************************
VBoxTray.exe pid: 1620
Command line : "C:\Windows\System32\VBoxTray.exe"
************************************************************************
SearchIndexer. pid: 1140
Command line : C:\Windows\system32\SearchIndexer.exe /Embedding
************************************************************************
wmpnetwk.exe pid: 2052
Command line : "C:\Program Files\Windows Media Player\wmpnetwk.exe"
************************************************************************
svchost.exe pid: 2296
Command line : C:\Windows\System32\svchost.exe -k LocalServicePeerNet
************************************************************************
iexplore.exe pid: 2516
Command line : "C:\Program Files\Internet Explorer\iexplore.exe"
************************************************************************
WmiPrvSE.exe pid: 2880
Command line : C:\Windows\system32\wbem\wmiprvse.exe
************************************************************************
iexplore.exe pid: 2280
Command line : "C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE" SCODEF:2516 CREDAT:1774879 /prefetch:2
************************************************************************
mscorsvw.exe pid: 780
Command line :
************************************************************************
mscorsvw.exe pid: 3252
Command line :
************************************************************************
sppsvc.exe pid: 3280
Command line :
************************************************************************
svchost.exe pid: 3320
Command line : C:\Windows\System32\svchost.exe -k secsvcs
************************************************************************
ie_to_edge_stu pid: 3444
************************************************************************
chrome.exe pid: 3660
Command line : "C:\Program Files\Google\Chrome\Application\chrome.exe" --from-installer
************************************************************************
chrome.exe pid: 2952
Command line : "C:\Program Files\Google\Chrome\Application\chrome.exe" --type=utility --utility-sub-type=network.mojom.NetworkService --field-trial-handle=1152,10551326307754508950,3778691879411989411,131072 --lang=en-GB --service-sandbox-type=none --mojo-platform-channel-handle=1372 /prefetch:8
************************************************************************
chrome.exe pid: 2512
Command line :
************************************************************************
chrome.exe pid: 2736
Command line :
************************************************************************
msiexec.exe pid: 4988
Command line : C:\Windows\system32\msiexec.exe /V
************************************************************************
chrome.exe pid: 5016
Command line :
************************************************************************
taskeng.exe pid: 2824
Command line :
************************************************************************
msiexec.exe pid: 3680
************************************************************************
Discord.exe pid: 1828
Command line : "C:\Users\Jacob\AppData\Local\Discord\app-1.0.9002\Discord.exe" --squirrel-firstrun
************************************************************************
taskhost.exe pid: 1336
Command line : "taskhost.exe"
************************************************************************
Discord.exe pid: 4908
Command line :
************************************************************************
Discord.exe pid: 4408
Command line :
************************************************************************
Discord.exe pid: 5288
************************************************************************
Discord.exe pid: 5396
Command line :
************************************************************************
Discord.exe pid: 5572
Command line :
************************************************************************
chrome.exe pid: 6060
Command line :
************************************************************************
msiexec.exe pid: 3688
************************************************************************
msiexec.exe pid: 3600
************************************************************************
soffice.exe pid: 3748
************************************************************************
soffice.bin pid: 5228
Command line : "C:\Program Files (x86)\OpenOffice 4\program\soffice.exe" "-env:OOO_CWD=2C:\\Program Files (x86)\\OpenOffice 4"
************************************************************************
msiexec.exe pid: 4688
************************************************************************
msiexec.exe pid: 4488
************************************************************************
msiexec.exe pid: 5376
************************************************************************
jenkins.exe pid: 4644
Command line : "C:\Program Files\Jenkins\jenkins.exe"
************************************************************************
java.exe pid: 5528
Command line : "C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "C:\Program Files\Jenkins\jenkins.war" --httpPort=8080 --webroot="C:\Windows\system32\config\systemprofile\AppData\Local\Jenkins\war"
************************************************************************
conhost.exe pid: 5952
Command line : \??\C:\Windows\system32\conhost.exe "-154075351530581523016333457511636195217536156841732032102577596487-1138745220
************************************************************************
chrome.exe pid: 6120
Command line : "C:\Program Files\Google\Chrome\Application\chrome.exe" --type=renderer --field-trial-handle=1152,10551326307754508950,3778691879411989411,131072 --disable-gpu-compositing --lang=en-GB --device-scale-factor=1 --num-raster-threads=1 --renderer-client-id=140 --no-v8-untrusted-code-mitigations --mojo-platform-channel-handle=1972 /prefetch:1
************************************************************************
chrome.exe pid: 4724
Command line : "C:\Program Files\Google\Chrome\Application\chrome.exe" --type=renderer --field-trial-handle=1152,10551326307754508950,3778691879411989411,131072 --disable-gpu-compositing --lang=en-GB --device-scale-factor=1 --num-raster-threads=1 --renderer-client-id=143 --no-v8-untrusted-code-mitigations --mojo-platform-channel-handle=4760 /prefetch:1
************************************************************************
firefox.exe pid: 2080
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -first-startup
************************************************************************
firefox.exe pid: 2156
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.0.1806420328\2068587236" -parentBuildID 20210903235534 -prefsHandle 1156 -prefMapHandle 1340 -prefsLen 1 -prefMapSize 235474 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 1244 f0deb48 gpu
************************************************************************
firefox.exe pid: 2036
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.1.963837300\509935240" -childID 1 -isForBrowser -prefsHandle 1364 -prefMapHandle 1604 -prefsLen 1321 -prefMapSize 235474 -jsInit 720 285716 -parentBuildID 20210903235534 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 1032 10841e28 tab
************************************************************************
firefox.exe pid: 5524
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.2.1712272282\1704974947" -childID 2 -isForBrowser -prefsHandle 1792 -prefMapHandle 1788 -prefsLen 1426 -prefMapSize 235474 -jsInit 720 285716 -parentBuildID 20210903235534 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 1804 12a40108 tab
************************************************************************
firefox.exe pid: 5512
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.5.457040815\1949162558" -parentBuildID 20210903235534 -prefsHandle 2124 -prefMapHandle 1976 -prefsLen 1541 -prefMapSize 235474 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 2136 f0dcf28 rdd
************************************************************************
firefox.exe pid: 3536
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.8.1437269067\508647407" -childID 3 -isForBrowser -prefsHandle 2632 -prefMapHandle 2628 -prefsLen 1972 -prefMapSize 235474 -jsInit 720 285716 -parentBuildID 20210903235534 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 2648 10841b88 tab
************************************************************************
firefox.exe pid: 3344
Command line : "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -contentproc --channel="2080.12.1266410291\768878374" -childID 5 -isForBrowser -prefsHandle 4112 -prefMapHandle 4108 -prefsLen 11064 -prefMapSize 235474 -jsInit 720 285716 -parentBuildID 20210903235534 -appdir "C:\Program Files (x86)\Mozilla Firefox\browser" - 2080 "\\.\pipe\gecko-crash-server-pipe.2080" 4124 165b03a8 tab
************************************************************************
taskhost.exe pid: 4216
Command line : taskhost.exe $(Arg0)
************************************************************************
drpbx.exe pid: 3628
Command line : "C:\Users\Jacob\AppData\Local\Drpbx\drpbx.exe" C:\Users\Public\Videos\Sample?Videos\PJxhJQ9yUDoBF1188y\notsuspicious.exe★
************************************************************************
SearchProtocol pid: 2744
Command line : "C:\Windows\system32\SearchProtocolHost.exe" Global\UsGthrFltPipeMssGthrPipe7_ Global\UsGthrCtrlFltPipeMssGthrPipe7 1 -2147483646 "Software\Microsoft\Windows Search" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT; MS Search 4.0 Robot)" "C:\ProgramData\Microsoft\Search\Data\Temp\usgthrsvc" "DownLevelDaemon"
************************************************************************
SearchFilterHo pid: 5272
Command line : "C:\Windows\system32\SearchFilterHost.exe" 0 508 512 520 65536 516
notsuspicious.exeがあやしい。
$ volatility -f JacobsPC.raw --profile=Win7SP1x64 filescan | grep notsuspicious.exe
Volatility Foundation Volatility Framework 2.6.1
0x000000007f7cb980 8 0 R--r-d \Device\HarddiskVolume2\Users\Public\Videos\Sample Videos\PJxhJQ9yUDoBF1188y\notsuspicious.exe
$ volatility -f JacobsPC.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000007f7cb980 -D .
Volatility Foundation Volatility Framework 2.6.1
ImageSectionObject 0x7f7cb980 None \Device\HarddiskVolume2\Users\Public\Videos\Sample Videos\PJxhJQ9yUDoBF1188y\notsuspicious.exe
DataSectionObject 0x7f7cb980 None \Device\HarddiskVolume2\Users\Public\Videos\Sample Videos\PJxhJQ9yUDoBF1188y\notsuspicious.exe
$ md5sum file.None.0xfffffa80021d9b60.dat
c3894f0d12bacac4154e94bba0b9a798 file.None.0xfffffa80021d9b60.dat
このハッシュ値をVirusTotalで調べる。
マルウェアはJigsaw。フォルダはPJxhJQ9yUDoBF1188y。永続化メカニズムはRegistry Run Keys。
DUCTF{jigsaw_Registry Run Keys_PJxhJQ9yUDoBF1188y}
このフラグでは通らなかった。永続化メカニズムについて、他にもいろいろ試したが、通らない。
$ volatility -f JacobsPC.raw --profile=Win7SP1x64 printkey -K "Software\Microsoft\Windows\CurrentVersion\Run"
Volatility Foundation Volatility Framework 2.6.1
Legend: (S) = Stable (V) = Volatile
----------------------------
Registry: \SystemRoot\System32\Config\DEFAULT
Key name: Run (S)
Last updated: 2021-09-13 10:41:47 UTC+0000
Subkeys:
Values:
----------------------------
Registry: \??\C:\Users\Jacob\ntuser.dat
Key name: Run (S)
Last updated: 2021-09-13 12:10:15 UTC+0000
Subkeys:
Values:
REG_SZ Discord : (S) C:\Users\Jacob\AppData\Local\Discord\Update.exe --processStart Discord.exe
REG_SZ firefox.exe : (S) C:\Users\Jacob\AppData\Roaming\Frfx\firefox.exe
結果的には、永続化メカニズムというよりは、永続化するための実行ファイル名にする必要があった。
DUCTF{jigsaw_firefox.exe_PJxhJQ9yUDoBF1188y}
Substitution Cipher I (crypto)
この暗号化ではフラグの各文字のASCIIコードを以下の計算してunicode文字にしている。
f = 13*x^2 + 3*x + 7
各文字でブルートフォースして復号する。
import codecs
with codecs.open('output.txt', 'rb', 'utf-8') as f:
enc = f.read()
flag = ''
for c in enc:
for x in range(32, 127):
v = 13 * x**2 + 3 * x + 7
if v == ord(c):
flag += chr(x)
break
print(flag)
DUCTF{sh0uld'v3_us3d_r0t_13}
Substitution Cipher II (crypto)
フラグがDUCTF{***}という形式から、f関数を導き出し、復号する。各文字の暗号化では以下の式が成り立つ。
a1 * x**6 + a2 * x**5 + a3 * x**4 + a4 * x**3 + a5 * x**2 + a6 * x + a7 = c
方程式にすると、以下の行列の式が成り立つ。
A * x = C
x = inverse(A) * C
7個の文字について条件を付けられるので、a1~a7を割り出すことができる。
from string import ascii_lowercase, digits
def f(X, c, n):
v = 0
for i in range(7):
v += X[i][0] * pow(c, 6 - i, n)
return v % n
CHARSET = "DUCTF{}_!?'" + ascii_lowercase + digits
n = len(CHARSET)
enc = 'Ujyw5dnFofaou0au3nx3Cn84'
known_flag = 'DUCTF{}'
pt = []
for i in range(len(known_flag)):
pt.append(CHARSET.index(known_flag[i]))
ct = []
for i in range(len(known_flag) - 1):
ct.append(CHARSET.index(enc[i]))
ct.append(CHARSET.index(enc[-1]))
A = []
for p in pt:
row = []
for i in range(6, -1, -1):
row.append(pow(p, i, n))
A.append(row)
B = []
for c in ct:
B.append([c])
A = matrix(Zmod(n), A)
B = matrix(Zmod(n), B)
X = A.inverse() * B
for i in range(len(enc)):
for j in range(n):
v = f(X, j, n)
if v == CHARSET.index(enc[i]):
print i, CHARSET[j]
実行結果は以下の通り。
0 D
1 U
1 !
2 C
3 T
3 t
4 F
5 {
6 g
7 o
8 0
9 d
10 _
11 0
12 l
13 '
14 _
15 l
16 4
17 g
18 r
19 4
20 f
20 n
20 p
21 g
22 3
22 8
23 }
複数の復号結果が出るので、単語として成り立ちそうなものを選ぶ。
DUCTF{go0d_0l'_l4gr4ng3}
treasure (crypto)
サーバの処理概要は以下の通り。
・FAKE_COORDS = 5754622710042474278449745314387128858128432138153608237186776198754180710586599008803960884
・p = 13318541149847924181059947781626944578116183244453569385428199356433634355570023190293317369383937332224209312035684840187128538690152423242800697049469987
・shares = create_shares(REAL_COORDS)
・r1, r2: 1以上p-1以下ランダム整数
・s1 = r1*r2*REAL_COORDS % p
・s2 = r1*r1*r2*REAL_COORDS % p
・s3 = r1*r2*r2*REAL_COORDS % p
・[s1, s2, s3]を返す。
・shares[0]を表示
・secret_coords = run_combiner(shares)
・your_share: 数値入力
・reveal_secret([your_share, shares[1], shares[2]])を返却
・s1, s2, s3 = [your_share, shares[1], shares[2]]
・secret = pow(s1, 3, p) * pow(s2*s3, -1, p) % p
・secret_coordsを表示
・is_coords(secret_coords)がFalseかどうかチェック
・secret_coords が正規表現で以下を満たしていなければFalse
・'-?\d+\.\d+?, -?\d+\.\d+'
・secret_coords = run_combiner(shares)
・your_share: 数値入力
・reveal_secret([your_share, shares[1], shares[2]])を返却
・is_coords(secret_coords)がTrueかどうかチェック
・secret_coords が正規表現で以下を満たしていればTrue
・'-?\d+\.\d+?, -?\d+\.\d+'
・secret_coords がFAKE_COORDSと一致していることが必要
・real_coords: 数値入力
・REAL_COORDSと一致していたら、フラグを表示
最初の入力では1を指定するとpow(s2*s3, -1, p)が取得できる。
次の入力について考える。
reveal_secret([x, s2, s3]) == FAKE_COORDSである必要あり
pow(x, 3, p) * pow(s2*s3, -1, p) % p = FAKE_COORDS
→pow(x, 3, p) = (FAKE_COORDS * (s2 * s3)) % p
これでRSA暗号の復号の要領でxを求めることができる。
最後の入力では、REAL_COORDSを算出する必要がある。
REAL_COORDS = pow(s1, 3, p) * pow(s2*s3, -1, p) % p
pow(s1, 3, p)もpow(s2*s3, -1, p)もわかっているので、簡単に計算できる。
import socket
from Crypto.Util.number import *
def recvuntil(s, tail):
data = b''
while True:
if tail in data:
return data.decode()
data += s.recv(1)
FAKE_COORDS = 5754622710042474278449745314387128858128432138153608237186776198754180710586599008803960884
p = 13318541149847924181059947781626944578116183244453569385428199356433634355570023190293317369383937332224209312035684840187128538690152423242800697049469987
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('pwn-2021.duc.tf', 31901))
data = recvuntil(s, b'\n').rstrip()
print(data)
shares0 = int(data.split(' ')[-1])
your_share = 1
data = recvuntil(s, b': ')
print(data + str(your_share))
s.sendall(str(your_share).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
inv_s2s3 = int(data.split(' ')[-1])
c = FAKE_COORDS * inverse(inv_s2s3, p) % p
phi = p - 1
d = inverse(3, phi)
your_share = pow(c, d, p)
data = recvuntil(s, b': ')
print(data + str(your_share))
s.sendall(str(your_share).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
real_coords = pow(shares0, 3, p) * inv_s2s3 % p
data = recvuntil(s, b': ')
print(data + str(real_coords))
s.sendall(str(real_coords).encode() + b'\n')
for _ in range(10):
data = recvuntil(s, b'\n').rstrip()
print(data)
実行結果は以下の通り。
Your share is: 7804293849402738656143934896341083753302497888743094224497544817840005883520708954899094814585889708716443115003224471488288312933165458151030566716551263
Your two friends input their shares into the combiner and excitedly wait for you to do the same...
Enter your share: 1
The secret is revealed: 10778146055053391357265261942770602144861595970618645595558801335308604801636463229704860925111251602145029455459496243606168210175092865359176816238912500
"Hey those don't look like coordinates!"
Your friends grow a bit suspicious, but you manage to convince them that you just entered a digit wrong. You decide to try again...
Enter your share: 8710965049368583723357806344126910624939097477429135301479243146268371450183461800160858606290045446882089498090263858527131639024232533573995887518618067
You've successfully deceived your friends!
Now enter the real coords: 5756627544102572649201219381096443309301530404084814366157678459246004007288774904822314549
You travel to the exact coordinates that you found
and notice something shining in the corner of your
eye. It's a treasure chest! You open it and in a
completely unexpected turn of events, it's empty!
Etched at the bottom of the hollow chest, you make
out some writing. It reads:
DUCTF{m4yb3_th3_r34L_tr34sur3_w4s_th3_fr13nDs_w3_m4d3_al0ng_Th3_W4y.......}
DUCTF{m4yb3_th3_r34L_tr34sur3_w4s_th3_fr13nDs_w3_m4d3_al0ng_Th3_W4y.......}
Break Me! (crypto)
pad(flag + 入力文字列 + key)がAES-ECBで暗号化される。ただしpadは、16の倍数の長さの場合行われず、'0'がパディングされる。鍵を1文字ずつはみ出させ、ブルートフォースでブロック単位で暗号が一致するものを求めていく。
$ nc pwn-2021.duc.tf 31914
AES-128
Enter plaintext:
a
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YJN8jgrU3lwgaZYItQD8O+/ySPAtunw8lTSmucLjij7WA==
Enter plaintext:
aa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YIAGEIjKUMQ4Cxs5ILqeYKqW5R1Q3puWvM1y514p0HJPQ==
Enter plaintext:
aaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YK+FyUcVZgHiuctzk91CBtarasdO9jL90GuHmd670h1xw==
Enter plaintext:
aaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YJHD8oKkejNXPMCzmVVznNy9mFyRlVMomJ047jWairQcg==
Enter plaintext:
aaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YI0AjZAsMu3waxcwMWizZl70RnGBxkNfAuXcLka0D37xg==
Enter plaintext:
aaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YK9l6G/8NfdF4i4YI5Q5Qo3HamNuq787ok2g47VlrOqRQ==
Enter plaintext:
aaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YIn9motbI4Mf+IoFVPEgsdLKXkAfRCXygaTG3MfOEf8qA==
Enter plaintext:
aaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKI7epqyfcn88oO8MSDMAxuOryUpfzvcX/y5pjmHX4HhA==
Enter plaintext:
aaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YJOhlrdOWKyL6k3Ps89a2upQSgTyzzafEDgxqs1XVcjdw==
Enter plaintext:
aaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YIBeFJVe8wHSX9fUKzIQCTO6FDKhre+OwE2annUeyi3XA==
Enter plaintext:
aaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YLzS1Iuf4fhzRqk3Vm9akOV/qzvoUmXw/HmE/Y+F6ZBjA==
Enter plaintext:
aaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKMJ0ylGJtkoeilWQpnWm/LPOLlkZPLGxXCFF0yLHxiqg==
Enter plaintext:
aaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKlTo/QGx0MpanMUAd/j1VSSDewVaRDbl/Q0nqsdRnPAg==
Enter plaintext:
aaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YI1OhDtn0QNJYViu+LzUkQl77ukeyH+Uxabp3PiWJAvZA==
Enter plaintext:
aaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YJRUuFnwgTq5tTDe0LM6F+6p2zTX1Ao4jQHUauEyyuDrA==
Enter plaintext:
aaaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKYCiwa1u9m8RzI/xJpWN8hm8XWdhGwJb3Z/JWY2GlrlQ==
Enter plaintext:
aaaaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKYCiwa1u9m8RzI/xJpWN8hTfI4K1N5cIGmWCLUA/Dvv8kjwLbp8PJU0prnC44o+1g=
この結果からブロックの構成をすると以下のようになり、フラグは32バイト、鍵は16バイトであることがわかる。
0123456789abcdef
FFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFF
aaaaaaaaaaaaaaaa
aKKKKKKKKKKKKKKK
KPPPPPPPPPPPPPPP
鍵の1バイト目をはみ出させる場合は、以下のような構成。
0123456789abcdef
FFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFF
aaaaaaaaaaaaaaa?
aaaaaaaaaaaaaaaK
KKKKKKKKKKKKKKKP
import socket
from Crypto.Cipher import AES
from base64 import b64decode
def recvuntil(s, tail):
data = b''
while True:
if tail in data:
return data.decode()
data += s.recv(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('pwn-2021.duc.tf', 31914))
data = recvuntil(s, b'\n').rstrip()
print(data)
key = ''
for i in range(16):
for code in range(256):
if code == 10:
continue
data = recvuntil(s, b'\n').rstrip()
print(data)
msg = 'a' * (15 - i) + key + chr(code) + 'a' * (15 - i)
print(msg)
s.sendall(msg.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
enc = b64decode(data)
if enc[32:48] == enc[48:64]:
key += chr(code)
break
cipher = AES.new(key.encode(), AES.MODE_ECB)
flag = cipher.decrypt(enc[:32]).decode()
print(flag)
実行結果は以下の通り。
AES-128
Enter plaintext:
aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YIDOwmfNIffUAEzy4ft/neCUVLhZ8IE6ubUw3tCzOhfuqds019QKOI0B1GrhMsrg6w=
Enter plaintext:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YLAeBLB5TAXo2ck2INfV20/UVLhZ8IE6ubUw3tCzOhfuqds019QKOI0B1GrhMsrg6w=
Enter plaintext:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKmpoiIGcutSnvgQ73UbqESUVLhZ8IE6ubUw3tCzOhfuqds019QKOI0B1GrhMsrg6w=
:
Enter plaintext:
!_SECRETSOURCE_
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKbxdZ2EbAlvdn8lZjYaWuVp2zTX1Ao4jQHUauEyyuDrA==
Enter plaintext:
!_SECRETSOURCE_
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKbxdZ2EbAlvdn8lZjYaWuVp2zTX1Ao4jQHUauEyyuDrA==
Enter plaintext:
!_SECRETSOURCE_
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKbxdZ2EbAlvdn8lZjYaWuVp2zTX1Ao4jQHUauEyyuDrA==
Enter plaintext:
!_SECRETSOURCE_!
8MAq3pGs7/KTcv0c3ijqTJhv/z9V8QA7l9TkMkU72YKbxdZ2EbAlvdn8lZjYaWuVm8XWdhGwJb3Z/JWY2GlrlQ==
DUCTF{ECB_M0DE_K3YP4D_D474_L34k}
DUCTF{ECB_M0DE_K3YP4D_D474_L34k}
Secuchat (crypto)
各ユーザ(30名)がrsa_key(公開鍵)を持っている。Userテーブルから全ユーザのrsa_keyをエクスポートする。rsa_keyのModulusで同じ約数を持つものを探し、秘密鍵ファイルを作成してみる。
from Crypto.PublicKey import RSA
from Crypto.Util.number import *
users = ['angela45', 'hortonashley', 'sarahdavis', 'lmiller', 'denisemoore',
'rogerrichards', 'davidfoster', 'bushjessica', 'michelehansen', 'amoore',
'james72', 'elizabeth93', 'cwhite', 'ryan10', 'courtney14', 'garciamartha',
'aprilchambers', 'pmarquez', 'floresmaria', 'ybrown', 'pwilson',
'josephlindsey', 'matthew75', 'eriksaunders', 'aliciadrake',
'johnsontimothy', 'oneillpatricia', 'nscott', 'rcruz', 'storres']
ns = []
for u in users:
fname = 'key/%s.bin' % u
with open(fname, 'rb') as f:
pub_data = f.read()
pubkey = RSA.importKey(pub_data)
n = pubkey.n
e = pubkey.e
assert e == 65537
ns.append(n)
for i in range(len(ns)):
for j in range(i+1, len(ns)):
p = GCD(ns[i], ns[j])
if p != 1:
q1 = ns[i] // p
q2 = ns[j] // p
print 'user1 =', users[i]
print 'user2 =', users[j]
print 'p =', p
print 'q1 =', q1
print 'q2 =', q2
phi1 = (p - 1) * (q1 - 1)
phi2 = (p - 1) * (q2 - 1)
d1 = inverse(e, phi1)
d2 = inverse(e, phi2)
key1 = RSA.construct(map(long, (ns[i], e, d1)))
key2 = RSA.construct(map(long, (ns[j], e, d2)))
with open(users[i] + '_pri.key', 'w') as f:
f.write(key1.exportKey())
with open(users[j] + '_pri.key', 'w') as f:
f.write(key2.exportKey())
実行結果は以下の通り。
user1 = hortonashley
user2 = eriksaunders
p = 133466825987755430272845819131189878475949531124908548925625729014773654095611929382311940926413578955464687448166109016437333937351204126047469738072985838469878770181604920274710562425226226629637410423438143246879323430748145634335643727697763949446994599049954230220862004818645276994332655884528632470029
q1 = 150800758546585864276699976719226785712279609923705796183705575603672079795403309961784619004552042973374437992254498313339528652360723160548428435272795441449993138937121825516230321249669799044011210832693978123523904947810980190276881271928695574417287879362480460759690362693750109971383652883143766360359
q2 = 148704904308273523058484127055137378620932174272777551833069204786761758340570631741859456508662259607861904153885411924765940981745547976574197604593706187290791666135495071771144625678996286172037544681268601514948592778248296514095308664212132680408538439244614357066052877805077334535299786616961129671337
他のデータも見てみる。
Conversationテーブルではイニシエータと各メッセージとの紐づけがわかる。
Parametersテーブルでは各メッセージに対応するRSA2048-OAEPで暗号化されたAES-256-CBCの鍵とIVが格納されている。
MessageテーブルではAES-256-CBCで暗号化されたメッセージの暗号化データが格納されている。
そこで、秘密鍵ファイルが生成できたhortonashleyからのメッセージが最後にあることからこのメッセージを復号する。
以下のデータをエクスポートする。
・Parametersテーブルのidが328~332のデータの
encrypted_aes_key_for_initiator(AES暗号鍵のRSA暗号データ)、iv(AES暗号IV)
・Messageテーブルのidが329~333のデータのencrypted_message(暗号化メッセージ)
エクスポートしたデータを使って、以下のような流れで各メッセージを復号する。
・encrypted_aes_key_for_initiatorをRSA暗号の秘密鍵を使って、RSA2048-OAEP復号する。
・復号したAES鍵とivを使って、encrypted_messageを復号する。
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
with open('hortonashley_pri.key', 'r') as f:
pri_data = f.read()
pri_key = RSA.importKey(pri_data)
for i in range(328, 333):
fname = 'enc_aeskey_%d.bin' % i
with open(fname, 'rb') as f:
enc_aes_key = f.read()
cipher = PKCS1_OAEP.new(pri_key)
aes_key = cipher.decrypt(enc_aes_key)
fname = 'iv_%d.bin' % i
with open(fname, 'rb') as f:
iv = f.read()
fname = 'enc_msg_%d.bin' % (i+1)
with open(fname, 'rb') as f:
enc_msg = f.read()
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
msg = unpad(cipher.decrypt(enc_msg), 16)
print msg
実行結果は以下の通り。
hey Harum ipsum eos ex unde.
hey Asperiores repellat enim dolorum accusamus repudiandae cupiditate eius.
here's the flag btw Veniam aperiam quae.
DUCTF{pr1m1t1v35, p4dd1ng, m0d35- wait, 3n7r0py?!} Ratione distinctio totam.
cheers Ea alias enim laborum.
DUCTF{pr1m1t1v35, p4dd1ng, m0d35- wait, 3n7r0py?!}
Survey (survey)
アンケートに答えたら、フラグが表示された。
DUCTF{th4nk_y0u_f0r_pl4ying_DUCTF_2021_!!}