Skip to content

Instantly share code, notes, and snippets.

@ptr-yudai
Last active August 28, 2016 15:31
Show Gist options
  • Save ptr-yudai/468bf5546c11533fd5c1f7fe8f719b4a to your computer and use it in GitHub Desktop.
Save ptr-yudai/468bf5546c11533fd5c1f7fe8f719b4a to your computer and use it in GitHub Desktop.
hashme - Cryptography - katagaitaiCTF#5 関西med
# coding: utf-8
from pwn import *
#
# crypto200.pyからそのまま引用
#
from math import sin
from urlparse import parse_qs
from base64 import b64encode
from base64 import b64decode
from re import match
def xor(a, b):
return ''.join(map(lambda x : chr(ord(x[0]) ^ ord(x[1])), zip(a, b * 100)))
def F(X,Y,Z):
return ((~X & Z) | (~X & Z)) & 0xFFFFFFFF
def G(X,Y,Z):
return ((X & Z) | (~Z & Y)) & 0xFFFFFFFF
def H(X,Y,Z):
return (X ^ Y ^ Y) & 0xFFFFFFFF
def I(X,Y,Z):
return (Y ^ (~Z | X)) & 0xFFFFFFFF
def ROL(X,Y):
return (X << Y | X >> (32 - Y)) & 0xFFFFFFFF
#
# 接続
#
#sock = remote('127.0.0.1', 9999)
sock = remote('katagaitai.orz.hm', 7777)
#
# 適当なユーザーのcertを取得する
#
username = "A" * 128
baseinfo = "login=%s&role=anonymous" % username
sock.recvuntil('[1] Login\n======================\n')
sock.sendline('0') # [0] Register
sock.recvuntil('Your login: ')
sock.sendline(username) # 適当なユーザー名で登録
sock.recvuntil('Your auth certificate:\n')
# certからxorされた"login=%s&role=anonymous"を取得
cert_original = sock.recvline()
cert_original = b64decode(cert_original)
cert = cert_original[0:-32]
#
# KEYを取得する
#
KEY = xor(cert, baseinfo)
for i in range(1, len(KEY)):
if KEY[0:i] == KEY[i:2*i]: # 繰り返しを検出
KEY = KEY[0:i]
break
print("[INFO] KEY found : %s" % KEY.encode('hex'))
#
# hashme(SALT + "login=[username]&role=anonymous" + "&role=administrator")
# を計算する
#
cert_original = xor(cert_original, KEY)
hash_original = cert_original[-32:]
X = [int(0xFFFFFFFF * sin(i)) & 0xFFFFFFFF for i in xrange(256)]
s = "&role=administrator" # 追加する文字列
# SALTの長さによってiが変わる
for SALT_len in range(1, 32):
print("[INFO] trying new length : %d" % SALT_len)
# 元に戻す
B = int(hash_original[0:8], 16)
A = int(hash_original[8:16], 16)
D = int(hash_original[16:24], 16)
C = int(hash_original[24:32], 16)
for i,ch in enumerate(s):
i = SALT_len + len(baseinfo) + i # 追加文字なのでiを更新
k, l = ord(ch), i & 0x1f
A = (B + ROL(A + F(B,C,D) + X[k], l)) & 0xFFFFFFFF
B = (C + ROL(B + G(C,D,A) + X[k], l)) & 0xFFFFFFFF
C = (D + ROL(C + H(D,A,B) + X[k], l)) & 0xFFFFFFFF
D = (A + ROL(D + I(A,B,C) + X[k], l)) & 0xFFFFFFFF
# hash_newができた
hash_new = ''.join(map(lambda x : hex(x)[2:].strip('L').rjust(8, '0'), [B, A, D, C]))
print("[INFO] new hash generated : %s" % hash_new)
# hash_newからcert_newを作る
cert_new = baseinfo + s + hash_new
cert_new = b64encode(xor(cert_new, KEY))
print("[INFO] new cert generated : %s" % cert_new)
# 試してみる
sock.recvuntil('[1] Login\n======================\n')
sock.sendline('1') # [1] Login
sock.recvuntil('Provide your certificate:')
sock.sendline(cert_new)
sock.recvline()
ret = sock.recvline()
print("[INFO] received : %s" % ret)
# 成功したか
if "[+] Welcome," in ret:
print(sock.recv(4096))
break
sock.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment