g-140w-mdg 140w ud的超级密码码是多少

密码学笔记
此处会长期更新我做过的一些密码学题目。
一些基本知识:
RSA中几个用到的字母:
P : 大质数p
Q : 大质数q
φ(n) = φ(p) * φ(q) = (p - 1)(q - 1) = n - (p + q - 1)
e : encryption key (public key) (又称加密指数)
d : decryption key (private key)
e对于φ(n)的模反元素
c : ciphertext
m:message(m & n)
主要公式:
c≡me(modn)
m≡cd(modn)
欧拉函数:φ(n)是小于等于n的数中与n互质的数的数目。
欧拉函数是积性函数——若p,q互质,φ(p*q)= φ(p) *φ(q)
若p为质数,则φ(p)=p-1
同余定理:给定一个正整数m,如果两个整数a和b满足(a-b)能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)。
性质: 1 反身性 a≡a (mod m)
2 对称性 若a≡b(mod m),则b≡a (mod m)
3 传递性 若a≡b (mod m),b≡c (mod m),则a≡c (mod m)
4 同余式相加 若a≡b (mod m),c≡d(mod m),则a+-c≡b+-d (mod m)
5 同余式相乘 若a≡b (mod m),c≡d(mod m),则ac≡bd (mod m)
模反元素:指有一个整数d,可以使得e*d被φ(n)除的余数为1,即e*d ≡ 1 (mod φ(n)),这个式子等于e*d - 1 = k*φ(n)
快速幂取模:python实现
def modexp(c,d,n):
while d&0:
ret=(ret*c)%n
return ret
在linux上使用openssl解密的:
安装环境:
sudo -i apt-get install
libgmp3-dev
sudo -i pip install gmpy
sudo -i pip install pyasn1
rsatool.py:
import base64, fractions, optparse, random
import gmpy
except ImportError as e:
import gmpy2 as gmpy
except ImportError:
from pyasn1.codec.der import encoder
from pyasn1.type.univ import *
PEM_TEMPLATE = '-----BEGIN RSA PRIVATE KEY-----\n%s-----END RSA PRIVATE KEY-----\n'
DEFAULT_EXP = 65537
def factor_modulus(n, d, e):
Efficiently recover non-trivial factors of n
See: Handbook of Applied Cryptography
8.2.2 Security of RSA -& (i) Relation to factoring (p.287)
http://www.cacr.math.uwaterloo.ca/hac/
t = (e * d - 1)
while True:
quotient, remainder = divmod(t, 2)
if remainder != 0:
t = quotient
found = False
while not found:
a = random.randint(1,n-1)
while i &= s and not found:
c1 = pow(a, pow(2, i-1, n) * t, n)
c2 = pow(a, pow(2, i, n) * t, n)
found = c1 != 1 and c1 != (-1 % n) and c2 == 1
p = fractions.gcd(c1-1, n)
q = (n / p)
return p, q
class RSA:
def __init__(self, p=None, q=None, n=None, d=None, e=DEFAULT_EXP):
Initialize RSA instance using primes (p, q)
or modulus and private exponent (n, d)
self.e = e
if p and q:
assert gmpy.is_prime(p), 'p is not prime'
assert gmpy.is_prime(q), 'q is not prime'
self.p = p
self.q = q
elif n and d:
self.p, self.q = factor_modulus(n, d, e)
raise ArgumentError('Either (p, q) or (n, d) must be provided')
self._calc_values()
def _calc_values(self):
self.n = self.p * self.q
if self.p != self.q:
phi = (self.p - 1) * (self.q - 1)
phi = (self.p ** 2) - self.p
self.d = gmpy.invert(self.e, phi)
self.dP = self.d % (self.p - 1)
self.dQ = self.d % (self.q - 1)
self.qInv = gmpy.invert(self.q, self.p)
def to_pem(self):
Return OpenSSL-compatible PEM encoded key
return (PEM_TEMPLATE % base64.encodestring(self.to_der()).decode()).encode()
def to_der(self):
Return parameters as OpenSSL compatible DER encoded key
seq = Sequence()
for x in [0, self.n, self.e, self.d, self.p, self.q, self.dP, self.dQ, self.qInv]:
seq.setComponentByPosition(len(seq), Integer(x))
return encoder.encode(seq)
def dump(self, verbose):
vars = ['n', 'e', 'd', 'p', 'q']
if verbose:
vars += ['dP', 'dQ', 'qInv']
for v in vars:
self._dumpvar(v)
def _dumpvar(self, var):
val = getattr(self, var)
parts = lambda s, l: '\n'.join([s[i:i+l] for i in range(0, len(s), l)])
if len(str(val)) &= 40:
print('%s = %d (%#x)\n' % (var, val, val))
print('%s =' % var)
print(parts('%x' % val, 80) + '\n')
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-p', dest='p', help='prime', type='int')
parser.add_option('-q', dest='q', help='prime', type='int')
parser.add_option('-n', dest='n', help='modulus', type='int')
parser.add_option('-d', dest='d', help='private exponent', type='int')
parser.add_option('-e', dest='e', help='public exponent (default: %d)' % DEFAULT_EXP, type='int', default=DEFAULT_EXP)
parser.add_option('-o', dest='filename', help='output filename')
parser.add_option('-f', dest='format', help='output format (DER, PEM) (default: PEM)', type='choice', choices=['DER', 'PEM'], default='PEM')
parser.add_option('-v', dest='verbose', help='also display CRT-RSA representation', action='store_true', default=False)
(options, args) = parser.parse_args()
if options.p and options.q:
print('Using (p, q) to initialise RSA instance\n')
rsa = RSA(p=options.p, q=options.q, e=options.e)
elif options.n and options.d:
print('Using (n, d) to initialise RSA instance\n')
rsa = RSA(n=options.n, d=options.d, e=options.e)
parser.print_help()
parser.error('Either (p, q) or (n, d) needs to be specified')
rsa.dump(options.verbose)
if options.filename:
print('Saving %s as %s' % (options.format, options.filename))
if options.format == 'PEM':
data = rsa.to_pem()
elif options.format == 'DER':
data = rsa.to_der()
fp = open(options.filename, 'wb')
fp.write(data)
fp.close()
except optparse.OptionValueError as e:
parser.print_help()
parser.error(e.msg)
openssl 语句:
从公钥中读取e和n:openssl
rsa -pubin -text -modulus -in warmup -in 【public.pem】
Rsatool.py生成指定的私钥:python rsatool.py -o 【private.pem】 -e 【65537】 -p 【123】-q 【123】
用私钥解密:openssl rsautl -decrypt -in 【flag.enc】 -inkey 【private.pem】
啥都知道类
只要了解RSA的基本运作原理就可以解密了。
例题:HCTF GAME 密码学教室入门(一)
题目描述:
:0x9a724c6747de9eadccd33f4d60adac65590cafe66f69a2f4afbfd359e47ca6fd2dbde6bc574fbb6d8ae47beaa0c1ebeddL
:0x8c1c81cc005ce3dd6d684ebb8b1cef8a29b1cbd9aacacae68987d99aff0dd8967a4afa00f2116873L
:0x190ac8c2326369aaf8c7ca85e685bba968bf1f7ca222e1f0dfdeb01ef94bf15ca6d8f263fed22d67c26da6d31acfc4d599c70cba80859bee099e5a2dc3ab23aecf58f73f44dc623d9612efefb15bf8dab77d5d54e85L
:0x28b95b7ecbf537e007ae49864b7dbb93fc370a5L
:0x09c73ffad6d2ff6e47be588dfee7abd221ccca76ec1ec6e25c49f1c61c72b141c0b427d8e30eeab8cafecb0eb0e3f89e0fdbcc66a6aad4a1a4a85da5d569b7eeb6f2b524aa52993f9L
不解释,用python写个脚本:
c=0x09c73ffad6d2ff6e47be588dfee7abd221ccca76ec1ec6e25c49f1c61c72b141c0b427d8e30eeab8cafecb0eb0e3f89e0fdbcc66a6aad4a1a4a85da5d569b7eeb6f2b524aa52993f9
d=0x28b95b7ecbf537e007ae49864b7dbb93fc370a5
n=0x9a724c6747de9eadccd33f4d60adac65590cafe66f69a2f4afbfd359e47ca6fd2dbde6bc574fbb6d8ae47beaa0c1ebedd * 0x8c1c81cc005ce3dd6d684ebb8b1cef8a29b1cbd9aacacae68987d99aff0dd8967a4afa00f2116873
m=pow(c,d,n)
print hex(m)[2:len(hex(m))-1].decode('hex')
flag:hgame{rsa_1s_v3ry_e4sy!}
表面上是个RSA,其实根本没加密。
例题:HCTF GAME 密码学教室入门(四)
题目描述:
n: 0x81cfc71c44c83faf3ce533fc945f3bef30bc1b3debcecb8f7ef92fa169b8acdf75bda4c47dedc8f698f5ecf1d06adafae4ad67adafc6a3d9f529c0a055ce25e68bc21395L
c: 0xb35ffe6f77217dL
注意到e=1,c≡me*(modn),所以c ≡ m mod n,又因为n远大于c,所以m=c。
print 'b35ffe6f77217d'.decode('hex')
flag:hgame{rsa_1s_sti1l_e4sy_now!}
n能被工具快速分解类
两个常用的工具:
在线分解大质数(不一定都能成功分解):
windows工具:
将n成功分解得到p,q。由p,q,e模反求得d。最后c,d,n求m。
例题:HCTF GAME 密码学教室进阶(五)
题目描述:
n = 0xee290c7a603fc2edeb1af33bedc9612c5eeb4ab07d838a3bb43a977ed40ccd8f57ac5bc2daee2dec301aac508f9befc27fae4ab1ddd17d3a0c85740bed8d53eeda665a5fc1bed35fbbcedd7ac1f996f724b14f0228366aeaeff962c2a53dbb47bdbfd1e7b59be24d34edb0f3b53f0fe26c4a3e95cd1a47f806a1f16b86a9fc5e8af5cba0dd5ad58fb0e97ebac9a41dc3fb4a0e64c131bca19bd54e39bbfa0d7a0e7c89d955b1c9fL
e = 0xe438fddb77f9bc2cfa5ce8d0853cbfb657bd3dfc0b723c5f7c8c9b397e275d00cce1cf760fff90cbe513c6ccbcee33e499fb028c2b0d811bba22ef0c4fea3451ecdeb5d6e98bd5ed71abc532aeae6c29f52c3f9be649a4142810ddb5fcdca9cce24fddcf43f5dcf24e15f132e9dca4ff68cc7637139dbdbae8af118d8dfae3f811af9L
c = 0xbe864c22e69bd8b3c9797cf76afa2b2cac70c5a1a47fb6b6046dafe0eb299d12a7485ad9edaced28ef0bcba69c1e556ed2a69b6eca7e030f8cf61616faff4e063caf1ae7ffdf7abcc2d34db666a34fa9e0f108ce091ba2abff6ac8f4d3ffef9ecee37fa30cfb42f69afc734b18e94e96b5d24a4b63cdbbd36084bad58c5e5cb3d275c953efc73aff595f36d92e182d6705fee14dabd29dfdab80ac2dfa29a88a5f585cbda8bbL
上factordb成功分解:
python模反:
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
return x % m
e=0xe438fddb77f9bc2cfa5ce8d0853cbfb657bd3dfc0b723c5f7c8c9b397e275d00cce1cf760fff90cbe513c6ccbcee33e499fb028c2b0d811bba22ef0c4fea3451ecdeb5d6e98bd5ed71abc532aeae6c29f52c3f9be649a4142810ddb5fcdca9cce24fddcf43f5dcf24e15f132e9dca4ff68cc7637139dbdbae8af118d8dfae3f811af9
d=modinv(e,(p-1)*(q-1))
python解密:
c=0xbe864c22e69bd8b3c9797cf76afa2b2cac70c5a1a47fb6b6046dafe0eb299d12a7485ad9edaced28ef0bcba69c1e556ed2a69b6eca7e030f8cf61616faff4e063caf1ae7ffdf7abcc2d34db666a34fa9e0f108ce091ba2abff6ac8f4d3ffef9ecee37fa30cfb42f69afc734b18e94e96b5d24a4b63cdbbd36084bad58c5e5cb3d275c953efc73aff595f36d92e182d6705fee14dabd29dfdab80ac2dfa29a88a5f585cbda8bb
n=0xee290c7a603fc2edeb1af33bedc9612c5eeb4ab07d838a3bb43a977ed40ccd8f57ac5bc2daee2dec301aac508f9befc27fae4ab1ddd17d3a0c85740bed8d53eeda665a5fc1bed35fbbcedd7ac1f996f724b14f0228366aeaeff962c2a53dbb47bdbfd1e7b59be24d34edb0f3b53f0fe26c4a3e95cd1a47f806a1f16b86a9fc5e8af5cba0dd5ad58fb0e97ebac9a41dc3fb4a0e64c131bca19bd54e39bbfa0d7a0e7c89d955b1c9f
m=pow(c,d,n)
print hex(m)[2:len(hex(m))-1].decode('hex')
flag:hgame{1f_u_kn0w_p_q_1n_RSA_1t_is_easy___}
多个n有公约数分解类
还是对n的分解,只是和上面分解n的方法不同。这类题给了许多组MD5加密,有一个特点就是他们的q是相同的(p不同)。
运用gcd求出q,然后p=n/q求得p,然后老套路。
例题:HCTF GAME 进击的 Crypto [0]
题目描述(原题给了10组,我们只取前两组即可):
n is 56181
e is 65537
c is 29591
n is 78613
e is 65537
python分解n:
def gcd(a, b):
a, b = b, a
while b != 0:
temp = a % b
n1 = 56181
n2 = 78613
p = gcd(n1,n2)
print p,"\n\n",n1 // p
解得n1下的p,q:
老套路,模反求d,pow求m,不在写过程了,flag:hctf{I7_1s_d4nger0us_2_Sh4re_prim3}
低加密指数广播攻击类
看题目的话和上面很像,都是给了很多组的RSA,但这个类型有一个特点,就是e很小且相同。
如果选取的加密指数较低,并且使用了相同的加密指数给一个接受者的群发送相同的信息,那么可以进行广播攻击得到明文。
例题:HCTF GAME 进击的 Crypto [5]
题目描述:
n is 00149
n is 77577
n is 51761
c is 32923
n is 33277
n is 91129
c is 37506
n is 51793
c is 81909
n is 04501
n is 56273
n is 46821
c is 09553
n is 18257
m,e相同,不同的是c和n,有:
c1≡memodn1
c2≡memodn2
c3≡memodn3
cn≡memodnn
由中国剩余定理,得:
cx≡mnmodn1n2n3???nn
python解密得:
import gmpy
def my_parse_number(number):
string = "%x" % number
while string != '':
erg = erg + [chr(int(string[:2], 16))]
string = string[2:]
return ''.join(erg)
def e_gcd(a, b):
x,y = 0, 1
lastx, lasty = 1, 0
a, (q, b) = b, divmod(a,b)
x, lastx = lastx-q*x, x
y, lasty = lasty-q*y, y
return (lastx, lasty, a)
def chinese_remainder_theorem(items):
for a, n in items:
result = 0
for a, n in items:
r, s, d = e_gcd(n, m)
if d != 1:
raise "Input not pairwise co-prime"
result += a*s*m
return result % N, N
n=[00149,77577,51761,33277,91129,51793,04501,56273,46821,18257]
c=[7416,2689,32923,3831,37506,81909,5466,2926,09553,9316]
for i in range(len(c):
data += [(c[i],n[i])]
x, n = chinese_remainder_theorem(data)
realnum = gmpy.mpz(x).root(e)[0].digits()
print my_parse_number(int(realnum))
得flag:hctf{Hastad's_broadcast_attack_is_interesting}
提供enc和pem文件类
这类题目需要用linux的openssl来解。
例题:Jarvis OJ Medium RSA
题目: 密码:snl4
题目描述:flag.enc,pubkey.pem
linux下敲命令:openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem
n=0xCD8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
factordb分解n:
模反(方法见前)得d:
此时不能使用之前的方法解密,是解不出来的,还是需要用openssl,不过在这之前,需要用rsatool.py(在文章最前面,建议ctrl+F搜索)生成私钥。
linux下敲入(先把rsatool.py放在当前目录):python rsatool.py -o private.pem -e 65537 -p 299 -q 239
得到私钥以后用openssl解密:openssl rsautl -decrypt -in flag.enc -inkey private.pem -out flag.dec
flag:PCTF{256b_i5_m3dium}
Rabin 密码类
具体的看wiki吧:
这个我也是第一次接触,慢慢啃下来的,应该会写的很唠叨(可能还有错误),也算是自己的笔记吧。
例题:Jarvis OJ Hard RSA
题目: 密码:obbz
题目描述:flag.enc,pubkey.pem。1.不需要爆破。2.用你的数学知识解决此题。3.难道大家都不会开根号吗?
同上,先openssl,得到e和n:
n=0xCD8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
factordb分解n:
我们观察到e为2,提示用数学知识来解,所以应该是Rabin密码。
先写一下Rabin的加密方法:
p = {0,1,2 ... n-1}
c ≡ m^2 (mod n)
Rabin解密:
首先因为c=m2(modn)
从而有mp=c√(modp) 和 mq=c√(modq)
又因为二次剩余:
若p是奇质数且p不能整除d,则:
1.d是模p的二次剩余当且仅当:dp-12≡1(modp)
2.d是模p的非二次剩余当且仅当:dp-12≡-1(modp)
两遍同时乘上d,再开根号,得到:±cp+14≡c√(modn)
所以mp≡cp+14(modp) , mq≡cq+14(modq)
然后根据中国剩余定理:
设正整数m1,m2...mk两两互素,则同余方程组
x≡a1(modm1)
x≡a2(modm2)
x≡a3(modm3)
x≡ak(modmk)
有整数解。并且在模M=m1?m2?...?mk下的解是唯一的,解为
x≡(a1M1M-11+a2M2M-12+...+akMkM-1k)modM
其中Mi=M/mi,而M-1i为Mi模mi的逆元。
故我们得到:
r=(yp?p?mq+yq?q?mp)modn
s=(yp?p?mq-yq?q?mp)modn
其中有一个为我们想要的明文m。
python解密:
import gmpy
def n2s(num):
t = hex(num)[2:]
if len(t) % 2 == 1:
return ('0'+t).decode('hex')
return t.decode('hex')
c = int(open('flag.enc','rb').read().encode('hex'),16)
r = pow(c,(p+1)/4,p)
s = pow(c,(q+1)/4,q)
a = gmpy.invert(p,q)
b = gmpy.invert(q,p)
x =(a*p*s+b*q*r)%n
y =(a*p*s-b*q*r)%n
print n2s(x%n)
print n2s((-x)%n)
print n2s(y%n)
print n2s((-y)%n)
最后在输出中找到flag:PCTF{sp3ci4l_rsa}
共模攻击类
如果在RSA的使用中使用了相同的模n对相同的明文m进行了加密,那么就可以在不分解n的情况下还原出明文m的值。
例题:Jarvis OJ Hard RSA
题目: 密码:9fyr
题目描述:flag.enc1,flag.enc2,veryhardRSA.py
首先分析加密脚本,先判断下是否够512-11位,不够的随机补全。
然后就是使用相同的N,不同的e,加密相同的数据。所以想到了共模攻击。
即加密时有:
c1≡me1(modn)
c2≡me2(modn)
如果e1,e2互质,即存在s1,s2使得:
s1e1+s2e2=1
从而可以化简得到:cs11cs22≡m mod n
python脚本:
from gmpy import invert
n = 0x00b0bee5e3e9e5a7e8d00bfc8c7d7d03b82ef398deeba70d383aee8a964d380cb157f48c951adfa65db0b122ca40e42faa4f0d746e2f6069baf11cebd650f14b93cb1eea6d6e1da775502abff89d3a8bb88a976bce181f6f11eef80017bad238e470f949d3a4fa7f3e549dfffafd936fe411e006e4e93d1a00b0fea541bbfc8c3a94bc77ea54bacc6ceebd1bebe0f6f806db8b3ecd826cad24f5324ccdec6e8fead2cc8dcdc59402ccacccddefa010b7f196c74ba8c37b128f9ef78b7b9e56f71f77a1b4daad3fc54b5e7ef935d9a72fbb4bbc02e314d5c06b64dcccf45b5e611c805d335dbab0c35d226cc208d8ce4426fae006c7fe52d5267dcfb9c3884f51fddfdf4a9794bcfe0ee6c8ef421dba263aff6fd8f76deb62bdef7bead25aa2a92d1fe0c174bfad75e186a946a3f4387446cccebb3929
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
c1 = int(open('flag.enc1', 'rb').read().encode('hex'),16)
c2 = int(open('flag.enc2', 'rb').read().encode('hex'),16)
e2 = 65537
s = egcd(e1,e2)
c1 = invert(c1, n)
elif s2&0:
c2 = invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
print hex(m)[2:].decode('hex')
flag:PCTF{M4st3r_oF_Number_Th3ory}
不好分类,只能这样写了。
例题:HCTF GAME 进击的 Crypto [4]
题目描述:python文件
import hashlib
from gmpy2 import mpz, invert
def data_to_int(s):
return int(s.encode('hex'), 16)
def SHA1(data):
return data_to_int(hashlib.sha1(data).hexdigest())
def encrypt(data, p, q, g, x, k):
r = pow(g, k, p) % q
s = (invert(k, q) * (SHA1(data) + x * r)) % q
return (r, s)
data1 = "guest"
data2 = "admin"
(r1, s1) = encrypt(data1, p, q, g, x, k)
(r2, s2) = encrypt(data2, p, q, g, x, k)
print SHA1(data1)
print SHA1(data2)
def getflag(data):
if data == "getflag":
(r, s) = encrypt(data, p, q, g, x, k)
flag = "hctf{" + str(s % r) + "}"
print flag
这里我做一个小小的改动,把gmpy2库改成gmpy,我的linux不知怎的就是装不上gmpy2,就拿gmpy将就一下,反正也能做题,如果有大佬知道怎么装请务必告诉我谢谢。
顺便说一下,我查资料的时候看到一种叫DSA的加密算法和他好像,虽然不知道这是不是DSA。
先观察加密函数:
r=(gkmodp)modq
s=(invert(k,q)*(SHA1(data)+x*r))modq
其中invert函数是求逆元。
题中给了两组加密,说明只用一组来暴力跑肯定是不科学的。如果从r入手肯定是暴力了,所以我从s入手。
两组的s相减可以发现:
s2-s1=(invert(k,q)*(sha2-sha1))modq
消掉了其中的x*r。我们记s = s2 - s1,sha = sha2 - sha1。
得到:s=(y*sha)modq
其中:k*ymodq=1
因此我们两边乘k,化简得到:k=(sha÷s)modq
在python中利用gmpy的divm(sha,s,q)解出k。
对原始的s式子两边乘k,除r得到:
s1*kr=(sha1r+x)modq
从而化简得到:x=((s1*krmodq)-(sha1rmodq))modq
在python中利用gmpy的(divm(s1*k,r,q) - divm(sha1,r,q)) % q解出k。
以下为完整的python解密代码:
import hashlib
from gmpy import mpz, invert,divm
s = s2 - s1
sha = sha2 - sha1
k = divm(sha,s,q)
x = (divm(s1*k,r,q) - divm(sha1,r,q)) % q
def data_to_int(s):
return int(s.encode('hex'), 16)
def SHA1(data):
return data_to_int(hashlib.sha1(data).hexdigest())
def encrypt(data, p, q, g, x, k):
r = pow(g, k, p) % q
s = (invert(k, q) * (SHA1(data) + x * r)) % q
return (r, s)
def getflag(data):
if data == "getflag":
(r, s) = encrypt(data, p, q, g, x, k)
flag = "hctf{" + str(s % r) + "}"
print flag
getflag("getflag")
解得flag:hctf{}
CBC字节翻转攻击
例题:HCTF GAME explorer的奇怪番外5
题目描述:
咱们继续做密码学:)
这次的内容和块加密算法的块加密模式有关
这次我们来试试密码学中对Cipher Block Chaining (CBC)的一种常见攻击手段——CBC字节翻转攻击。
这里是服务器端源代码。
nc 121.42.25.113 20002
源码我贴在这里:
from Crypto.Cipher import AES
from Crypto import Random
def checkPad(data):
num = ord(data[-1])
if num & 1 or num & 16:
print "decrypt error"
return "null:null"
for i in xrange(1,num+1):
if data[-i] != chr(num):
print "decrypt error"
return "null:null"
return data[:-num]
def signin():
token = raw_input("give me you token:")
iv = token[:32].decode('hex')
cipherText = token[32:].decode('hex')
aes = AES.new(key,AES.MODE_CBC,iv)
plainText = aes.decrypt(cipherText)
t = checkPad(plainText).split(':')
if len(t) != 2:
print "you are not admin"
name,passwd = t
if name == 'admin' and passwd == 'alvndasjncakslbdvlaksdn':
print flag
elif name == 'null' and passwd == 'null':
print "you are not admin"
def signup():
print "sorry singup is close"
rand = Random.new()
for name in os.listdir('.'):
if 'flag' in name:
fp = open(name)
flag,key = fp.readlines()
fp.close()
flag = flag.strip()
key = key.strip().decode('hex')
welcome = '''
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
welcome to explorer's strange crypto
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
menu = '''
what do you want to do?
print welcome
while True:
print menu,
choose = raw_input('enter you choose:')
if choose == '1':
elif choose == '2':
print "invalid choose"
首先,我们sign up,比如我提交的是bdmin,密码和原来一样,是
alvndasjncakslbdvlaksdn。得到了token:
dbc290e4acefd383cd4bb93a0ee020efd7ecab77cfea5cfcad3539498
观察程序源码可知,前面的16位(decode之后)是iv:
def signin():
token = raw_input("give me you token:")
iv = token[:32].decode('hex')
cipherText = token[32:].decode('hex')
aes = AES.new(key,AES.MODE_CBC,iv)
plainText = aes.decrypt(cipherText)
name,passwd = checkPad(plainText).split(':')
if name == 'admin' and passwd == 'alvndasjncakslbdvlaksdn':
print flag
print "you are not admin"
CBC是16位一组进行加密的,因此我们编写代码在改变iv的情况下把bdmin改成admin:
a='dbc290e4acefd383cd4bb93a0ee020efd7ecab77cfea5cfcad3539498'
b=a.decode('hex')
b[0] = chr(ord(b[0]) ^ ord('b') ^ ord('a'))
b = ''.join(b)
c=b.encode('hex')
得到构造的token:
d8c290e4acefd383cd4bb93a0ee020efd7ecab77cfea5cfcad3539498
提交得到flag: hctf{cRypT0_ls_1nteRestlng!}
padding oracle attack
具体原理见:
例题:HCTF GAME explorer的奇怪番外6
题目描述:
这次的内容还是和块加密算法的块加密模式有关
这次依然是密码学中对Cipher Block Chaining (CBC)的一种著名攻击手段——padding oracle attack。
这里是服务器端源代码。这次就没有注册功能啦。
nc 121.42.25.113 20003
代码在此:
from Crypto.Cipher import AES
from Crypto import Random
def checkPad(data):
num = ord(data[-1])
if num & 1 or num & 16:
print "decrypt error"
return "null:null"
for i in xrange(1,num+1):
if data[-i] != chr(num):
print "decrypt error"
return "null:null"
return data[:-num]
def signin():
token = raw_input("give me you token:")
iv = token[:32].decode('hex')
cipherText = token[32:].decode('hex')
aes = AES.new(key,AES.MODE_CBC,iv)
plainText = aes.decrypt(cipherText)
t = checkPad(plainText).split(':')
if len(t) != 2:
print "you are not admin"
name,passwd = t
if name == 'admin' and passwd == 'alvndasjncakslbdvlaksdn':
print flag
elif name == 'null' and passwd == 'null':
print "you are not admin"
def signup():
print "sorry singup is close"
rand = Random.new()
for name in os.listdir('.'):
if 'flag' in name:
fp = open(name)
flag,key = fp.readlines()
fp.close()
flag = flag.strip()
key = key.strip().decode('hex')
welcome = '''
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
welcome to explorer's strange crypto
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
menu = '''
what do you want to do?
print welcome
while True:
print menu,
choose = raw_input('enter you choose:')
if choose == '1':
elif choose == '2':
print "invalid choose"
因为网上大多是 Web 应用中的已知密文的攻击,而这道题是已知明文的攻击。不过大同小异。
如果我们先随便选取一段密文,根据这种攻击的思想跑出相应的 IV,但是问题在于此时的明文不一定是我们想要的。我们知道 AES 解密后的中间值(即上图中的 Intermidiary Value)是不变的,对于同一段密文和 key 来说。假设我们之前跑出来的明文及 IV 分别为 m1、IV1,要求的明文及 IV 为 m2、IV2
m1&xor&IV1=Intermidiary&Valuem2&xor&IV2=Intermidiary&ValueIV2=Intermidiary&Value&xor&m2
也就是说我们用跑出来的 Intermidiary Value 和 想要的明文进行异或,就得得到符合要求的 IV,然后我们从最后一组 token 往前跑,因为这样就可以异或得到的 IV 作为前一组的密文
python脚本:
import time
import socket
import random
host = '121.42.25.113'
port = 20003
sk = socket.socket()
sk.connect((host,port))
time.sleep(0.5)
mes = sk.recv(1024)
msg1 = 'admin:alvndasjnc'.encode('hex')
msg2 = 'akslbdvlaksdn'.encode('hex') + '03' * 3
intermediary = list('-' * 32)
IV = '0' * 32
def sendData(IV, c):
IV = ''.join(IV)
sk.sendall('1\n')
sk.recv(1024)
sk.sendall(IV + c + '\n')
time.sleep(0.01)
mes = sk.recv(1024)
return mes
def changeIV(IV, num):
tmp = (32 - num)/2
nextPad = tmp + 1
print str(num + 1).zfill(2) + '-' + str(num + 2).zfill(2) + ': ',
for i in range(1,tmp + 1):
tmp2 = 32 - 2 * i
IV[tmp2:tmp2+2] = hex(int(''.join(IV[tmp2:tmp2+2]),16) ^ tmp ^ nextPad)[2:].zfill(2)
return ''.join(IV)
def changeMessageIV(IV, m):
for i in range(30,-1,-2):
IV[i:i+2] = hex(int(''.join(IV[i:i+2]),16) ^ 17 ^ int(''.join(m[i:i+2]),16))[2:].zfill(2)
return ''.join(IV)
def run(m, c):
IV = '0' * 32
if num & 0:
return changeMessageIV(list(IV), list(m))
for i in range(256):
h = hex(i)[2:].zfill(2)
IV = list(IV)
IV[num:num+2] = h
res = sendData(IV, c)
if 'decrypt error' not in res:
IV = changeIV(IV, num)
def main():
c = '0' * 32
token2 = run(msg2,c)
print 'The token 2 is ' + token2
c = token2
token1 = run(msg1,c)
print 'The token 1 is ' + token1
print sendData(token1,token2 + '0'*32)
if __name__ == '__main__':
自改的块加密
考块加密的基本知识以及结构。
例题:HCTF GAME explorer的奇怪番外3
题目描述:
密钥:explorer
密文:1fde6a7b2ff15d0abadd470
交flag的时候记得加上hctf{}
加密代码(python):
from hashlib import sha256
def xor(a,b):
return ''.join([chr(ord(i)^ord(j)) for i,j in zip(a,b)])
def HASH(data):
return sha256(data).digest()[:8]
def bes_encrypt(subkeys, data):
d1 = data[:8]
d2 = data[8:]
for i in subkeys:
d1 = xor(xor(HASH(d2),i),d1)
d1,d2 = d2,d1
return d2 + d1
def key_schedule(key):
subKeys = []
subKey = key
for i in xrange(16):
subKey = HASH(subKey)
subKeys.append(subKey)
return subKeys
def bes(key,data):
subKeys = key_schedule(key)
return bes_encrypt(subKeys, data).encode('hex')
if __name__ == "__main__":
print bes('explorer','??flag_is_here??')
用python写出解密函数:
from hashlib import sha256
def xor(a,b):
return ''.join([chr(ord(i)^ord(j)) for i,j in zip(a,b)])
def HASH(data):
return sha256(data).digest()[:8]
def bes_encrypt(subkeys, data):
d1 = data[:8]
d2 = data[8:]
for i in subkeys:
d1 = xor(xor(HASH(d2),i),d1)
d1,d2 = d2,d1
return d2 + d1
def key_schedule(key):
subKeys = []
subKey = key
for i in xrange(16):
subKey = HASH(subKey)
subKeys.append(subKey)
return subKeys
def bes(key,data):
subKeys = key_schedule(key)
return bes_encrypt(subKeys, data).encode('hex')
def bes_de(key,data):
subKeys = reversed(key_schedule(key))
return bes_decrypt(subKeys, data.decode('hex'))
def bes_decrypt(subkeys, data):
d1 = data[8:]
d2 = data[:8]
for i in subkeys:
d1,d2 = d2,d1
d1 = xor(xor(HASH(d2),i),d1)
return d1+d2
if __name__ == "__main__":
print bes_de('explorer','1fde6a7b2ff15d0abadd470')
加上flag{}得到最终的flag:flag{rEvers3_tHe_kEy!}
古典密码编码方法归根结底主要有两种,即置换和代换。
把明文中的字母重新排列,字母本身不变,但其位置改变了,这样编成的密码称为置换密码。最简单的置换密码是把明文中的字母顺序倒过来,然后截成固定长度的字母组作为密文。
代换密码则是将明文中的字符替代成其他字符。
凯撒密码是一种代换密码。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。
如果有数字,则数字进行另外偏移量的偏移(可能与字母相同)。
例题:HCTF GAME 密码学教室入门(二)
题目描述:mlfrj{Hfjxfw_hnumjw_8x_ozxy_ktw_kzs}
你可以用工具来解,也可以用python来解,比如我选择python。
a='mlfrj{Hfjxfw_hnumjw_8x_ozxy_ktw_kzs}'
for i in range(27):
for c in a:
if c.isalpha() :
c = chr(ord(c)-1)
if c.isalpha() == 0:
c = chr(ord(c)+26)
b.append(c)
a = ''.join(b)
lkeqi{Geiwev_gmtliv_8w_nywx_jsv_jyr}
kjdph{Fdhvdu_flskhu_8v_mxvw_iru_ixq}
jicog{Ecguct_ekrjgt_8u_lwuv_hqt_hwp}
ihbnf{Dbftbs_djqifs_8t_kvtu_gps_gvo}
hgame{Caesar_cipher_8s_just_for_fun}
gfzld{Bzdrzq_bhogdq_8r_itrs_enq_etm}
feykc{Aycqyp_agnfcp_8q_hsqr_dmp_dsl}
edxjb{Zxbpxo_zfmebo_8p_grpq_clo_crk}
dcwia{Ywaown_yeldan_8o_fqop_bkn_bqj}
cbvhz{Xvznvm_xdkczm_8n_epno_ajm_api}
baugy{Wuymul_wcjbyl_8m_domn_zil_zoh}
aztfx{Vtxltk_vbiaxk_8l_cnlm_yhk_yng}
zysew{Uswksj_uahzwj_8k_bmkl_xgj_xmf}
yxrdv{Trvjri_tzgyvi_8j_aljk_wfi_wle}
xwqcu{Squiqh_syfxuh_8i_zkij_veh_vkd}
wvpbt{Rpthpg_rxewtg_8h_yjhi_udg_ujc}
vuoas{Qosgof_qwdvsf_8g_xigh_tcf_tib}
utnzr{Pnrfne_pvcure_8f_whfg_sbe_sha}
tsmyq{Omqemd_oubtqd_8e_vgef_rad_rgz}
srlxp{Nlpdlc_ntaspc_8d_ufde_qzc_qfy}
rqkwo{Mkockb_mszrob_8c_tecd_pyb_pex}
qpjvn{Ljnbja_lryqna_8b_sdbc_oxa_odw}
poium{Kimaiz_kqxpmz_8a_rcab_nwz_ncv}
onhtl{Jhlzhy_jpwoly_8z_qbza_mvy_mbu}
nmgsk{Igkygx_iovnkx_8y_payz_lux_lat}
mlfrj{Hfjxfw_hnumjw_8x_ozxy_ktw_kzs}
lkeqi{Geiwev_gmtliv_8w_nywx_jsv_jyr}
得到:hgame{Caesar_cipher_8s_just_for_fun}
再对数字进行一定的偏移,比如我们观察此时应该是’1s’。
flag:hgame{Caesar_cipher_1s_just_for_fun}
埃特巴什码
也是一种非常简单的以字母倒序排列作为特殊密钥的替换密码。
替换方法如下:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ZYXWVUTSRQPONMLKJIHGFEDCBA
例题:暂无
比如有明文m = the quick brown fox jumps over the lazy dog
密文:c = gsv jfrxp yildm ulc qfnkh levi gsv ozab wlt
python脚本:
from string import maketrans,translate
map = maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz','ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba')
m_or_c = 'gsv jfrxp yildm ulc qfnkh levi gsv ozab wlt'
print m_or_c.translate(map)
rot类(5,13,18,47)
rot类其实就是特殊的凯撒密码。特殊在它具有可逆性,可以自我解密。加密和解密的函数相同,比如rot13,13是因为有26个字母,一个字母+13再+13以后就是它本身。
ROT5:只对数字进行编码,用当前数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6,以此类推顺序循环。
ROT13:只对字母进行编码,用当前字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O,以此类推顺序循环。
ROT18:这是一个异类,本来没有,它是将ROT5和ROT13组合在一起,为了好称呼,将其命名为ROT18。
ROT47:对数字、字母、常用符号进行编码,按照它们的ASCII值进行位置替换,用当前字符ASCII值往前数的第47位对应字符替换当前字符,例如当前为小写字母Z,编码后变成大写字母K,当前为数字0,编码后变成符号_。用于ROT47编码的字符其ASCII值范围是33-126,具体可参考ASCII编码。
例题:HCTF 2014 Entry
题目描述:57R9S980RNOSPQO9S80Q36P 听说丘比龙一口气能吃“13”个甜甜圈呢!
python解rot13:
from string import maketrans,translate
map = maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz','NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')
m_or_c = '57R9S980RNOSPQO9S80Q36P'
print m_or_c.translate(map)
得到57E9F980EABFCDB9F80D36C
md5解密得Qoobee
简单替换密码
简单换位密码(Simple Substitution Cipher)加密方式是以每个明文字母被与之唯一对应且不同的字母替换的方式实现的。和埃特巴什码的区别在于他的替换码不再是Z→A,而是乱序的,比如:
abcdefghijklmnopqrstuvwxyz
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
phqgiumeaylnofdxjkrcvstzwb
解这种密码我们可以用字频分析的方法(当密文足够长时),或者我们可以利用网站:
例题:暂无
比如我们有密文:
pmpafxaikkitprdsikcplifhwceigixkirradfeirdgkipgigudkcekiigpwrpucikceiginasikwduearrxiiqepcceindgmieinpwdfprduppcedoikiqiasafmfddfipfgmdafmfdteiki
扔进quipqiup中,解得明文:
again pierre was overtaken by the depression he so dreaded for three days after the delivery of his speech at the lodge he lay on a sofa at home receiving no one and going nowhere
希尔密码(Hill Cipher)是基于线性代数多重代换密码,由Lester S. Hill在1929年发明。每个字母转换成26进制数字:A=0, B=1, C=2…Z=25一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果 MOD 26。
举例:我们有明文ACT,明文对应矩阵:
???0&2&19???
我们的加密密钥为:GYBNQKURP,对应加密矩阵:
???6&13&2024161711015???
计算过程:
???6&13&2024161711015??????0&2&19???=???67&222&319???≡???15&14&7???(mod26)
得到密文:FIN
解密先求加密矩阵的逆矩阵,即解密矩阵:
???6&13&2024161711015???-1≡???8&21&21581210218???(mod26)
解密计算:
???8&21&21581210218??????15&14&7???≡???260&574&539???≡???0&2&19???(mod26)
得到明文:ACT
例题:HCTF GAME 密码学教室进阶(六)
题目描述:
:jchfecncvxogmtgqtqlqamqutqsgnniw
:5 17 4 15
完成解密以后加上{}作为
这题…手解嫌累,写代码我也不会写,只能找个在线解密:
总之扔进去就好了…
flag:hgame{haohaoxuexiandainihuiqiuniyuanma}
是一种简单的替换密码。
应该都看得懂,不解释了。
栅栏密码(Rail-fence Cipher)就是把要加密的明文分成N个一组,然后把每组的第1个字符组合,每组第2个字符组合…每组的第N(最后一个分组可能不足N个)个字符组合,最后把他们全部连接起来就是密文,这里以2栏栅栏加密为例。
例题:IDF 聪明的小羊
题目描述:
一只小羊跳过了栅栏,两只小样跳过了栅栏,一坨小羊跳过了栅栏…
tn c0afsiwal kes,hwit1r
ttessfu}ua u
hmqik e {m,
n huiouosarwCniibecesnren.
写个py脚本:
def decrypt(c = None, zu = 0, len = 0 ):
for i in range(zu):
for j in range(len):
m = m+c[i+zu*j]
c="tn c0afsiwal kes,hwit1r
ttessfu}ua u
hmqik e {m,
n huiouosarwCniibecesnren."
for zu in range(1,len(c)):
if len(c)%zu == 0:
print decrypt(c,zu,len(c)/zu)
输出为可能的答案:
tn c0afsiwal kes,hwit1r
ttessfu}ua u
hmqik e {m,
n huiouosarwCniibecesnren.
taastg su km uwbnnfl,1, sah ,hoCer s hrntf me usncecikw ptuuq
iaien0wei te} i{noris.
the anwser is wctf{C01umnar},if u is a big new,u can help us think more question,tks.
得flag:wctf{C01umnar}
替换表(这是最常用的一套):
加密者需使用两种不同字体。准备好一篇包含相同AB字数的假信息后,即两种字体分别代表A型和B型。然后假信息中的每个字母按字体来决定其代表“A”还是“B”。
法兰西斯·培根另外准备了一种方法,其将大小写分别看作A与B。
例题:HCTF GAME 我是一个没节操的misc题目
题目描述:flag的其中一段加密后是:
wOsHiShUIWOZAINAaaAa_zHeShIsHENMEgUI_SHuinENggaOSuwo}
按照大写A,小写B,首先得到:
BABABABAAAAAAAAABBAB_BABABABAAAAABAA_AABBBAABBBAABBB}
查表得到:xiao_xie_hhh}
维吉尼亚密码
等我整理。。。
代码混淆加密
aaencode可以将JS代码转换成常用的网络表情,也就是我们说的颜文字js加密。
在线加密:
比如我们有代码:
?ω??= /`m?)? ~┻━┻
/ ['_']; o=(???)
=_=3; c=(?Θ?) =(???)-(???); (?Д?) =(?Θ?)= (o^_^o)/ (o^_^o);(?Д?)={?Θ?: '_' ,?ω?? : ((?ω??==3) +'_') [?Θ?] ,???? :(?ω??+ '_')[o^_^o -(?Θ?)] ,?Д??:((???==3) +'_')[???] }; (?Д?) [?Θ?] =((?ω??==3) +'_') [c^_^o];(?Д?) ['c'] = ((?Д?)+'_') [ (???)+(???)-(?Θ?) ];(?Д?) ['o'] = ((?Д?)+'_') [?Θ?];(?o?)=(?Д?) ['c']+(?Д?) ['o']+(?ω?? +'_')[?Θ?]+ ((?ω??==3) +'_') [???] + ((?Д?) +'_') [(???)+(???)]+ ((???==3) +'_') [?Θ?]+((???==3) +'_') [(???) - (?Θ?)]+(?Д?) ['c']+((?Д?)+'_') [(???)+(???)]+ (?Д?) ['o']+((???==3) +'_') [?Θ?];(?Д?) ['_'] =(o^_^o) [?o?] [?o?];(?ε?)=((???==3) +'_') [?Θ?]+ (?Д?) .?Д??+((?Д?)+'_') [(???) + (???)]+((???==3) +'_') [o^_^o -?Θ?]+((???==3) +'_') [?Θ?]+ (?ω?? +'_') [?Θ?]; (???)+=(?Θ?); (?Д?)[?ε?]='\\'; (?Д?).?Θ??=(?Д?+ ???)[o^_^o -(?Θ?)];(o???o)=(?ω?? +'_')[c^_^o];(?Д?) [?o?]='\"';(?Д?) ['_'] ( (?Д?) ['_'] (?ε?+(?Д?)[?o?]+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(???)+ (c^_^o)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((o^_^o) +(o^_^o))+ (?Д?)[?ε?]+(???)+ (c^_^o)+ (?Д?)[?ε?]+((???) + (o^_^o))+ ((???) + (?Θ?))+ (?Д?)[?ε?]+(???)+ (c^_^o)+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (o^_^o)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((o^_^o) +(o^_^o))+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (o^_^o))+ (o^_^o)+ (?Д?)[?ε?]+((o^_^o) +(o^_^o))+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+((o^_^o) +(o^_^o))+ (o^_^o)+ (?Д?)[?ε?]+((o^_^o) +(o^_^o))+ (o^_^o)+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (o^_^o))+ ((???) + (?Θ?))+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+((???) + (o^_^o))+ (o^_^o)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((???) + (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ (???)+ (?Д?)[?ε?]+((???) + (?Θ?))+ (c^_^o)+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((o^_^o) +(o^_^o))+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((???) + (o^_^o))+ (?Д?)[?ε?]+((???) + (o^_^o))+ ((???) + (o^_^o))+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+((???) + (?Θ?))+ (?Θ?)+ (?Д?)[?o?]) (?Θ?)) ('_');
解密方法就是在把代码后面的('_');去掉,然后在浏览器控制台上跑一下。
function anonymous() {
var f = "ctf{233}";alert("flag?")
和上面类似。
在线加密:
解法同上,把最后一个()去掉。
和上面类似。
在线加密:
解法同上,把最后一个()去掉。
Brainfuck是一种极小化的计算机语言,按照”Turing complete(完整图灵机)”思想设计的语言,它的主要设计思路是:用最小的概念实现一种“简单”的语言,BrainF**k 语言只有八种符号,所有的操作都由这八种符号(& & + - . , [ ])的组合来完成。
在线加解密:
+++++ ++++[ -&+++ +++++ +&]&+ +++++ +++++ +++++ ++.&+ +++[- &++++ &]&+.
&+++[ -&--- &]&-- ---.& ++++[ -&+++ +&]&+ ++++. &++++ ++++[ -&--- -----
&]&-- ----- --.+. ..&++ +++++ +[-&+ +++++ ++&]& +++++ +++++ .&
不解释,直接扔进去就好了。
明文:ctf{2333}
base/32/64等
先说base16,其实就是hex,对,你没有看错。
比如有加密:
774F94EF7AE5776F7D
直接在python里用decode(‘hex’)就能解出明文。
有如下编码映射表:
只用到了A~Z和2~7。
解base64直接用python的base64模块就行,不会的用在线解密也可以,玩re的需要去看看base64的加密函数怎么写,逆向时可能会遇到。
莫尔斯电码
直接查表就好。
一次性密码本(OTP)
例题:HCTF GAME 进击的 Crypto [1] - 神秘的加密系统
题目描述:(题目源地址,看运气还能不能打开)
我们随便输入,发现每次加密的结果都不一样,猜测加密的key不可能无限长,所以输入了非常长的一串‘1’,试出来key的长度为128bytes。然后观察加密后网页的源码,可以发现下面有flag_enc:
加密的方法是K xor M_input = C_input ,K xor Flag = Flag_enc。
而我们现在知道了M_input,C_input,Flag_enc。
所以Flag = K xor Flag_enc = (M_input xor
Flag_enc。
先写个python脚本获取Flag_enc(此处吐槽一下为什么Flag_enc不base64或hex显示):
import urllib2
req = urllib2.Request( url = 'http://119.29.138.57:23333/crypto/encode_system/index.php', data = 'message=')
response = urllib2.urlopen(req).read()
print response
print response[-131:-3].encode('hex')
从而得到了C_input和Flag_enc,python解密之:
c=[0x59,0x4f,0x72,0x5d,0x5c,0x07,0x72,0x6a,0x7e,0x50,0x07,0x67,0x49,0x44,0x15,0x6a,0x6f,0x7b,0x73,0x5e,0x77,0x18,0x50,0x53,0x59,0x08,0x6c,0x4f,0x40,0x4b,0x74,0x10,0x5d,0x5b,0x59,0x6f,0x15,0x05,0x01,0x62,0x1d,0x6d,0x7d,0x40,0x4c,0x62,0x7d,0x19,0x10,0x04,0x09,0x1b,0x68,0x5f,0x79,0x4d,0x19,0x7e,0x1c,0x4a,0x06,0x09,0x6e,0x55,0x51,0x08,0x12,0x1e,0x70,0x72,0x75,0x6d,0x72,0x70,0x40,0x6c,0x7d,0x04,0x42,0x5d,0x48,0x7f,0x07,0x1e,0x76,0x01,0x42,0x61,0x7a,0x67,0x43,0x00,0x74,0x7d,0x79,0x45,0x41,0x0d,0x55,0x58,0x7a,0x79,0x00,0x4a,0x07,0x52,0x76,0x45,0x04,0x15,0x45,0x44,0x15,0x4d,0x42,0x4b,0x42,0x42,0x5f,0x5d,0x69,0x63,0x5f,0x12,0x74,0x64,0x61,0x7b]
c_flag=list('3dca7e1e0b2f4d233d86f1eb5fe2ee6f2a760e3b4aba693dd017b3f420a1b161c336c0d5f501a302a37'.decode('hex'))
for i in range(128):
c[i]=c[i]^ord('1')
b.append(chr(c[i] ^ ord(c_flag[i])))
b=''.join(b)
得到flag:hctf{Rive5t_C1pher_4_1s_ez}
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 e 140w p 超级密码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信