强网杯2021——wp

一、MISC

(一)ISO1995

题目描述:We follow ISO1995. ISO1995 has many problems though. One known problem is a time. 压缩包解压密码:fantasicqwb2021

光看文件头辨别不出什么文件,file命令看一下发现是Linux Debian的磁盘文件

binwalk提取出一个ISO文件,用ultraiso打开发现每个字符都分开到一个文件中,直接全部提取出来写个python脚本拼接

flag=''
for i in range(1024):
    name='flag_f'+str(i).rjust(5,'0')
    #print(name)
    with open("E:/CTF_project/Game/强网杯2021/{}".format(name),"r") as fr:
        flag+=fr.readline()
print(flag)

得到下面字符串

!=gF~B.@YB01.%DYzb^-1}jH&@,K[7t/LOi*5b)L'<pW'am\W4LH@\toGKE1{"oDW0qf2{l{W_0V-m:af8AO4^iCT_+ $W3cz(LO)L_-s8'_<Ic/KFP9vrr~6\ni{~#g5cs#7z2s++Y1BbYQV'iSl=DZ__|3T1QxWEwX}NJ@_3SdKK]91b?s-rS6gQwBs@4#5IGxW#&ArDw~_x"!_I^O`x5o'.s5)+c9RU'/%_b[rjiOP0y!&/)WjKR#IjWh0\,Dr!@PH^Nf%,YoWEJ(2wXj/u~Y@gh%&_Gz5U`A=0pAV$E/ >1Kg:@4tS:V4ZB`1_x*.17B&:<xn0rW|2TY_DSN<zvbKCj7+6w'r}Lo8':fYC@FvJ02VbO)noQlMI3#AZ+]U3##P|W{V>z,G5[s r|Ra~-P'>oYJ{O{B"oh=VG*SB2KoNt1 7|,*r#d!=N'%O$1Tron:7}6C(yVSIZmtw8Xza]6D,nn*q&KHNK,PW .b<h E$){Kw_)h,=m41LAv'f6l:I xN:4z0{>&F5(cRg|:M9RMX $,8/1vq-][?a/H}1"X;((,MZ(=WJ4o</_8.D9Q8~S"aA:RNTxpsC8LKW+Pfgw<NTqmy_8G6Np%c-9tAG-em&]1IYtz\IJa1KD&z<k'w7vH Fr--py2uH=;3l*iuisp39+m;"1:xPJB@*LB8;x*?G.'`n^[Pib$KM>RFG#vDrwlk@QC0ebUkG,~fw+xH[W<{:eJmcbx,Yi6KcZ~}vH_R,t{F =}gTKX&;^_Fv1b,DezJ1N}6q)76a]Us=\u8tY;t*#}zSGo`-h64=u2bGZ)I(&%K68&!nQke&+gX=L4TmMy$5nHC&+#<486HKF4f0d%1?I:1=M[p~DxBLtCKh\>4<Qf+cj?a3p0F`4*-%%7*<~'^+KkQ<*z9oUgrgO$:NC.Di<.$`s+69Pn7:IgO`^\T%n |Q'G&9Tx-@!6W<VK_5tH/#i>$7SKKH[Dki-o{b{?j?4.Zw+aV!|Zi{2oTqk*#!O0h$-6oCbPpaZbPfi

根据题目的提示One known problem is a time,说明需要把这些文件按时间顺序排一下就能得到flag。那就定位到iso文件的目录记录字段,把这些日期时间字段都dump下来即可

发现前四个字节年、月、日、时设置的都是FF,最后一个GMT都设置的是0x08,那就取其中间的2个字段。

image-20211123210532481

写exp

import re
time=[]
flag=''
with open(r"0.iso","rb") as fr:
    fr.seek(0x16043)
    s=fr.read()
    for i in range(len(s)):
        try:
            if s[i:i+4]==b'\xff\xff\xff\xff':
                time.append(int.from_bytes(s[i+4:i+6], byteorder='big', signed=False))
                name='flag_f'+str(time[-1]).rjust(5,'0')
                #print(name)
                with open("iso1995\{}".format(name),"r") as fr:
                    flag+=fr.readline()
        except:
            break
print(flag)

得到flag

FLAG{Dir3ct0ry_jYa_n41}

(二)BlueTeaming

题目描述:Powershell scripts were executed by malicious programs. What is the registry key that contained the power shellscript content?
(恶意程序执行了一个Powershell脚本。包含power shell脚本内容的注册表项是什么?)

是一道内存取证题,既然是powershell脚本运行,那就找powershell日志(windows中的powershell日志文件一般为WindowsPowerShell.evtx),filescan确认一下是否存在

image-20211123203215142

volatility -f memory.dmp --profile=Win7SP1x64 filescan | find "evtx"

然后把它dump出来

volatility -f memory.dmp --profile=Win7SP1x64 dumpfiles -Q 0x000000013d9a7640 --dump-dir=./

image-20211123203029653

后缀名改evtx后在Windows事件查看器里分析,随便选一个事件进去可以看到在powershell中执行的命令关键字powershell -noprofile,后面跟的应该就是恶意脚本

image-20211123205925467

010 Editor或者其它编辑器打开memory.dmp搜索powershell -noprofile即可看到注册表项。

image-20211123210259617

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication

(三)EzTime

题目描述:Forensic.Find a file that a time attribute has been modified by a program.

(查找时间属性已被程序修改的文件。)

X-ways打开,找修改时间与记录更新时间不一样的

image-20211124200706023

得到flag

{45EF6FFC-F0B6-4000-A7C0-8D1549355A8C}.png

(四)Cipherman

题目描述:The attacker malicously accessed the user’s PC and encrypted specific volumes. How to decrypto the volume?(攻击者恶意访问用户的PC并加密特定卷。如何解密该卷?)

内存取证

先扫一下文件

volatility -f memory --profile=Win7SP1x86_23418 filescan

发现BitLocker恢复密钥

image-20211124223606851

dump出来(不知道为啥windows下volatility报错,就换linux了)

vol.py -f memory --profile=Win7SP1x86_23418 dumpfiles -Q 0x000000007e02af80 --dump-dir=./

得到内容如下

image-20211124223810290

image-20211124223212232

恢复密钥就是

221628-533357-667392-449185-516428-718443-190674-375100

找个挂载工具挂载到本地,双击进入该盘会弹出要求输入PIN码,更多里面切换到输入恢复密钥然后输入即可

image-20211125125445608

得到flag

Wow, you have a great ability. How did you solve this? Are you a hacker? Please give me a lesson later.

(五)threebody

参考:强网杯2021-threebody - wdxxg’s Blog

了解完bmp图片结构之后再来看,发现这是一个未压缩且直接给出颜色数据的位图图片,深度是24,也就是3个字节代表一个像素,但010 Editor中观察到这些数据更像是4个字节一组(因为对于相邻的像素颜色值总是相近的)

image-20211125182512329

所以修改biBitCount字段值为32,变成4个字节一个像素

image-20211125183045880

保存后得到的图片如下

threebody

StegSolve中看RGB各个通道,只有这个正常些

image-20211125183503930

行列分别有LSB隐写

image-20211125184623916

image-20211125184555938

网上搜一下David,查到这个人是戴维 · 希尔伯特,一个数学家

用StegSolver只能看到bmp的RGB三个通道,不能看到rgbReserved通道的情况(试过了,Alpha通道看到的是白屏),本来想找个在线工具把bmp转png,然后发现没有用,可能是那个网站转换算法有问题把,所以无奈之下写个脚本转换成png格式再去看各个通道的情况。

from PIL import Image
image=Image.new(mode='RGBA',size=(580,435))
with open(r'threebody.bmp','rb') as f:
    file=f.read()
    index=0
    for i in range(434,-1,-1):  #根据bmp的结构知道该bmp文件上下倒序存储像素值
        for j in range(0,580):
            s=[]
            for t in range(0,4):
                s.append(file[index])
                index+=1
            image.putpixel((j,i),(s[2],s[1],s[0],s[3]))  #
    image.show()
    image.save('threebody_new.png')

那个通道果然有问题,

image-20211125222339781

我们先把上面的绿色通道得到的图片导出,稍微剪切一下

threebody_new

然后还有个线索没用到——希尔伯特,到搜索引擎里查希尔伯特与三体就找到这样一篇文章

真·降维打击!《三体》中二向箔吞噬地球的场景成真了!_腾讯新闻 (qq.com)

也就是说将上面的图片看作01矩阵,用希尔伯特曲线进行“降维打击”,变成一维的二进制流

贴上别的博主写的降维脚本学习一下

import numpy as np
from PIL import Image
#安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple hilbertcurve
from hilbertcurve.hilbertcurve import HilbertCurve
#提取像素数据
with Image.open('threebody_new.png') as img:
    arr = np.asarray(img)
arr = np.vectorize(lambda x: x&1)(arr[:,:,2])
#确定图片中的有效区域
for x1 in range(np.size(arr,0)):
    if sum(arr[x1])>0:
        break
for x2 in reversed(range(np.size(arr,0))):
    if sum(arr[x2])>0:
        break
for y1 in range(np.size(arr,1)):
    if sum(arr[:,y1])>0:
        break
for y2 in reversed(range(np.size(arr,1))):
    if sum(arr[:,y2])>0:
        break
#剪切出有效二维数据
arr = arr[x1:x2+1, y1:y2+1]
#print(x2+1-x1)#得出是128*128的矩阵
#构建希尔伯特曲线对象
hilbert_curve = HilbertCurve(7, 2)
#生成一维的二进制流数据
s = ''
for i in range(np.size(arr)):
    [x,y] = hilbert_curve.point_from_distance(i)
    s += str(arr[127-y][x])
#转ASCII文本写入文件
with open('output', 'wb') as f:
    f.write(int(s,2).to_bytes(2048, 'big'))

跑出来得到一个C源文件,稍微修改一下语法报错(malloc前面加(char *))

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* a(char* s);

char t[65536];

void b()
{
	printf("%s\n\nint main()\n{\n\tstrcpy(t, \"%s\");\n\tb();\n\treturn 0;\n}\n\nchar* a(char* s)\n{\n\tint l=strlen(s);\n\tchar* n=malloc(l*2+1);\n\tchar* p=n;\n\tfor(int i=0; i<l; i++)\n\t\tswitch(s[i])\n\t\t{\n\t\t\tcase '\\n':\n\t\t\t\t*p++='\\\\'; *p++='n'; break;\n\t\t\tcase '\\t':\n\t\t\t\t*p++='\\\\'; *p++='t'; break;\n\t\t\tcase '\\\\':\n\t\t\t\t*p++='\\\\'; *p++='\\\\'; break;\n\t\t\tcase '\\\"':\n\t\t\t\t*p++='\\\\'; *p++='\\\"'; break;\n\t\t\tdefault:\n\t\t\t\t*p++=s[i]; break;\n\t\t}\n\t\t*p=0;\n\n\treturn n;\n}\n", t, a(t)); 		  		  		 		   		    	 		  			 				 		 	   	    		   	 		 		 	 	   	 	 		 			   		 	 	 		 	  	  		     		 			  	     	 		 		   	 					 	 	     			  	   		      		 		   		   	 		  	 	 		 		 	 					 	
}

int main()
{
	strcpy(t, "#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n\nchar* a(char* s);\n\nchar t[65536];\n\nvoid b()\n{\n\tprintf(\"%s\\n\\nint main()\\n{\\n\\tstrcpy(t, \\\"%s\\\");\\n\\tb();\\n\\treturn 0;\\n}\\n\\nchar* a(char* s)\\n{\\n\\tint l=strlen(s);\\n\\tchar* n=malloc(l*2+1);\\n\\tchar* p=n;\\n\\tfor(int i=0; i<l; i++)\\n\\t\\tswitch(s[i])\\n\\t\\t{\\n\\t\\t\\tcase '\\\\n':\\n\\t\\t\\t\\t*p++='\\\\\\\\'; *p++='n'; break;\\n\\t\\t\\tcase '\\\\t':\\n\\t\\t\\t\\t*p++='\\\\\\\\'; *p++='t'; break;\\n\\t\\t\\tcase '\\\\\\\\':\\n\\t\\t\\t\\t*p++='\\\\\\\\'; *p++='\\\\\\\\'; break;\\n\\t\\t\\tcase '\\\\\\\"':\\n\\t\\t\\t\\t*p++='\\\\\\\\'; *p++='\\\\\\\"'; break;\\n\\t\\t\\tdefault:\\n\\t\\t\\t\\t*p++=s[i]; break;\\n\\t\\t}\\n\\t\\t*p=0;\\n\\n\\treturn n;\\n}\\n\", t, a(t));\n}");
	b();
	return 0;
}

char* a(char* s)
{
	int l=strlen(s);
	char* n=(char *)malloc(l*2+1);
	char* p=n;
	for(int i=0; i<l; i++)
		switch(s[i])
		{
			case '\n':
				*p++='\\'; *p++='n'; break;
			case '\t':
				*p++='\\'; *p++='t'; break;
			case '\\':
				*p++='\\'; *p++='\\'; break;
			case '\"':
				*p++='\\'; *p++='\"'; break;
			default:
				*p++=s[i]; break;
		}
		*p=0;

	return n;
}

运行了一下发现把这个程序自己的源代码打印了出来,同时发现这个源代码里夹杂了密文

image-20211126132148728

tab对应1,空格对应0

import re
c=''
m=re.sub(' ','0',c)
m=re.sub('\t','1',m)
#print(m)
flag=''
for i in range(0,len(c),8):
    flag+=chr(int(m[i:i+8],2))
print(flag)

得到flag

flag{D1mEn5i0nAl_Pr061em}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Em0s_Er1t

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值