camp ctf 2016 writeup -Earth編-
はじめに
セキュリティキャンプ全国大会2016中に開催されたctfのwriteupです。
まだ全部解いてないので、Earth(Crypto)だけのwriteupです。
ポートスキャンの結果
Earthが待ち受けているのは、10725番ポートだった。このポートに対してnetcatして、解いていく感じ。
% nmap 192.168.179.3 -p1-65535 Starting Nmap 7.12 ( https://nmap.org ) at 2016-08-29 20:51 JST Nmap scan report for 192.168.179.3 Host is up (0.013s latency). Not shown: 65530 closed ports PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 443/tcp open https 10725/tcp open unknown 24154/tcp open unknown
1問目
見た感じrot13だと思ったので、pythonで確認。
% nc 192.168.179.3 10725 ---------------------------------------------------------------- Problem #1 SYNT{uryybpelcgbfreire} Challenge 1/3>
% python Python 2.7.10 (default, Oct 23 2015, 19:19:21) [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> "SYNT{uryybpelcgbfreire}".decode("rot13") u'FLAG{hellocryptoserver}'
2問目
1問目のflagを入力して2問目へ。
rot13の次だから、換字式なんだろうなーと思い、大文字小文字のアルファベットを入力してみる。
Problem #2 KMZH{xbqofodmzxxnddnotqu} Challenge 1/3> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQESTUVWXYZ zrdaqkhtnlpmijvowuxbfsegcyZRDAQKHTNLPMIJVOWQXBFSEGCY Wrong.. Challenge 2/3>
より換字式っぽさが出てきたので、適当に復号してみる。
# decrypto.py P = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQESTUVWXYZ{}" C = "zrdaqkhtnlpmijvowuxbfsegcyZRDAQKHTNLPMIJVOWQXBFSEGCY{}" flag = "KMZH{xbqofodmzxxnddnotqu}" print "".join(P[C.index(q)] for q in flag) # FLAG{stepupclassiccipher}
ちなみにだが、この変換テーブルは接続するたびに変わっている。
3問目
2問目のflagを入力して、3問目へ。
16進数のような文字列が出てきた。
Problem #3 1fb53a2b241ad4b1219609143010d8b120890f0322 Challenge 1/3> AAAAAAAAAAAAAAAAAAAAAA 18b83a2d1e23fa8218b83a2d1e23fa8218b83a2d1e23 Wrong..
そのままではASCIIコードとしては使えないので、xorしているんだろうな、と予測する。
1回の接続中にxorの鍵が変わることはないだろうと踏んで、AAA...を入力。出力結果からxorの鍵を求めて、それと出題をxorする。
q = "1fb53a2b241ad4b1219609143010d8b120890f0322".decode("hex") aaa = "18b83a2d1e23fa8218b83a2d1e23fa8218b83a2d1e".decode("hex") flag = "" for i in range(len(d)): flag += chr((ord(aaa[i]) ^ ord("A") ) ^ ord(q[i])) print flag # FLAG{xorxorxorcrypto}
writeupを書いてる途中で気づいたが、鍵は8文字ぐらいで繰り返しになっている。
4問目
Problem #4 - RSA
やるだけ
---------------------------------------------------------------- Problem #4 - RSA p = 89763157488328820493828889999529349687515193829186446452191659847993832608188788728417088150112600782050523041398$ 3432801309883064874870881446698538363907 q = 113841038790428002844600998710560664858598146193863557129392399065993065441040086685388432151725491152653570885016 24031156542729241733486420090143766579357 e = 65537 C = 0x23464c5c42a522eed7e2f15d7ada1a8c9d87918f1bd01ccdf6718e5fffa09c6ca166732f41dd23af65df64771d40508a86c6590725eb2c8c dcc2a51b6a7ab6f483c393a2a59468341302a1d58f945541a5ffd23283c5c04b0c449ba3bb7e53b0bc6530bfcc5e9757ae8b49da67d2d47ef9aba7 c65ca3517d5bf6d7b5da3fb421 Answer(FLAG{...})>
def bits(integer): #Gets number of bits in integer result = 0 while integer: integer >>= 1 result += 1 return result def mod_pow(base, exponent, modulo=None): #Allows fast exponentation with and without moduli result = 1L if modulo == None: iteration = bits(exponent) while iteration >= 0: result *= result if (exponent >> iteration) & 1: result *= base iteration -= 1 else: firstModulus = base % modulo iteration = bits(exponent) while iteration >= 0: result = (result * result) % modulo if (exponent >> iteration) & 1: result = (result * firstModulus) % modulo iteration -= 1 return result def extended_gcd(aa, bb): lastremainder, remainder = abs(aa), abs(bb) x, lastx, y, lasty = 0, 1, 1, 0 while remainder: lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) x, lastx = lastx - quotient*x, x y, lasty = lasty - quotient*y, y return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1) # ax = 1 mod m def modinv(a, m): g, x, y = extended_gcd(a, m) if g != 1: raise ValueError return x % m p = 8976315748832882049382888999952934968751519382918644645219165984799383260818878872841708815011260078205052304139803432801309883064874870881446698538363907 q = 11384103879042800284460099871056066485859814619386355712939239906599306544104008668538843215172549115265357088501624031156542729241733486420090143766579357 e = 65537 c = 0x23464c5c42a522eed7e2f15d7ada1a8c9d87918f1bd01ccdf6718e5fffa09c6ca166732f41dd23af65df64771d40508a86c6590725eb2c8cdcc2a51b6a7ab6f483c393a2a59468341302a1d58f945541a5ffd23283c5c04b0c449ba3bb7e53b0bc6530bfcc5e9757ae8b49da67d2d47ef9aba7c65ca3517d5bf6d7b5da3fb421 phi = (p-1) * (q-1) n = p * q d = modinv(e, phi) m = mod_pow(c, d, n) print hex(m)[2:-1].decode("hex") # FLAG{didyoulearnrsa?}
全部回答すると、祝福が見れる。
Answer(FLAG{...})> FLAG{didyoulearnrsa?} Correct! ---------------------------------------------------------------- Congratulations! You solved all challenges!
おわりに
難易度自体は低めだったので、「早めに取り組めていたらなー」と後悔している。
やるだけだった。