0%

WriteUp of 2022scuctf-CTF

来源信息

SignIN

hint1: 首页只是为了好看,不是注入
hint2: 简单的云渗透

sign1.png

刚开始dompdf rce差点没试死,最后出了hit才知道不是rce,看到网站指纹是spring,去网上找相关的文档进行测试,发现env接口可以访问,有回显,里面有flagpath,以及secretid和secretkey。但是secretkey是*遮掩的。在heapdump接口下载到了JVM 堆信息,利用Memory Analyzer解析出secretkey,最终解析出了key。

sign2.png

从flag和hint知道是云渗透,需要去连接oss,利用ossutilmac64工具配置相关的参数,访问flag的path就可以拿到flag了。

sign3.png

Never Gonna Give Misc Up

题目:

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
take me to ur heart
we know the sys and we're gonna play it
we know the base64 and we're gonna play it
give key up "Never Gonna Give You Up"
gonna encrypt rick
give areYouRoll up 0
give astleyCounter up 0
together forever and never to part
and if u ask me how im feeling astleyCounter is length(rick)
desert u
say goodbye
and if u ask me how im feeling areYouRoll is 1
desert u
say goodbye
give watermanCounter up 0
together forever and never to part
and if u ask me how im feeling watermanCounter+astleyCounter is length(rick)
give areYouRoll up 1
desert u
say goodbye
and if u ask me how im feeling watermanCounter is length(key)
desert u
say goodbye
give rick[astleyCounter + watermanCounter] up ord(rick[astleyCounter + watermanCounter]) ^ ord(key[watermanCounter])
give watermanCounter up watermanCounter + 1
say goodbye
give astleyCounter up astleyCounter + length(key)
say goodbye
give rick up base64.b64encode(bytes(rick))
i just wanna tell u how im feeling rick
say goodbye
give flag up sys.stdin.readline()[:-1]
encrypt(list(flag))
# PQYDBgZGPFYIWgUZf1xCSBhsXRENYUgrAFsEShVzQlhXAxR2CkNQFTxeEF0=

可以看到歌词是有规律的,首先去网上找相似的题目,在github找到了RickRoll,参照着其中的语法讲文本翻译成python代码并进行调试,可以发现加密函数和解密函数是一样的。只需要修改最后的输出即可。

参考这个:https://github.com/Rick-Lang/rickroll-lang 进行翻译

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
import base64
import sys
from tokenize import String
from turtle import right


def encrypt(string):
key = "Never Gonna Give You Up"
rick = list(string)
areYouRoll = 0
astleyCounter = 0
while True:
if astleyCounter == len(rick):
break
if areYouRoll == 1:
break
watermanCounter = 0
while(True):
if watermanCounter + astleyCounter == len(rick):
areYouRoll = 1
break
if watermanCounter == len(key):
break
rick[astleyCounter + watermanCounter] = ord(rick[astleyCounter + watermanCounter]) ^ ord(key[watermanCounter])
watermanCounter = watermanCounter + 1
astleyCounter = astleyCounter + len(key)
rick = base64.b64encode(bytes(rick))
print(rick)

解密函数

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
def decrypt(flag_en):
string = base64.b64decode(flag_en)
flag_en = bytes.decode(string)
key = "Never Gonna Give You Up"
rick = list(flag_en)
areYouRoll = 0
astleyCounter = 0
while True:
if astleyCounter == len(rick):
break
if areYouRoll == 1:
break
watermanCounter = 0
while(True):
if watermanCounter + astleyCounter == len(rick):
areYouRoll = 1
break
if watermanCounter == len(key):
break
rick[astleyCounter + watermanCounter] = ord(rick[astleyCounter + watermanCounter]) ^ ord(key[watermanCounter])
watermanCounter = watermanCounter + 1
astleyCounter = astleyCounter + len(key)
rick = base64.b64encode(bytes(rick))
rick = base64.b64decode(rick)
rick = bytes.decode(rick)
print(rick)

decrypt('PQYDBgZGPFgIC1ATcQoVSBloV0ENYRYoUVtcRBkjQghfVkUhWBcGFmBYQ10=')

最后可以成功解出flag。

CheckIn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(0);

$action = $_GET['a']?$_GET['a']:highlight_file(__FILE__);

if($action==='inject'){
die('Permission denied');
}

$lock = call_user_func(($_GET['Y']));
if (isset($_GET['env']) && $lock == "Web_Dog" && $action == 'inject') {
foreach ($_GET["env"] as $k => $v) {
putenv("{$k}={$v}");
}

system("bash -c 'snakin'");
foreach ($_GET["env"] as $k => $v) {
putenv("{$k}");
}
}

?>

第一反应就是绕参数,构造env,Y,a。a由于用的是弱等于,所以只需要保证前面一致,后面随便加些字符就可以绕过,env去网上找到相关的题目,是环境命令注入,但是Y由于是call_user_func()函数,因此刚开始一直没有任何的办法,最后只能尝试利用phpinfo()去解析,成功解析。在返回的环境中发现了flag。

checkin.png

无e烦

RSA加密,已知多组c,m,已知n,求解flag

题目:

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
from Crypto.Util.number import *
from random import randint
from hashlib import md5, sha256
from secret import flag

p = getPrime(512)
q = getPrime(512)
e = getPrime(1020)
n = p * q
M = [randint(1, 2**128) for _ in range(10)]
C = []
m = randint(1, 2**128)

for i in M:
tmp = pow(i, e, n)
C.append(tmp)
c = pow(m, e, n)
assert flag.lstrip('SCUCTF{').rstrip('}') == md5(str(c).encode()).hexdigest()

print('n = ', n)
print('m = ',m)
print('M = ', M)
print('C = ', C)
print('sha256(c) = ', sha256(str(c).encode()).hexdigest())
'''
this time, you dont have yi, can you solve it?
n = 80866130102261518785138247492226418988283622967107642931626670770991287290017575544856640708656070056599413982921939820092653964250560158534164684509508570827031257145358915936716873579275999289598802214938312512124960829274763697183422853018643009337211154573323694306354847681849997475073748060554116885743
m = 27869827573821748315559900687594988919
M = [5579, 598603829, 260990180, 1021754, 776307182737258, 1024275153677530399, 4600527292991, 122745486818718559362816, 648394777237946314, 967584531487748385405909929860]
C = [31144948752006156956371408281561352243079201486174266637408555124157021185950319222361922834637592274602797401823142568566421878331058293593226929896870037754087323313283303137533025781672293482174192932461883863211124310703337677122102074722437833121327084819887896193852163626471460810662932603076534660804, 58749052925641223456561705208530964408557935651157882734266347388456853409033384416852410757712668576320121029921896159470323217774586441972199278374439949270876469606930228396601576234668190157650922636135501186357625172032576738756614273367295339284973641828226470658939082400779599258757898885883644801053, 40579637913832144242682484264514378732436426402443803846093953264515971181103912187778246987360607324323099933248625621555519103040756905979660584142448386505386901820391693230451974101594790778026848209779850319523275751832867671987115959904668387865788935422538240044475848660391245453237006973560308165704, 15835925903597045972140032459728544439513422823860173109658290670683594043875129538306223165929079184397089052592444654067130249396164980960356271754915481618011410536765933171454501338047351306704434512914546553962486447770536415910399995606608613315118790692706536805083836633281529931209281637891318353741, 4151494489564600318094655116793301906740457645167301450751640199360784554254420449223484211520605752417331051052221881536558310384015644237944026227453976543115190245641063933315808492207164476079528582238760181801532524373077098185522630038060400419605143520089304061730233240190827575204697167386552820873, 46450004515612124682062326769786875920262836498726465653281013385901400386040827258028783122454588622468817101329068510845265192227085655559383112363438579993120259202146869556553612006784560362028894578429513744992720306276354566189337126874210742595318199174149347871156773709876660547468111493256985790264, 5293675028656705650831635378836383447792200771454173820886211319500431128744638963226815998459995451887706586775256373154495638727831792733331349999470387188688842268193444623645723157924374339534474296911972302241786675561240710375985864649928838541714831703346767850719207370350131520678912020234750273930, 30043574658200438024547973628567719018751546081493990329929735757336474377209161041596827306653602292215720621453139092179169784224079738652396993819458373985141265627934492408720528950069791313892499982826159264170102770059863789006549726625129186587016838115681900755406881891907749234407979155358030945914, 49664459429620491137496885409272085607758468537571273414043041753461839754010622955053495314196284424560133883998315943659743474201365515603408943978523525179827702636431575706855973368124936003475671990897616340108065511459270017655645179716434335969764382936670154226518119191587925302403315274959019503422, 72335423827835340317296400031661018813932187781068379309839710979890568519179106231620831225764055797117609283378510499491626336945698456043068123495971189674660151501766805123602763163842302478047056395083249502992176542543200848695685618337947070448376674020551810665597616550148876318339506522538505673458]
sha256(c) = 845a1ffbdc9850b729c57b7e672355aa3eb163e382f02e620cc37394ddb52163
'''

题目给出了多组的c和M,而且还给出了一个m,flag = md5(c) = RSA(m)。

根据RSA的公式,我们可以得到:

c1 = m1^e mod n
c2 = m2^e mod n
...
c10 = m10^e mod n

其中,c1, c2, ..., c10是密文,m1, m2, ..., m10是明文。
1
c1c2 = (m1m2 mod n)^e mod n

只要能找到m与Mk之间的关系,就可以找到c与Ck之间的关系。
最终

我们对m和m1~m10进行分解

1
2
3
4
5
6
7
8
9
10
11
12
# [7, 797]
# [631, 948659]
# [2, 2, 5, 11, 83, 14293]
# [2, 641, 797]
# [2, 371179, 1045731551]
# [1012967, 1011163397897]
# [7, 657218184713]
# [2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1231, 43277783002583209]
# [2, 631, 641, 844913, 948659]
# [2, 2, 5, 426095513, 113540802703518305461]

# m [7, 7, 844913, 1012967, 657218184713, 1011163397897]

最终发现m之间的关系满足

1
m = (m0 * m6 * m8 * m5) / (m3 * m1)

因此C也满足同样的关系,这里直接使用sege可以计算得到c,但是一定要记得mod n

c = [(c0 * c6 * c8 * c5) / (c3 * c1)] mod n

最终计算得到flag

1
md5(str(c).encode()).hexdigest() == flag

flag = 0bc5e3a135bc252623bb4a391c886c08

窗外的山

开局一张图,位置全靠猜

image.jpeg

找图中框出来的山峰

question.png

先利用在线的网站查图片的信息
https://www.strerr.com/cn/exif.html

fig2.png

fig1.png

找到发现是在成都附近的山峰,网上搜成都附近的山,对照一下就是天牙峰

https://sichuan.scol.com.cn/sczh/202009/57894100.html

截屏2022-05-23 16.54.32.png