又被暴打了QAQ

RE

baby_c++

判断的地方找数组即可

1
2
3
4
5
from prism import *
a = [0x00, 0x53, 0x49, 0x43, 0x54, 0x46, 0x7B, 0x34, 0x65, 0x34, 0x37, 0x34, 0x62, 0x38, 0x61, 0x2D, 0x39, 0x64, 0x66, 0x36, 0x2D, 0x34, 0x35, 0x34, 0x62, 0x2D, 0x39, 0x65, 0x61, 0x36, 0x2D, 0x64, 0x34, 0x66, 0x35, 0x65, 0x33, 0x37, 0x63, 0x64, 0x35, 0x31, 0x66, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

pl(a)
#SICTF{4e474b8a-9df6-454b-9ea6-d4f5e37cd51f}

ez_pyc

分析逻辑可知,是求解一个数独,同时只要求其中的一个解

尝试放到网上直接求解,直接出来了

image-20240223163033222

1
2548656723194376198518245679931748649825721856943342156965374812

image-20240223163250217

这里我把输入改成十进制了

之后更新一个碰撞md5的方法

Sweet_Tofu

动调直接找检查数组,判断时要异或0x66

1
2
3
4
5
6
7
8
9
10
from prism import *
a = [0x00, 0x0A, 0x07, 0x01, 0x1D, 0x3F, 0x09, 0x13,
0x39, 0x07, 0x08, 0x02, 0x39, 0x2F, 0x39, 0x21,
0x09, 0x02, 0x41, 0x15, 0x39, 0x25, 0x14, 0x03,
0x07, 0x12, 0x0F, 0x09, 0x08, 0x47, 0x22, 0x09,
0x08, 0x41, 0x12, 0x39, 0x04, 0x03, 0x39, 0x15,
0x03, 0x14, 0x0F, 0x09, 0x13, 0x15, 0x47, 0x1B]

pxor(a,0x66)
#flag{You_and_I_God's_Creation!Don't_be_serious!}

artbreaker

ida打开后发现不能反编译也不能看流程,修改最大节点数量然后跳到流程图

结果

image-20240223164916217

居然用流程图把flag画出来了,看未定义变量的wp,说是用了**Artfuscator**这个来画的画

1
flag{Rabbit_falls_into_rabbit_hole}

BattleCity

游戏题,看样子是要通关,在assets中可以看到levels.ldtk文件,用文本文件编辑器打开可以发现里面有各种东西的属性,于是我把每一关的敌人只留了一个,然后把基地的长宽改成0,打完4关,assets里出现了win.png,是二维码,扫码就出来了

closeme

提示是要用正常方式结束程序

由于程序一直弹出窗口,因此需要通过messagebox函数的交叉引用找到主函数。或者通过动态调试找到位置。

然后动调分析一下,发现是一个循环+一些东西,要结束的话只能先break,在205行有唯一的break。同时后面有一个goto,让执行流又回到label_4了,这就

(看了wp)发现下面有一个xor加密的hint,解密得到

1
2
3
4
5
6
from prism import *
a=[0x23, 0x11, 0x0D, 0x1B, 0x13, 0x4B, 0x18, 0x04, 0x03, 0x0A, 0x50, 0x08, 0x1D, 0x06, 0x54, 0x16, 0x1A, 0x18, 0x0B, 0x1C, 0x5A, 0x0F, 0x14, 0x18, 0x5E, 0x12, 0xE5, 0xF2, 0xF1, 0xE2, 0xE3, 0xE0, 0xE4, 0xE8, 0xF0, 0xA9, 0xE8, 0xF2, 0xAC, 0xEE, 0xE2, 0xE6, 0xF3, 0xFA, 0xB2, 0xF3, 0xCD, 0xF0, 0xE5, 0xF7, 0xB8, 0xF6, 0xE8, 0xBB, 0xFC, 0xD3, 0xF1, 0xFF, 0x8C, 0x81, 0xCB, 0xD7, 0x84, 0xD2, 0xCF, 0xCB, 0xC4, 0x89, 0xC8, 0xCE, 0x8C, 0xDE, 0xDA, 0xC0, 0xC2, 0xD4, 0xD6, 0x9D, 0x94, 0xFF, 0xC3, 0xC4, 0xCC, 0x99, 0xD9, 0xD3, 0xD3, 0xD2, 0xCD, 0xDA, 0xE0, 0x98, 0xA7, 0xB0, 0xEB, 0x8B, 0xA9, 0xEF, 0xF9, 0xE6, 0xFA, 0xE2, 0xEC, 0xA4, 0xA0, 0xEF, 0xB1, 0xF1, 0xB1, 0xB6, 0xA6, 0xA1, 0xB7, 0xBE, 0xB6, 0xF9, 0xB5, 0xA9, 0xB8, 0xB8, 0xAC, 0xFF, 0x97, 0x89, 0x8B, 0x80, 0x8C, 0xC5, 0x8F, 0x94, 0xC8, 0x9D, 0x82, 0x8E, 0xCC, 0x8B, 0x82, 0x8E, 0x97, 0xDD, 0xD2, 0x80, 0x81, 0x96, 0x9E, 0xD7, 0x99, 0x8A, 0xDA, 0xCB, 0xCD, 0xCD, 0xCE, 0xCE,0x31, 0x31, 0x32, 0x2D, 0x24, 0x55, 0x6A, 0x62, 0x69, 0x7A, 0x6F, 0x2B, 0x7F, 0x78, 0x6C, 0x62, 0x79, 0x65, 0x32, 0x75, 0x78, 0x74, 0x71, 0x37, 0x6F, 0x71, 0x73, 0x78, 0x74, 0x3D, 0x6A, 0x77, 0x45, 0x01, 0x44, 0x4C, 0x56, 0x48, 0x47, 0x53, 0x08, 0x45, 0x43, 0x40, 0x49, 0x0D, 0x4E, 0x7C, 0x79, 0x72, 0x66, 0x75, 0x4F, 0x05, 0x07, 0x07, 0x08, 0x08, 0x0B, 0x0B, 0x0C, 0x40, 0x5E]
for i in range(len(a)):
a[i] ^= i+102
pl(a)
#Every time you close the messagebox by click `Yes` or `No`, it will be stored. Just choose Yes/No(1/0) in a certain order which is the flag, such as 01001100. Please submit flag which the format like `SICTF{01001100}`

那么根据上面的break,可以看出需要输入16次

但是要检测到按键按的是哪个

根据messageboxW:yes是6,no是7。查找后可以发现

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
if ( v2 == 5 * (v2 / 5) )
{
v63 = (const WCHAR *)&unk_140022B10;
v64 = (__int64)&unk_140022B3C;
LOWORD(Size) = 0;
LODWORD(v66) = 1;
sub_140003240(&v70, &v63);
lpWindowName = v71;
v63 = (const WCHAR *)&unk_140022B3C;
v64 = (__int64)&unk_140022B5D;
LOWORD(Size) = 0;
LODWORD(v66) = 1;
sub_140003240(lpCaption, &v63);
v73 = (unsigned __int64)lpCaption[1];
choose = MessageBoxW(0i64, lpWindowName, lpCaption[1], 4u);
if ( lpCaption[0] )
sub_1400038E0(v73, 2 * (__int64)lpCaption[0], 2i64);
if ( v70 )
sub_1400038E0(lpWindowName, 2i64 * (_QWORD)v70, 2i64);
this_choose_ans = 1;
if ( choose != 6 ) // 否
{
if ( choose != 7 ) // 否,不可能进入
{
v63 = (const WCHAR *)&off_140022B98;
v64 = 1i64;
Size = (size_t)&off_140022888;
v66 = 0i64;
sub_1400214A0(&v63, &off_140022BA8);
}
this_choose_ans = 0;
}
cont2 = cont; // 是
if ( cont == v59 ) // ?
{
sub_140003820(&v59);
cont2 = cont;
}
*(_BYTE *)(save_place + cont2) = this_choose_ans;
if ( ++cont == 16 )
break;
}

修正this_choose_ans的值,是==1,否==0,最后存在save_place中

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
sp0 = *(unsigned __int8 *)save_place;
if ( sp0 > 1 )
goto LABEL_3;
sp1 = *(unsigned __int8 *)(save_place + 1);
if ( sp1 > 1 )
goto LABEL_3;
sp2 = *(unsigned __int8 *)(save_place + 2);
if ( sp2 > 1 )
goto LABEL_3;
sp3 = *(unsigned __int8 *)(save_place + 3);
if ( sp3 > 1 )
goto LABEL_3;
sp4 = *(unsigned __int8 *)(save_place + 4);
if ( sp4 > 1 )
goto LABEL_3;
sp5 = *(unsigned __int8 *)(save_place + 5);
if ( sp5 > 1 )
goto LABEL_3;
sp6 = *(unsigned __int8 *)(save_place + 6);
if ( sp6 > 1 )
goto LABEL_3;
sp7 = *(unsigned __int8 *)(save_place + 7);
if ( sp7 > 1 )
goto LABEL_3;
sp8 = *(unsigned __int8 *)(save_place + 8);
if ( sp8 > 1 )
goto LABEL_3;
sp9 = *(unsigned __int8 *)(save_place + 9);
if ( sp9 > 1 )
goto LABEL_3;
sp10 = (LPCWSTR)*(unsigned __int8 *)(save_place + 10);
if ( (unsigned __int64)sp10 > 1 )
goto LABEL_3;
sp11 = *(unsigned __int8 *)(save_place + 11);
if ( sp11 > 1 )
goto LABEL_3;
sp12 = *(unsigned __int8 *)(save_place + 12);
if ( sp12 > 1 )
goto LABEL_3;
sp13 = *(unsigned __int8 *)(save_place + 13);
if ( sp13 > 1 )
goto LABEL_3;
sp14 = *(unsigned __int8 *)(save_place + 14);
if ( sp14 > 1 )
goto LABEL_3;
sp15 = *(unsigned __int8 *)(save_place + 15);
if ( sp15 > 1 )
goto LABEL_3;
final = sp0
+ 10
* (sp1
+ 10
* (sp2
+ 10
* (sp3
+ 10
* (sp4
+ 10
* (sp5
+ 10
* (sp6
+ 10
* (sp7
+ 10
* (sp8
+ 10 * (sp9 + 10i64 * (_QWORD)&sp10[50000 * sp15 + 5000 * sp14 + 500 * sp13 + 50 * sp12 + 5 * sp11])))))))));

经过这里后label_4会到第一个while(1)的位置最后,那只能继续分析final,它储存了所有输入内容计算后的最终值,由于先输入sp0,然后1。。。说明高位后输入,低位先输入

1
if ( (unsigned __int8)sub_14001F580(&final, &zero) )

并且由于提示的按一定方式点击,说明肯定有检测的存在

在label_3的位置:

1
2
3
4
5
6
if ( (what & 0xFFFF0000) != -1443823616 )
{
LABEL_3:
cont = 0i64;
goto LABEL_4;
}

只要等于就可以往后走

反异或一下what的值等于1443758080/560E 0000

动态调试,输入测试,发现sp0到15就是放入的值1010101,唯一奇怪的是sp13和sp11是特定的值0x800和0x90000000

继续看what的生成看不出来,试试代数据

1
2
3
4
5
6
7
1111 1111 0000 0000 》           1111 1111 0000 0000 0000 0000

0000 1111 1111 1111 》 0011 1111 1111 1100 0000 0000 0000 0000

0000 0000 1111 1111 》 0011 1111 1100 0000 0000 0000 0000 0000

1001 1001 1001 1001 》 0110 0110 0110 0110 0000 0000 0000 0000

根据第一组数据感觉是倒序排入,上面final也是倒序的。倒序一下

1
2
3
4
5
6
7
0000 0000 1111 1111 》           1111 1111 0000 0000 0000 0000

1111 1111 1111 0000 》 0011 1111 1111 1100 0000 0000 0000 0000

1111 1111 0000 0000 》 0011 1111 1100 0000 0000 0000 0000 0000

1001 1001 1001 1001 》 0110 0110 0110 0110 0000 0000 0000 0000

第四个看得很明显如果不看后4位是最后两个变到了前面

试一试最后的what是不是这样变的

1
2
3
4
560e0000:
0101011000001110
0101100000111001
0101 1000 0011 1001

不对?重新看了一遍发现是与运算,不是异或,那就是说最后的A9F1就是结果的末值

1
2
3
4
5
1010 1001 1111 0001
1010 0111 1100 0110
0110 0011 1110 0101
得到
SICTF{0110001111100101}

这道题告诉我看到这种抽象的题要多调试,静下来分析QAQ

virus-nlys1s[待补充]

居然是病毒样本,没玩过,之后再说


CRYPTO

vigenere

从名字可以看出是维吉尼亚密码

第二段可以明显看出有一段是SICTF{},进入

https://www.dcode.fr/vigenere-cipher这个网站,输入密文和已知的明文

得key:SAATF和明文

SuperbRSA

这个是变体的共模攻击

通过e1,e2求gcd,最后的结果要取gcd的根

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

e1=55
e2=200
n= 19006830358118902392432453595802675566730850352890246995920642811967821259388009049803513102750594524106471709641202019832682438027312468849299985832675191795417160553379580813410722359089872519372049229233732405993062464286888889084640878784209014165871696882564834896322508054231777967011195636564463806270998326936161449009988434249178477100127347406759932149010712091376183710135615375272671888541233275415737155953323133439644529709898791881795186775830217884663044495979067807418758455237701315019683802437323177125493076113419739827430282311018083976114158159925450746712064639569301925672742186294237113199023
c1= 276245243658976720066605903875366763552720328374098965164676247771817997950424168480909517684516498439306387133611184795758628248588201187138612090081389226321683486308199743311842513053259894661221013008371261704678716150646764446208833447643781574516045641493770778735363586857160147826684394417412837449465273160781074676966630398315417741542529612480836572205781076576325382832502694868883931680720558621770570349864399879523171995953720198118660355479626037129047327185224203109006251809257919143284157354935005710902589809259500117996982503679601132486140677013625335552533104471327456798955341220640782369529
c2= 11734019659226247713821792108026989060106712358397514827024912309860741729438494689480531875833287268454669859568719053896346471360750027952226633173559594064466850413737504267807599435679616522026241111887294138123201104718849744300769676961585732810579953221056338076885840743126397063074940281522137794340822594577352361616598702143477379145284687427705913831885493512616944504612474278405909277188118896882441812469679494459216431405139478548192152811441169176134750079073317011232934250365454908280676079801770043968006983848495835089055956722848080915898151352242215210071011331098761828031786300276771001839021

g,x,y=gmpy2.gcdext(e1,e2)

m=pow(c1,x,n)*pow(c2,y,n)%n
m=gmpy2.iroot(m,g)[0]
print(long_to_bytes(m))
#b'SICTF{S0_Great_RSA_Have_Y0u_Learned?}'

easyLattice[待补充]

感觉在考逆元和模的基本运算?但是没做出来悲伤。

翻wp发现是考格密码,按照VSCode配置sage教程 不用notebook直接运行+代码高亮+命令行输出_sage windows-CSDN博客安装好环境,(最后失败了,于是把库全放到自带的解释器里面)

没见过呀(TVT),看不懂,之后再说

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#sage
from Crypto.Util.number import *

h = 9848463356094730516607732957888686710609147955724620108704251779566910519170690198684628685762596232124613115691882688827918489297122319416081019121038443
p = 11403618200995593428747663693860532026261161211931726381922677499906885834766955987247477478421850280928508004160386000301268285541073474589048412962888947
T = 2^250

L = Matrix(ZZ,[[1,T*h],[0,T*p]])

f,g = L.LLL()[0]
f,g = abs(f),abs(g)

print(long_to_bytes(int(f)))
# SICTF{e3fea01c-18f3-4638-9544-9201393940a9}

大概是说
$$
h = (f^{-1}g) \mod p
$$

$$
g = fh+kp
$$

$$
\begin{pmatrix}
f & k \
\end{pmatrix}
\times
\begin{pmatrix}
1 & h \
0 & p
\end{pmatrix}

\begin{pmatrix}
f & g \
\end{pmatrix}
$$

gggcd[待补充]

这个第一次见到诶,好怪:同e,n不同m,$m_2=f(m_1)$

m2是m1的线性变换

然后已知c1,c2,n,e

查了查,原来这个叫相关消息攻击

通过求可能的g再求其gcd(g1,g2)得到m

看大佬们的wp,exp都是用sage写的,我安装好后也不能导入python,但是直接用sage自带的好像可以,不过不能导入Crypto.Util.number,我就先解出m再longtobytes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....: c2 = 205635624489021368248826364689528951802539834493392269547383991633413
....: 32272571882209784996486250189912121870946577915881638415484043534161071782
....: 38735899371291867878739806568899981073418921390469351451959495552246015176
....: 94795153230498219402854082280557713496709195875609525488767962526341049263
....: 67078177733076253
....: e = 65537
....: a = 233
....: b = 9527
....:
....: import binascii
....: def franklinReiter(n,e,c1,c2):
....: PR.<x> = PolynomialRing(Zmod(n))
....: g1 = (x)^e - c1
....: g2 = (233*x+9527)^e - c2
....:
....: def gcd(g1, g2):
....: while g2:
....: g1, g2 = g2, g1 % g2
....: return g1.monic()
....: return -gcd(g1, g2)[0]
....:
....: m=franklinReiter(n,e,c1,c2)
....: print((m))
11658736990073968144116409270602503966776095409763057826884617698882016691134900406351481309826095854973
1
2
print(long_to_bytes(11658736990073968144116409270602503966776095409763057826884617698882016691134900406351481309826095854973))
b'SICTF{45115fb2-84d6-4369-88c2-c8c3d72b4c55}'

签到,确信![待补充]

我不解,但我大受震撼

铜匠[待补充]

似乎这个是已知p的高位

但是转5进制之后似乎不能准确表示p的高位,难度是把n转5进制?

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
from Crypto.Util.number import *
import gmpy2
from tqdm import *

leak = "2011133132443111302000224204142244403203442000141102312242343143241244243020003333022112141220422134444214010012"
n = 85988668134257353631742597258304937106964673395852009846703777410474172989069717247424903079500594820235304351355706519069516847244761609583338251489134035212061654870087550317540291994559481862615812258493738064606592165529948648774081655902831715928483206013332330998262897765489820121129058926463847702821
e = 65537
c = 64708526479058278743788046708923650158905888858865427385501446781738669889375403360886995849554813207230509920789341593771929287415439407977283018525484281064769128358863513387658744063469874845446480637925790150835186431234289848506337341595817156444941964510251032210939739594241869190746437858135599624562

def five_to_ten(num):
temp = 0
i = 109
for j in reversed(num):
temp += int(j) * 5**i
i += 1
return temp

leak = five_to_ten(leak)
gift = leak >> 256

for i in trange(2^8):
ph = gift << 8
phigh = ph + i
phigh = phigh << 248
R.<x> = PolynomialRing(Zmod(n))
f = phigh + x
res = f.small_roots(X=2^248, beta=0.4, epsilon=0.01)
if res != []:
p = phigh + int(res[0])
q = n // p
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(f"i = {i}")
print(long_to_bytes(int(m)))
break

babyRSA[待补充]

easy_or_baby_RSA[待补充]

2024_New_Setback[待补充]


MISC

签到

略

geekchallenge

这个要连接一个地址,连接后是一个猜数字游戏,114位,一共5种字符,一开始尝试了很久不知道为什么错了,最后发现它延迟一次显示,上一次的结果出现在下一次在,那么解

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
import socket
import string

# 所有可见字符
visible_chars = string.printable[:-6]

# 创建一个socket对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接到服务器
s.connect(("yuanshen.life", 34757))

# 创建一个114位的列表,初始值为None
password = [None] * 114

# 保存上一次的字符
last_char = None

# 循环遍历所有可能的字符
for char in visible_chars:

if not all(v is None for v in password):
# 将guess设为password并将空位全部改为char
guess = ''.join([v if v is not None else char for v in password]) + '\n'
else:
# 否则,guess为114个相同的字符
guess = char * 114 + '\n'

# 发送字符串到服务器
s.send(guess.encode())

# 接收服务器的响应
response = s.recv(1024).decode()
print(guess)
print(response)
# 如果response中有'1',就把上一次的char放入password中的每一个返回的'1'的位置
if '1' in response and last_char is not None:
for i, bit in enumerate(response):
if i < len(password) and bit == '1'and password[i] is None:
password[i] = last_char

# 更新上一次的字符
last_char = char

print(''.join(filter(None, password)))

while True:
message = input("请输入你要发送的消息:\n")
message += '\n'
s.send(message.encode())
response = s.recv(1024).decode()
print(response)

# 关闭连接
s.close()
#SICTF{18e62b78-c753-407c-9b0f-aa386fb4d6fd}

New_year`s regret

给了一个压缩包,有秘密,但是说了格式:xxxxSICTF

那就掩码爆破:格式是????SICTF

出来是2024SICTF

解压压缩包得到一个task.png和output.txt,同时压缩包注释表示压缩包有额外数据,用010editor查看得:43637d135333

task.png是400x400的类似二维码的黑白图像,一行25个格

output.txt是一堆0101二进制串,22464个字符加一个换行符

那么很有可能要把output转为图片,但是并不知道要怎么转换。

然后这里的额外数据43637d135333实在想不出来是什么意思,看wp后才知道要反转之后from hex:351×64刚好22464

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from PIL import Image

def create_image_from_file(filename, width, height):
with open(filename, 'r') as file:
data = file.read().replace('\n', '')

img = Image.new('RGB', (width, height), "white")
pixels = img.load()

for i in range(0, len(data)):
row = i // width
col = i % width
if data[i] == '1':
pixels[col, row] = (0, 0, 0)
elif data[i] == '0':
pixels[col, row] = (255, 255, 255)

img.save('output.png')

create_image_from_file('output.txt',351,64)

output

得到一张五线谱,这个叫Music Sheet Cipher

通过网站:Music Sheet Cipher - Online Notes Decoder, Encoder, Translator (dcode.fr)

来解码

得到:PUTITALLTOGETHER/put_it_all_together

以zip形式打开task.png

发现有base64编码的字符,解码后好像还是base64,多试几次,最后发现35次的时候有PNG的标志,37次就不能继续了,把它输出成png,是一个二维码,扫码然后获得部分flag

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

with open('result.txt', 'r') as file:
data = file.readline().strip()

for _ in range(35):
data = base64.b64decode(data)

print(data)

with open('something.png','wb') as file:
file.write(data)
1
SICTF{Congratuation_to_you!

再查看task.png,二进制打开看有没有什么标志,除了50 4B 03 04还有一个PNG,复制PNG保存打开是一张武器表,根据提示:你知道这是几星吗想到要找武器星级

k

1
44664654464566654465645644544664654654644546445446646565444454544664654664544545646454544454466465465645644

结果是如上。四五六有三种变化,猜莫斯密码

1
..--.- ..-. --- ..- -. -.. ..--.- .- .-.. .-.. ..--.- - .... . ..--.- .--. .. . -.-. . ... ..--.- .- -. -..
1
_FOUND_ALL_THE_PIECES_AND

拼接flag

1
SICTF{Congratulation_to_you!_found_all_the_pieces_and_put_it_all_together}

WHOWHOWHO

又是有密码的压缩包,但是有提示:6位数小写密码,爆破:qweqwe

二号位置有空白字符,很明显是0宽隐写,网上找工具解密

1
2
3
U2FsdGVkX19uvldJ6CGUNff3B28QEdIjZqgUh98K+/0J16ELU8WVQydohw4P5+2M
jbhTLQHNOpcoOd7kSRgy8pwpovCmimdD8M0IbYUeXjNKYePL/WP4PCMaOJHAW3HR
b7IEoDDH1NYh3o5NwMmcFEqy1ujf72VgQIQkaeYFFFE=

base64,有三行,直接解密,解完发现是乱码,但是一开头说salted,加盐了

上网查时发现rabbit加密开头一定是U2FsdGVkX1,base64之后就是salted_所以尝试用这个解密,需要key才可以,根据txt文件中的谁是渣男,尝试:shumu

成功

1
GTAGAGCTAGTCCTT{GGGTCACGGTTC_GGGTCACGGTTC_GAACGGTTC_GTAGTG_GCTTCA_GTAGACGTGGCGGTG_GTAGACTCA_TATGACCGG_GCTCGGGCT}

这个是dna加密,好像没有直接解密的,但是有脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mapping = {
'AAA':'a','AAC':'b','AAG':'c','AAT':'d','ACA':'e','ACC':'f', 'ACG':'g','ACT':'h','AGA':'i','AGC':'j','AGG':'k','AGT':'l','ATA':'m','ATC':'n','ATG':'o','ATT':'p','CAA':'q','CAC':'r','CAG':'s','CAT':'t','CCA':'u','CCC':'v','CCG':'w','CCT':'x','CGA':'y','CGC':'z','CGG':'A','CGT':'B','CTA':'C','CTC':'D','CTG':'E','CTT':'F','GAA':'G','GAC':'H','GAG':'I','GAT':'J','GCA':'K','GCC':'L','GCG':'M','GCT':'N','GGA':'O','GGC':'P','GGG':'Q','GGT':'R','GTA':'S','GTC':'T','GTG':'U','GTT':'V','TAA':'W','TAC':'X','TAG':'Y','TAT':'Z','TCA':'1','TCC':'2','TCG':'3','TCT':'4','TGA':'5','TGC':'6','TGG':'7','TGT':'8','TTA':'9','TTC':'0','TTG':' ','TTT':'.'}

input= 'GTAGAGCTAGTCCTT{GGGTCACGGTTC_GGGTCACGGTTC_GAACGGTTC_GTAGTG_GCTTCA_GTAGACGTGGCGGTG_GTAGACTCA_TATGACCGG_GCTCGGGCT}'
final = ''

i=0
while i<len(input):
if input[i]=='_'or input[i]=='{' or input[i]=='}':
final+=input[i]
i+=1
else:
tmp = input[i:i+3]
final += mapping[tmp]
i+=3
print(final)
#SICTF{Q1A0_Q1A0_GA0_SU_N1_SHUMU_SH1_ZHA_NAN}

日志分析1

使用了windows自带的evtx浏览器和logparser

尝试查找注册或者登录:id4779

找到

1
日志分析1.evtx	1600	2020-07-22 10:52:19	2020-07-22 10:52:19	4779	8	Success Audit event	12551	The name for category 12551 in Source "Microsoft-Windows-Security-Auditing" cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer	Microsoft-Windows-Security-Auditing	attack$|ADOFLMB|0x12a334|RDP-Tcp#0|kali|192.168.222.200	WIN-WH8G5MDPHE5.ADoflmb.com	NULL	The description for Event ID 4779 in Source "Microsoft-Windows-Security-Auditing" cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer	NULL

这里找到attack$的用户名,ADOFLMB的用户域,下面的192.168.222.200是内网登录的ip,然后查找创建计划任务的id:

得到任务名称\callback,文件路径c:\windows\system32\windows_attack.exe

锁定这一天寻找其它内容就能找到就能找到用户组是Administrators

远程登录账户是WIN-WH8G5MDPHE5$

1
SICTF{192.168.222.200|attack$|Administrators|\callback|c:\windows\system32\windows_attack.exe|ADOFLMB\WIN-WH8G5MDPHE5$}

但是不对,结果远程登录账户就是attack$

在4769号内容2020/7/22/10:52:06

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
已请求 Kerberos 服务票证。

帐户信息:
帐户名: attack$@ADOFLMB.COM
帐户域: ADOFLMB.COM
登录 GUID: {7539ad21-0be8-8cb6-7406-054797c14d68}

服务信息:
服务名称: WIN-WH8G5MDPHE5$
服务 ID: S-1-5-21-867333373-202576419-2389709931-1000

网络信息:
客户端地址: ::1
客户端端口: 0

附加信息:
票证选项: 0x40810000
票证加密类型: 0x12
故障代码: 0x0
传递服务: -

每次请求访问资源(例如计算机或 Windows 服务)时生成此事件。服务名称表示请求访问的资源。

可以通过比较每个事件中的“登录 GUID”字段将此事件与 Windows 登录事件相关联。登录事件发生在被访问的计算机上,通常情况下,该计算机不是颁发服务票证的域控制器计算机。

票证选项、加密类型和故障代码是在 RFC 4120 中定义的。

第一行得到目标账户名,这个事件是生成凭证以访问资源的所以没问题?

1
SICTF{192.168.222.200|attack$|Administrators|\callback|c:\windows\system32\windows_attack.exe|ADOFLMB\attack$}

然而,任务名不加\,这个\表示它位于任务计划程序的根目录下,所以正确flag是

1
SICTF{192.168.222.200|attack$|Administrators|callback|c:\windows\system32\windows_attack.exe|ADOFLMB\attack$}

(所以说$表示隐藏为什么要加QAQ)

日志分析2[待补充]

神秘的流量[待补充]


FORENSICS

明明是社工却叫取证?

OSINT签到

直接放到谷歌识图,得出答案

红城湖公园位于海南省海口琼山区府城街道红城湖路北侧

1
SICTF{海南省_海口市_琼山区_红城湖公园}

这才是签到

谷歌识图得出地点是意大利的威尼斯,图片中是一个酒店,但是提示说不酒店,拍摄地点找没有空格的好像找不出来?

看对话jpg,是说穿过小巷,感觉很多啊。奇怪诶。

好吧,看了wp发现没有特殊字符是省略空格就可以,那拍摄地点是Gondola Danieli

穿过小道,我之前一直理解成往左边走,结果是往右??

不过提示了比例尺是20m,穷举也是可以的

1
SICTF{意大利_威尼斯_GondolaDanieli_ChiesadiSanZaccaria}

真的签到

显眼的是摩天轮

谷歌识图找到地点

1
SICTF{广东省_珠海市_斗门区_大信新都汇}

树木的压迫

百度识图只搜索红框部分

1
SICTF{四川省_达州市_通川区_凤凰大道376号_达州市体育中心}

签退

根据左下角车是右舵,去网上搜索地区

采用右舵,靠左行驶的国家主要是英联邦国家,也就是原来受英国的影响比较大的国家,较大的国家有英国、日本、印度、澳大利亚、南非,等三十多个国家和地区。

具体都包括:孟加拉、不丹、文莱、东帝汶、印度、印度尼西亚、日本、马来西亚、马尔代夫、尼泊尔、巴基斯坦、新加坡、斯里兰卡、泰国、中国香港地区和澳门地区、爱尔兰、塞浦路斯、马耳他、英国、博茨瓦纳、肯尼亚、莱索托、马拉维、毛里求斯、莫桑比克、纳米比亚、塞舌尔、南非、斯威士兰、坦桑尼亚、乌干达、赞比亚、津巴布韦、安提瓜和巴布达、巴哈马、巴巴多斯、格林纳达、圭亚那、牙买加、圣基茨和尼维斯、圣卢西亚、圣文森特和格林纳丁斯、苏里南、特立尼达和多巴哥、澳大利亚、斐济、基里巴斯、新西兰、巴布亚新几内亚、所罗门群岛、汤加、图瓦卢。

通过直接搜图,发现一个视频【超清南非】第一视角 开车从开普敦机场高速前往市中心 (1080P高清版) 2022.2_哔哩哔哩_bilibili

其中红绿灯一样,建筑也差不多,就猜是开普敦了

同时裁剪图片搜索右上角建筑,可以发现中间被涂掉的蜘蛛侠。那么地点就是这里了。

根据这个图片继续查找,发现这个建筑的另一边

Commercial property to rent in Cape Town City Centre - 63 Strand Street - P24-112975960 (property24.com)

得到附近地址
strand street

全景地图观察发现就是这里

1
SICTF{南非\_开普敦\_StrandSt_STEERS}