周报03

【君子坐而论道,少年起而行之。 ——烽火戏诸侯《剑来》】

TPCTF 2025 题目复现

(难度有点高,尽力尝试ing)

题目:nanonymous spam

题目要求找到匿名垃圾邮件的发送者,打开题目,可以看到留言板上有许多不同的昵称和垃圾信息:

同时,我们可以在下方发送信息,我们注意到网站已经给我们生成了一个昵称:

可以发现的是,如果使用不同的IP访问网站,所显示的昵称是不同的!

也就是说,所谓的匿名,实则是通过一个“算法”,将你的IP地址转化成看似不规律的字符串。

那么,如果我们能逆向出这个算法,就可以知道留言板上的信息发送者了!

然而,想要逆推出算法,我们一定需要大量不同的IP以及对应的匿名昵称来找寻对应关系。

这里借鉴一下0xFFF队的WP

我们可以通过 X-Real-IP 这个 HTTP 头来伪造 IP 地址。

并且也发现第一个 Spam 留言者昵称对应的 IP 地址正是 TPCT 这个 Flag 头的 ASCII 码,这证实了猜想。

那么我们先从 0.0.0.0 开始递增看一看是否能找到一些规律:

1
2
3
4
5
6
7
8

f = open("result.txt", "at")
for i in range(0, 512):
ip = i
a, b, c, d = ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff
ip_str = "%d.%d.%d.%d" % (a, b, c, d)
f.write(f"{str(i).zfill(3)} {get(ip_str)} {ip_str}\n")
f.close()

结果如下,注意到昵称的第 4-6 个字符每 103 个 IP 地址会有一个周期,进入下一个周期改变了第 1-3 个字符的内容,其余字符则保持不变:

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

000 WimNodSerPuc 0.0.0.0
001 WimTapSerPuc 0.0.0.1
002 WimLizSerPuc 0.0.0.2
...
102 WimGuoSerPuc 0.0.0.102
103 HetNodSerPuc 0.0.0.103
104 HetTapSerPuc 0.0.0.104
...
205 HetGuoSerPuc 0.0.0.205
206 FauNodSerPuc 0.0.0.206
207 FauTapSerPuc 0.0.0.207
...

那就继续探索下一个周期变化。这个周期很长,所以直到将范围拉到 520 之后才确定其周期长度为 513:

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

for i in range(0, 520):
ip = i * 103
# 其余代码同上

000 WimNodSerPuc 0.0.0.0
001 HetNodSerPuc 0.0.0.103
002 FauNodSerPuc 0.0.0.206
...
512 ButNodSerPuc 0.0.206.0
513 WimNodDeaPuc 0.0.206.103
514 HetNodDeaPuc 0.0.206.206
...

进一步探索下一个周期。下一个周期的长度为 313,但同时也注意到,在进入下一个周期后,四个部分的顺序也发生了变化:

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

for i in range(0, 320):
ip = i * 103 * 513
# 其余代码同上

000 WimNodSerPuc 0.0.0.0
001 WimNodDeaPuc 0.0.206.103
002 WimNodJacPuc 0.1.156.206
...
312 WimNodFomPuc 0.251.141.136
313 WimSerMazNod 0.252.91.239
314 WimDeaMazNod 0.253.42.86
...

先对之前三个周期的昵称部分进行了整理,发现它们互相没有交集,所以顺序的变化不影响对下一个周期的探索:

1
2
3
4

A = ['Nod', 'Tap', 'Liz', 'Mel', 'Fig', 'Rif', 'Rip', 'Pud', 'Foo', 'Haw', 'Wef', 'Kel', 'Gat', 'Hod', 'Mom', 'Lin', 'Fez', 'Rua', 'Fay', 'Pat', 'Ned', 'Taz', 'Sid', 'Mic', 'Nom', 'Hab', 'Rug', 'Men', 'Nok', 'Fun', 'Pox', 'Red', 'Jah', 'Tet', 'Hip', 'Tem', 'Bad', 'Mir', 'Taj', 'Maf', 'Rac', 'Zia', 'Hea', 'Fis', 'Dem', 'Bim', 'Gow', 'Hub', 'Job', 'Nex', 'Jas', 'Lie', 'Sim', 'Poc', 'Ran', 'Voa', 'Gig', 'Jes', 'Nie', 'Lal', 'Lek', 'Pen', 'Cos', 'Col', 'Nao', 'Mop', 'Bac', 'Cis', 'Mor', 'Vim', 'Ceo', 'Gic', 'Mii', 'Dep', 'Len', 'Few', 'Lob', 'Lea', 'Bec', 'Mui', 'Pec', 'Mab', 'Her', 'Tas', 'Tui', 'Kun', 'Vic', 'Too', 'Woe', 'Uav', 'Dam', 'Jin', 'Kaz', 'Yew', 'Cid', 'Jaw', 'Hay', 'Gib', 'Mis', 'Til', 'Six', 'Bot', 'Guo']
B = ['Wim', 'Het', 'Fau', 'Ria', 'Dio', 'God', 'Man', 'Lim', 'Fap', 'Bar', 'Sot', 'Uae', 'Faq', 'Gum', 'Doe', 'Kay', 'Vol', 'Bic', 'Ren', 'Sox', 'Ral', 'Pii', 'Fol', 'Noo', 'Wes', 'Law', 'Pic', 'Zig', 'Ric', 'Tad', 'Pav', 'Loo', 'Tea', 'Koh', 'Fia', 'Rep', 'Soa', 'Gog', 'Rim', 'Nec', 'Jun', 'Sus', 'Roh', 'Sac', 'Diy', 'Gin', 'Gul', 'Via', 'Tec', 'Mah', 'Rus', 'Cal', 'Wat', 'Mes', 'Pam', 'Sav', 'Luz', 'Lac', 'Jud', 'Lop', 'Tub', 'Lia', 'Kip', 'Nau', 'Loa', 'Roa', 'Dos', 'Nor', 'Jaz', 'Fim', 'Boo', 'Pad', 'Duo', 'Min', 'Vis', 'Hux', 'Cue', 'Soc', 'Caw', 'Rig', 'Wod', 'Pag', 'Tak', 'Cag', 'Coe', 'Lev', 'Ted', 'Vax', 'Peo', 'Uic', 'Cus', 'Huh', 'Rub', 'Gia', 'Raf', 'Bed', 'Pei', 'Sig', 'Pur', 'Qin', 'Dai', 'Deb', 'Pof', 'Neg', 'Tol', 'Lux', 'Jus', 'Uah', 'Que', 'Noe', 'Lov', 'Zee', 'Con', 'Fey', 'Soi', 'Tex', 'Pin', 'Kap', 'Sal', 'Luo', 'Tim', 'Mid', 'Daw', 'Had', 'Gam', 'Jul', 'Jie', 'Wol', 'Mon', 'Roc', 'Rel', 'Bas', 'Nou', 'Reo', 'Mar', 'Dao', 'Niu', 'Kev', 'Dee', 'Wip', 'Coc', 'Fes', 'Rat', 'Dig', 'Teu', 'Mob', 'Mae', 'Car', 'Tux', 'Dew', 'Xue', 'Poi', 'Sit', 'Xin', 'Per', 'Mos', 'Top', 'Gab', 'Yin', 'Loi', 'Jay', 'Moi', 'Yeo', 'Day', 'Dic', 'Haq', 'Dak', 'Mer', 'Wii', 'Pix', 'Fag', 'Dog', 'Por', 'Nib', 'Hog', 'Huw', 'Voc', 'Hob', 'Zep', 'Neo', 'Com', 'Seo', 'Cur', 'Mow', 'Reb', 'Jim', 'Noc', 'Big', 'Fin', 'Sek', 'Fav', 'Niv', 'Pom', 'Pes', 'Ker', 'Yao', 'Coq', 'Tif', 'Gem', 'Cel', 'Zit', 'Toc', 'Jet', 'Vow', 'Lon', 'Rev', 'Joi', 'Jem', 'Wad', 'Bom', 'Tar', 'Pua', 'Rao', 'Bio', 'For', 'Dec', 'Win', 'See', 'Pup', 'Mea', 'Fam', 'Muh', 'Doo', 'Moh', 'Sam', 'Maw', 'Tog', 'Moe', 'Tin', 'Hur', 'Won', 'Lox', 'Poa', 'Dun', 'Run', 'Bil', 'Vip', 'Viv', 'Del', 'Nae', 'Zip', 'Roo', 'Sum', 'Leh', 'Lam', 'Yoo', 'Yip', 'Tow', 'Pil', 'Nab', 'Goi', 'Gar', 'Qua', 'Cor', 'Hav', 'Let', 'Ree', 'Set', 'Lee', 'Cef', 'Jam', 'Fal', 'Daa', 'Put', 'Num', 'Vod', 'Tis', 'Cad', 'Mot', 'Rit', 'Lex', 'Nav', 'Sia', 'Lip', 'Nox', 'Raj', 'Pie', 'Hel', 'Bam', 'Fed', 'Los', 'Fax', 'Neh', 'Jag', 'Sec', 'Jap', 'Sun', 'Cea', 'Jug', 'Sis', 'Cut', 'Fit', 'Fox', 'Bum', 'Joh', 'Lag', 'Fic', 'Sae', 'Gaz', 'Yuh', 'Hee', 'Fae', 'Caf', 'Nag', 'Bay', 'Ray', 'Log', 'Dim', 'Bag', 'Gap', 'San', 'Sup', 'Kuo', 'Wav', 'Suh', 'Kal', 'Tom', 'Ret', 'Seb', 'Wil', 'Jen', 'Haz', 'Cum', 'Xiv', 'Pon', 'Cod', 'Kit', 'Biz', 'Gag', 'Fen', 'Leg', 'Uid', 'Bod', 'Peg', 'Fur', 'Pip', 'Vid', 'Ter', 'Mol', 'Yor', 'Tek', 'Koo', 'Sui', 'Gis', 'Cia', 'Jig', 'Nad', 'Sin', 'Wop', 'Hou', 'Xii', 'Mim', 'Naa', 'Nia', 'Fai', 'Cat', 'Mio', 'Vee', 'Sew', 'Pal', 'Bub', 'Lis', 'Cac', 'Bid', 'Pah', 'Dip', 'Goy', 'Rum', 'Hoc', 'Viz', 'Fog', 'Tax', 'Kin', 'Req', 'Kik', 'Coa', 'Meh', 'Mum', 'Lap', 'Mov', 'Pir', 'Bop', 'Der', 'Dag', 'Lei', 'Jit', 'Tod', 'Far', 'Tig', 'Tae', 'Ten', 'Toe', 'Sep', 'Mac', 'Hua', 'Vik', 'Piu', 'Rar', 'Hut', 'New', 'Pap', 'Hid', 'Xia', 'Hug', 'Rox', 'Rey', 'Meg', 'Zak', 'Uas', 'Dug', 'Bes', 'Ton', 'Lad', 'Hus', 'Lew', 'Jiu', 'Pub', 'Buy', 'Bet', 'Nog', 'Yak', 'Bau', 'Qol', 'Yet', 'Dor', 'Buh', 'Baz', 'Kat', 'Fei', 'Kon', 'Nuh', 'Noa', 'Cap', 'Cil', 'Tan', 'Jed', 'Dur', 'Bol', 'Sux', 'Gov', 'Dev', 'Teh', 'Bob', 'Bal', 'Pep', 'Hah', 'Res', 'Cai', 'Gas', 'Qiu', 'Wiz', 'Pis', 'Heh', 'Dil', 'Yer', 'Gon', 'Nis', 'Fiu', 'Ber', 'Gan', 'Bak', 'Fud', 'Cog', 'Zim', 'Doa', 'Bos', 'Hen', 'Hes', 'Dub', 'Web', 'Lol', 'Zoo', 'Vag', 'Lep', 'Vin', 'Cep', 'Sow', 'Naw', 'Mee', 'Vir', 'Jae', 'Lic', 'Gah', 'Wax', 'Zap', 'Bur', 'Civ', 'Tag', 'Led', 'Boe', 'Cin', 'You', 'Daf', 'Beg', 'Xan', 'Wix', 'Nun', 'Yap', 'Bai', 'Cox', 'Sur', 'Fet', 'Moj', 'Lau', 'Dis', 'Mat', 'Rid', 'Mal', 'Ris', 'Uis', 'Hib', 'Vie', 'But']
C = ['Ser', 'Dea', 'Jac', 'Way', 'Cio', 'Tie', 'Tun', 'Goa', 'Sap', 'Fan', 'Jor', 'Pit', 'Gor', 'Son', 'Mun', 'Dan', 'Veg', 'Wel', 'Sev', 'Jeb', 'Gio', 'Ceu', 'Bib', 'Cif', 'Bug', 'Zan', 'Mec', 'Rob', 'Lao', 'Hew', 'Quo', 'Hor', 'Foe', 'Mak', 'Hol', 'Fil', 'Cam', 'Nur', 'Vet', 'Yea', 'Yup', 'Lot', 'Jab', 'Goo', 'Soy', 'Pay', 'Hoe', 'Dud', 'Qos', 'Boa', 'Ceb', 'Lug', 'Nic', 'Rai', 'Nap', 'Sem', 'Rue', 'Bah', 'Sez', 'Jib', 'Ual', 'Mus', 'Cip', 'Cir', 'Yan', 'Div', 'Bor', 'War', 'Don', 'Tug', 'Tuk', 'Maj', 'Hae', 'Rui', 'Git', 'Gil', 'Lab', 'Med', 'Mag', 'Dui', 'Ruv', 'Raw', 'Sol', 'Foy', 'Sib', 'Sub', 'Moz', 'Ras', 'Mil', 'Rem', 'Nix', 'Dom', 'Ban', 'Zeb', 'Woo', 'Pus', 'Mau', 'Boi', 'Ped', 'Kee', 'Pop', 'Mix', 'Wai', 'Gun', 'Ley', 'Cee', 'Bok', 'Fao', 'Sul', 'Zac', 'Siu', 'Jan', 'Sai', 'Ged', 'Pau', 'Cop', 'Les', 'Suu', 'Dir', 'Var', 'Wap', 'Tai', 'Wah', 'Rei', 'Pas', 'Bat', 'Cas', 'Fad', 'Joe', 'Nir', 'Fem', 'Hai', 'Tal', 'Wea', 'Rok', 'Hoa', 'Goh', 'Hof', 'Nos', 'Roy', 'Nem', 'Bel', 'Yui', 'Wor', 'Neb', 'Tot', 'Luv', 'Yun', 'Lil', 'Doc', 'Lai', 'Hem', 'Kew', 'Lay', 'Nik', 'Gus', 'Hoh', 'Fix', 'Cup', 'Fer', 'Deo', 'Coy', 'Jer', 'Luc', 'Gif', 'Cou', 'Dob', 'Dow', 'Hum', 'Hom', 'Nan', 'Dot', 'Den', 'Yeh', 'Ces', 'Jak', 'Nei', 'Rag', 'Dar', 'Pun', 'Dex', 'Gee', 'Nes', 'Mit', 'Fos', 'Sed', 'Pac', 'Cic', 'Toi', 'Raz', 'Tok', 'Did', 'Rik', 'Hit', 'Kam', 'Hiv', 'Jut', 'Tee', 'Pod', 'Gir', 'Sax', 'Hat', 'Dab', 'Nai', 'Jez', 'Was', 'Bon', 'Kid', 'Him', 'Tia', 'Bin', 'Wep', 'Dup', 'Yue', 'Maa', 'Hao', 'Suv', 'Ken', 'Mod', 'Kan', 'Moc', 'Cow', 'Sex', 'Ben', 'Deg', 'Gaf', 'Yaw', 'Luk', 'Faa', 'Bow', 'Ror', 'Bee', 'Cob', 'Loy', 'Row', 'Det', 'Nut', 'Rah', 'Coi', 'Rap', 'Def', 'Hie', 'Tic', 'Wis', 'Mew', 'Dav', 'Sir', 'Zoe', 'Zin', 'Uac', 'Rab', 'Yen', 'Sip', 'Nip', 'Bir', 'Pak', 'Kar', 'Gen', 'Kea', 'Sor', 'Lod', 'Fas', 'Sif', 'Zag', 'Rea', 'Wed', 'Vex', 'Lem', 'Sob', 'Sue', 'Lar', 'Rav', 'Sou', 'Bev', 'Kek', 'Kol', 'Rae', 'Map', 'Dah', 'Pee', 'Tam', 'Loc', 'Boc', 'Coz', 'Ful', 'Paz', 'Hop', 'Bui', 'Ref', 'Coo', 'Rez', 'Seq', 'Lou', 'Hon', 'Leo', 'Bis', 'Dia', 'Hui', 'Mai', 'Pez', 'Boy', 'Rog', 'Dac', 'Tut', 'Rut', 'Cuz', 'Now', 'Nii', 'Yas', 'Doj', 'Saw', 'Bex', 'Fom']

那就继续:

1
2
3
4
5
6
7

i, ip = 0, 0
while ip < 256 ** 4:
a, b, c, d = ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff
ip_str = "%d.%d.%d.%d" % (a, b, c, d)
f.write(f"{str(i).zfill(3)} {get(ip_str)} {ip_str}\n")
i, ip = i + 1, ip + 103 * 513 * 313

然后意识到这应该是最后一环了,只需要把这个周期的昵称部分整理出来就可以了:

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

D, exists = [], set(A + B + C)
i, ip = 0, 0
while ip < 256 ** 4:
a, b, c, d = ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff
ip_str = "%d.%d.%d.%d" % (a, b, c, d)
nickname = get(ip_str)
parts = [nickname[j:j+3] for j in range(0, len(nickname), 3)]
D.extend([k for k in parts if k not in exists])
i, ip = i + 1, ip + 103 * 513 * 313
print(D)

D = ['Puc', 'Maz', 'Doh', 'Hun', 'Cud', 'Vit', 'Wer', 'Hag', 'Din', 'Feb', 'Gui', 'Rak', 'Vac', 'Kim', 'Pol', 'Som', 'Saa', 'Hac', 'Xie', 'Ses', 'Van', 'Nef', 'Mia', 'Tab', 'Pid', 'Ver', 'Cay', 'Jog', 'Jar', 'Lan', 'Hex', 'Soe', 'Lid', 'Fip', 'Wet', 'Ner', 'Dey', 'May', 'Dua', 'Dez', 'Gut', 'Sag', 'Kor', 'Yon', 'Haa', 'Par', 'Fat', 'Vel', 'Yum', 'Wac', 'Poe', 'Yes', 'Rex', 'Gop', 'Cit', 'Val', 'Xix', 'Bit', 'Mig', 'Mib', 'Gaa', 'Sat', 'Mex', 'Geo', 'Doi', 'Mou', 'Dol', 'Joy', 'Caa', 'Dix', 'Nat', 'Boj', 'Mad', 'Pew', 'Nev', 'Sas', 'Rin', 'Dal', 'Joo', 'Vii', 'Tid', 'Hap', 'Sea', 'Cae', 'Cab', 'Nea', 'Wan', 'Mem', 'Nam', 'Mao', 'Pov', 'Pio', 'Bey', 'Vas', 'Jee', 'Not', 'Lat', 'Sud', 'Bog', 'Hue', 'Rio', 'Got', 'Liu', 'Lax', 'Fec', 'Duc', 'Rec', 'Mas', 'Cig', 'Vox', 'Rov', 'Pow', 'Sil', 'Gac', 'Pet', 'Yay', 'Sad', 'Ram', 'Box', 'Wag', 'Nin', 'Lib', 'Tou', 'Dae', 'Tau', 'Teo', 'Sod', 'Hoy', 'Tip', 'Cer', 'Wee', 'Nov', 'Keg', 'Nit', 'Wok', 'Hin', 'Tue', 'Ron', 'Roi', 'Vos', 'Sao', 'Kia', 'Tix', 'Mip', 'Cub', 'Nah', 'Hot', 'Wic', 'Yar', 'Sic', 'Sar', 'Kok', 'Fee', 'Yuk', 'Hoo', 'Hei', 'Dap', 'Cen', 'Las', 'Guy', 'Jon', 'His', 'Moo', 'Roz', 'Fac', 'Fir', 'Ham', 'Rad', 'Foi', 'Sof', 'Poo', 'Toa', 'Kos', 'Sei', 'Dof', 'Get', 'Bap', 'Kes', 'Die', 'Dad', 'Pea', 'Nus', 'Tit', 'Ros', 'Nay', 'Moa', 'Zen', 'Mam', 'Heb', 'Fab', 'Rib', 'Cao', 'Hey', 'Wot', 'Soo', 'Kai', 'Cem', 'Rom', 'Uaw', 'Zed', 'Noi', 'Sab', 'Tes', 'Gob', 'Jax', 'Nob', 'Bao', 'Tos', 'Tor', 'Mep', 'Pan', 'Har', 'Guv', 'Foa', 'Nih', 'Cim', 'Pig', 'Jot', 'Sop', 'Duh', 'Jia', 'Nil', 'Fib', 'Kei', 'Gad', 'Toy', 'Pim', 'Gel', 'Cet', 'Hal', 'Wen', 'Yah', 'Nup', 'Jai', 'Paw', 'Pos', 'Qed', 'Tel', 'Gay', 'Liv', 'Bus', 'Fop', 'Pia', 'Miu', 'Ked', 'Fea', 'Fob', 'Sel', 'Miz', 'Lor', 'Tay', 'Pot', 'Tac', 'Wei', 'Mug', 'Dat', 'Wal', 'How', 'Yow', 'Pax']

那么就可以直接写解码将那些 Spam 留言者的昵称转换回 IP 地址,进一步解出 Flag 了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

targets = ["VicCouNeaGas", "DemHohBojWod", "PowFitGuoRut", "VetTasBesDae", "FasLiuTasJoi", "DevRecWoeDia", "BogHubSorHad", "BagLibYupSix", "MowPetBecZan", "LonRecRipLuk", "KarYapTajGot", "TiaLiuFayDic", "VizDivCitBot", "LeaLatReaSac", "FasLiuVicToc", "KunSadMerMun", "LemLiuGuoReq"]

la, lb, lc, ld = len(A), len(B), len(C), len(D)
for i in targets:
for j in [i[k:k+3] for k in range(0, len(i), 3)]:
if j in A: a = A.index(j)
elif j in B: b = B.index(j)
elif j in C: c = C.index(j)
elif j in D: d = D.index(j)
else: assert False
ip = d * (la*lb*lc) + c * (la*lb) + b * la + a
ip_part = [ip >> 24 & 0xFF, ip >> 16 & 0xFF, ip >> 8 & 0xFF, ip & 0xFF]
print(''.join(map(chr, ip_part)), end='')
print()

流量分析专题练习(NSSCTF)

(源自NSSCTF的流量分析题)

题目:[陇剑杯 2021]webshell(问2)

题目要求找到日志文件的绝对路径:

因为是日志文件,我们可以直接筛选.log文件:

在后面的流量中找到了日志文件:

但题目要求提交绝对路径,此时可通过已经查看分析的流量包中发现该网站系统为Linux系统,由此猜测默认目录为/var/www/html。也可以继续查看后续流量包,其中存在命令执行pwd,查看http流,可以准确的得到网站目录为/var/www/html

/var/www/html/data/Runtime/Logs/Home/21_08_07.log

题目:[CISCN 2023 初赛]被加密的生产流量

这是一道工业生产流量:(不禁想起了强网线下赛的流量分析题)

大部分是modbus和TCP流量包。

针对modbus协议分析,有以下脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import pyshark
def get_code():
captures = pyshark.FileCapture("modbus.pcap")
func_codes = {}
for c in captures:
for pkt in c:
if pkt.layer_name == "modbus":
func_code = int(pkt.func_code)
if func_code in func_codes:
func_codes[func_code] += 1
else:
func_codes[func_code] = 1
print(func_codes)
if __name__ == '__main__':
get_code()

运行脚本,可以分析流量包中Modbus/TCP的协议功能码,功能码主要有以下几种:

运行代码:

功能码为6(代表预置单个寄存器)的modbus协议数据包有16个,很可疑,于是我们使用wireshark过滤:

1
modbus.func_code == 6 && modbus.request_frame

追踪流,在TCP流中发现base32编码:

1
MMYWMX3GNEYWOXZRGAYDA=

解码得到flag:

题目:[LitCTF 2023]easy_shark

  • 题目描述:卧底小帅在潜伏期间截获了一段非常可疑的流量,为了里面的内容不被泄露出去,小帅将flag进行了加密,你能成功发现犯罪团伙的秘密,并拯救小帅吗?flag格式:NSSCTF{flag_木马连接的key}
  • 出题人:王八七七
    flag以NSSCTF{}形式提交

依旧是流量分析。

然而,刚下载的附件压缩包就被加密了,用010 Editor看看:

发现是伪加密,进行修复:

打开流量包,筛选http

可以发现第2个流中黑客上传了webshell

同时,在最后一个流中,发现了一个一元二次方程和加密的flag:

方程的解为17和77,这应该是两个key,在常见的古典密码中,是仿射密码的可能性较大,我们使用随波逐流工具进行解密:

buuCTF misc做题记录

题目:Mysterious

一道逆向题(居然塞到misc里面)

题目是一个exe程序,打开提示输入密码:

程序放到exeinfo检查,发现为32位程序,无壳:

我们通过IDA进行静态分析:

可以看到,非常明显的WinMain主函数(一般的win32程序就是WinMain作为主函数)

进入函数,对其反汇编

这里有一个DialogBoxParamA函数

详解:https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-dialogboxparama

通过以上对DialogBoxParamA函数的描述,我们知道这是一个对话框函数,其中DialogFunc是指向对话框过程的指针,这个对话框过程便是一个回调函数,双击函数查看代码:

这里是一个间接调用。。

接下来分析这个回调函数:

要满足if函数输出flag,

所以密码是122xyz,输入密码得到flag:

题目:zip

打开题目,一堆堆压缩包

每个压缩包里只有4bytes大小,于是可以想到是crc爆破:

有以下脚本:

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
import zipfile
import string
import binascii

def CrackCrc(crc):
for i in dic:
for j in dic:
for k in dic:
for h in dic:
s = i + j + k + h
if crc == (binascii.crc32(s.encode())):
f.write(s)
return

def CrackZip():
for i in range(0,68):
file = 'out'+str(i)+'.zip'
crc = zipfile.ZipFile(file,'r').getinfo('data.txt').CRC
CrackCrc(crc)

dic = string.ascii_letters + string.digits + '+/='

f = open('out.txt','w')
CrackZip()
print("CRC32碰撞完成")
f.close

运行后,得到的结果是一串base64:

1
z5BzAAANAAAAAAAAAKo+egCAIwBJAAAAVAAAAAKGNKv+a2MdSR0zAwABAAAAQ01UCRUUy91BT5UkSNPoj5hFEVFBRvefHSBCfG0ruGnKnygsMyj8SBaZHxsYHY84LEZ24cXtZ01y3k1K1YJ0vpK9HwqUzb6u9z8igEr3dCCQLQAdAAAAHQAAAAJi0efVT2MdSR0wCAAgAAAAZmxhZy50eHQAsDRpZmZpeCB0aGUgZmlsZSBhbmQgZ2V0IHRoZSBmbGFnxD17AEAHAA==

进行解密:

由于文件尾是3D 7B 00 40 07 00,所以这是rar文件

补全文件头:

打开压缩包文件,得到flag

题目:[WUSTCTF2020]girlfriend

题目是一个音频,显然是音频隐写。

频谱看上去不太像摩斯电码。

听出来这是手机键盘的拨号声,也就是DTMF拨号音识别

使用dtmf2num进行识别:

对应手机上九宫格输入,得到最后的字符串为YOUAREMYGIRLFRIENDS

切换成小写,得到flag

题目:[DDCTF2018](╯°□°)╯︵ ┻━┻

题目是一个txt文件

image-20250313174742569

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string = "d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd"
sliced_list = [string[i:i+2] for i in range(0, len(string), 2)]
print(sliced_list) ##每两位切片

decimal_list = [int(hex_num, 16) for hex_num in sliced_list]
print(decimal_list) ##将十六进制转换为十进制

result_list = [num - 128 for num in decimal_list]
print(result_list) ##转换后的十进制数都大于128,将列表内的每个数都减128

ascii_list = [chr(decimal) for decimal in result_list]
print(ascii_list) ##将十进制数转换为ASCII码

merged_string = ''.join([elem for sublist in ascii_list for elem in sublist])
print(merged_string) ##最终合并为一个字符串

得到flag:

flag{922ab9974a47cd322cf43b50610faea5}

题目:[MRCTF2020]千层套路

打开是一个压缩包,显示被加密

直接爆破密码:

打开后里面又是一个压缩包,继续爆破,此时我们发现,密码就是压缩包的文件名!

使用python脚本:

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
import os
import zipfile


def extract_and_store_final_file(initial_zip_path, target_dir):
if not os.path.exists(target_dir):
os.makedirs(target_dir)

current_zip_path = initial_zip_path

password = os.path.basename(initial_zip_path)[:4]

while True:
with zipfile.ZipFile(current_zip_path, 'r') as zip_ref:
files = zip_ref.namelist()
file_name = files[0]
next_zip_name = os.path.join(target_dir, file_name)
try:
zip_ref.extractall(target_dir, pwd=bytes(password, 'utf-8'))
print(f"Extracted {file_name} to {target_dir} using password {password}")
except RuntimeError as e:
print(f"Error extracting {file_name}: {e}")
break

if file_name.endswith('.zip'):
current_zip_path = next_zip_name
password = file_name[:4]
else:

print(f"The final file is {file_name}, stored in {target_dir}")
break



initial_zip_path = '0573.zip'
target_dir = 'flag'
extract_and_store_final_file(initial_zip_path, target_dir)

脚本提取文件名的前四位作为密码,然后将解压后的文件都放进名为flag的文件夹中,直到解压出的文件后缀不是zip为止。

最终,发现qr.zip

解压:

发现一串RGB数据,利用脚本还原图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PIL import Image

x = 200 # width #x坐标 通过对txt里的行数进行整数分解
y = 200 # height #y坐标 x * y = 行数
im = Image.new("RGB", (x, y)) # 创建图片
file = open('./resource/rgb.txt') # 打开rbg值的文件
# 通过每个rgb点生成图片
for i in range(0, x):
for j in range(0, y):
line = file.readline() # 获取一行的rgb值
rgb = line.replace('(', '').replace(')', '').strip().split(',') # 分离rgb
im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2]))) # 将rgb转化为像素

im.save("./resource/flag.jpg") # im.save('flag.jpg')保存为jpg图片

得到一张二维码,扫描得到flag

题目:百里挑一

解压附件,打开

流量分析题目,用wireshark打开流量包。根据题目提示,其中应该有很多的壁纸图片。尝试导出HTTP,全部保存在一个文件夹里面

使用exiftool *|grep flag得到一半的flag:

还有一半则是在流量包里面:

最终flag:

flag{ae58d0408e26e8f26a3c0589d23edeec}

总结:

针对本次的TPCTF比赛的话,第一道二维码还是比较简单的,运用PS把扭曲的二维码扶正后,其实可以尝试利用QRazyBox集成的工具进行修复,而不是手动修复,耗时耗力(借鉴了其他队的WP)

其次就是spam这道题目,完全没有想到IP地址上面,反而以为是Web方面的知识(那个输入框太误导人了!)当时也没有环境去试不同的IP地址。

后面较难的题暂且不论了。。。

然后就是本周的做题,主要以流量分析为主,学习了一下工业生产流量。这种题还是太少了