2019年全国信息安全管理知识与技能竞赛初赛技能赛于6月5日开始,多数省份比赛合计10道CTF试题,其中misc题6道、web题2道、crypto题1道、re题1道。以下是本人解题的思路,供大家参考:
1.misc_qiandao
(1)题目
题目下载: https://pan.baidu.com/s/151nnWXmkdqz3lpHe4YJw1g 提取码: 3i3h
本题的flag :
如果a='0123456789abcdefgl-{}',
且b=[15 , 17 , 10 , 16 , 19 , 1 , 2 , 3 , 20 ],
那么flag就是flag{123}(从a里面找到与b中数字对应位置的字符,位置从0开始)。
那么当b=[15 , 17 , 10 , 16 , 19 , 15 , 11 , 9 , 1 , 11 , 2 , 5 , 3 , 18 , 4 , 8 , 5 , 3 , 18 , 4 , 14 , 1 , 6 , 18 , 11 , 11 , 11 , 13 , 18 , 5 , 11 , 8 , 5 , 9 , 13 , 8 , 0 , 11 , 7 , 3 , 12 , 20],此时的值就是真正的flag。
(2)writeup
一道非常简单的签到题,读懂了题目就能解,就不多解释了,直接给出python代码:
>>>a='0123456789abcdefgl-{}'
>>>b=[15 , 17 , 10 , 16 , 19 , 15 , 11 , 9 , 1 , 11 , 2 , 5 , 3 , 18 , 4 , 8 , 5 , 3 , 18 , 4 , 14 , 1 , 6 , 18 , 11 , 11 , 11 , 13 , 18 , 5 , 11 , 8 , 5 , 9 , 13 , 8 , 0 , 11 , 7 , 3 , 12 , 20]
>>>"".join([a[b[i]] for i in range(len(b))])
'flag{fb91b253-4853-4e16-bbbd-5b859d80b73c}'
2.misc_pipe
(1)题目
题目下载:https://pan.baidu.com/s/185O4pFFyZ-uxe9lAcJbdPw 提取码: 2a5s
通过链接下载到一个文件 pipe.pcapng
题目提示:DNS、多重base、pipe
(2)writeup
用Wireshark打开文件pipe.pcapng,根据提示,重点筛选出DNS报文进行分析:
草草翻一下,就发现info列有很整齐的、奇怪的二进制串,好奇心驱使你不由想提取出来看一下是什么东西。好吧,上python
a=[]
with open("pipe.pcapng","rb") as file1:
data=file1.read()
flag='F="'
while True:
try:
start=data.index(flag)+len(flag)
data=data[start:]
end=data.index('"')
a.append(data[:end])
except:
break
with open("pipe.txt","w") as file1:
file1.write("".join([a[i]+"\n" for i in range(len(a))]))
查看输出的结果,非常整齐漂亮:
这些十六进制表示什么呢,转过来看看:
for i in range(len(a)):
a[i]=a[i][:60]
a[i]="".join([a[i][j+2:j+4] for j in range(0,len(a[i]),4)])
b="".join(a)
with open("flag.txt","w") as file1:
file1.write(b.decode("hex"))
虽然没有直接看到flag,但是发现了两串字符串,一串好像有flag的身影,但顺序不太对,另一串像是题目提示的base64字符串。估计flag应该是藏在base64里,直接base64解码,囧!!!没解出来。
好吧,分析一下第一串字符串,看怎么排出flag的:
h
}X
h
ious
h
_ser
h
_you
h
{are
h
flag1
得到解码flag{are_you_serious}X,玩我呢?明显就不是,后面一个X就告诉我了,不过还是傻傻的提上去试了一下,确实不是。但这个字符串的解码方式(以h分割4个一组的字符串,分离出来后再倒序组合字符串,即为解码结果),是不是就是第二串字符串的解码方式呢?手工试了一下:
>>>flag="NmF9hMTIyhNGVhhNzA3hOC1khOTZmhNTcthLTQ2hZTlihNS00hN2YzhMzY3hZ3s4hZmxh"
>>>length=len(flag)
>>>"".join([flag[length-i:length-i+4] for i in range(4,length+4,5)])
ZmxhZ3s4MzY3N2YzNS00ZTliLTQ2NTctOTZmOC1kNzA3NGVhMTIyNmF9
得到解码后面的base64编码:ZmxhZ3s4MzY3N2YzNS00ZTliLTQ2NTctOTZmOC1kNzA3NGVhMTIyNmF9
然后,base64解码:
>>>"ZmxhZ3s4MzY3N2YzNS00ZTliLTQ2NTctOTZmOC1kNzA3NGVhMTIyNmF9".decode("base64"))
flag{83677f35-4e9b-4657-96f8-d7074ea1226a}
解到这一步,结果应该出来了,肯定是flag{83677f35-4e9b-4657-96f8-d7074ea1226a}。可是比赛中,提交上去,提示结果是错误的,瞬间崩溃……估计是赛题里录入的答案有误吧,囧囧囧!!!
先写到这把,吃完饭,继续写后面的部分……
3.misc_eiint
(1)题目
题目下载:https://pan.baidu.com/s/1r0Ei3ZVipwkGt6CbeenBjw 提取码: 2ybi
下载文件得到eiint.log,提示蓝牙通信
(2)writeup
根据提示,用wireshark打开文件进行分析,直接查看蓝牙传送协议obex
数据报不多,很快就发现了感兴趣的东西:
A.一串奇怪的字符串
B.传送的文件是以504b0304开头的(基本可以确定传送的是一个压缩文件)
把文件提取出来,保存为a.rar文件
打开压缩文件,提示需要输入密码。把奇怪的字符串拷贝进去试试运气。
运气不错,结果直接给出来了:
4.misc_cupshead
(1)题目
题目下载:https://pan.baidu.com/s/1mvIdmdCTzcGXlGA4WU6TCg 提取码: 65xt
下载文件得到cupshead.pcapng,提示Linux下CUPS系统打印流程
(2)writeup
暂未做出来,求大神给思路~~~~~~~~
5.misc_easy_log
(1)题目
题目下载: https://pan.baidu.com/s/1F-bge6ZkV2oM9stoqA2VEA 提取码: vtdh
下载后得到文件access.log,提示flag为flag{md5(后台登陆密码+数据库注出来的密码)}
(2)writeup
目标再明确不过了,就是在日志里找后台登陆密码和数据库注出来的密码。关键字词“password”肯定是不能放过的,用excel打开日志,直接筛选包含"password"的行,很快就发现暴露破解后台登陆密码和数据库注密码的日志。
入侵者最后一次尝试后台登陆密码,应该就是正确的密码:654321
接下来分析数据库注入部分,从SQL语句一眼就能看出是时间盲注。密码串每一位的最后一次尝试即为正确字符(这个应该不用解释吧~~~),好吧,懒人就上python吧:
a=[]
with open("access.log","rb") as file1:
data=file1.read()
flag='GET /index.php?con=goods&act=set_online&status=0&id=12)%20and%20if(substr((select%20password%20from%20tiny_user%20limit%200,'
while True:
try:
start=data.index(flag)+len(flag)
data=data[start:]
end=data.index('"')
a.append(data[:end])
except:
break
with open("access.txt","w") as file1:
file1.write("".join([a[i]+"\n" for i in range(len(a))]))
我们获得SQL注入字符串后半部分,非常整齐:
接着上面的代码,继续对输出的结果进行分析,提取成功盲注获得的每一位密码:
value=""
index=9
for i in range(len(a)-1):
if a[i][3:5]!=a[i+1][3:5]:
i_start=index-1
while a[i][i_start]!="'":
i_start=i_start+1
i_end=i_start+2
while a[i][i_end]!="'":
i_end=i_end+1
value=value+a[i][i_start+1:i_end]
value=value+a[-1][index+1]
with open("flag.txt","w")as file1:
file1.write(value)
得到数据库盲注的MD5加密结果:a384b6463fc216a5f8ecb6670f86456a
上网站(https://www.cmd5.com)直接进行解密:
得到注出的数据库密码:qwert
将两个密码合并654321qwert,在网上求md5获得flag
>>> import md5
>>> flag="654321qwert"
>>> m=md5.new()
>>> m.update(flag)
>>> "flag{"+m.hexdigest()+"}"
flag{d10f7473de39e8fd37245c08fe128b32}
6.misc_hello_hacker
(1)题目
题目下载:https://pan.baidu.com/s/1sHYyMhhntV4em8CIvpWZCg 提取码: ipyt
下载文件得到文件hello_hacker.pcapng,提示最近新搭的服务被入侵了,你能通过这个流量包找到hacker都拿到了什么数据么?
(2)wirteup
这是一道比较绕的题。用wireshark打开hello_hacker.pcapng,数据非常多,简单翻了一下,毫无收获。根据提示,需要理清以下三个问题:
A.入侵者的IP是多少?
B.服务器的IP是多少?
C.入侵者获得了什么数据?
通过会话分析,发现192.168.58.1<-->192.168.58.145的通信量巨大,问题应该就在两者之间,通过双方收发数据看,也可以确定192.168.58.1应该就是入侵者,192.168.58.145是被入侵的服务器。首先对嫌疑最大的192.168.58.1进行报文分析。
首先发现的是入侵者再进行登陆页面账号密码暴力破解,不过好像均没成功:
后来又做了很多别的尝试,但服务器均相应500错误,应该也是没有收获的。
接着快速往下翻,发现了数据库注入,初步看了一下,发现是时间盲注。入侵者不断的尝试,看来是有收获的。提取出来看看:
def getValue(flag):
with open("hello_hacker.pcapng","rb") as file1:
data=file1.read()
tmp=data
list_a=[]
while True:
try:
start=tmp.index(flag)
tmp=tmp[start:]
end=tmp.index("\n")
a=tmp[:end]
#print(table)
list_a.append(a)
tmp=tmp[end:]
except:
break
return list_a
def writedata(data,name="b.txt"):
with open(name,"w") as file1:
file1.write("".join([data[i]+"\n" for i in range(len(data))]))
database="GET /dapur/apps/app_comment/controller/comment_status.php?stat=0&id=3%20or%20if(mid(database(),"
tables="GET /dapur/apps/app_comment/controller/comment_status.php?stat=0&id=3%20or%20if(mid((select%20group_concat(%22~%22,table_name)%20from%20information_schema.tables%20where%20table_schema=database()),"
database=getValue(database)
writedata(database,"database.txt")
tables=getValue(tables)
writedata(tables,"tables.txt")
可以很清晰的看到入侵者通过时间盲注企图获得库名和表名:
接着前面的代码,提取入侵者获得的库名和表名:
def analy(start,end,index,data):
value=""
i=0
for i in range(len(data)-1):
if data[i][start:end]!=data[i+1][start:end]:
i_start=index-1
while data[i][i_start]!="'":
i_start=i_start+1
i_end=i_start+2
while data[i][i_end]!="'":
i_end=i_end+1
value=value+data[i][i_start+1:i_end]
value=value+data[-1][index]
return value
flag=analy(95,96,110,database)
flag=flag+"\n"+analy(197,200,211,tables)
with open("flag.txt","w") as file1:
file1.write(flag)
得到以下的结果,看了差点崩溃,好像没有flag呀!!!
为方便分析,我们按照添加在表名间的“~”进行分割,把%XX的十六进制都转义回来:
~12qw,
~/_t1mebl1ndness},
~fiyo88/_apps,
~fiao8aaarticle,
~fiyo88/_article/_category,
~fiyo88/_article/_tags,
~fiyo88/_comment,
~fiyo88/_comment/_setting,
~fiyo88/_contact,
~fiyo88/_contactfiy
~fiyo88/_contact,
~fiyo88/_contact/_group,
~fiyo88/_menu,
~fiyo88/_menu/_category,
~fiyo88/_module,
~tact/_group,
~fiyo88/_me2
看到了这个:_t1mebl1ndness}。有点像flag的后半部分,但总觉得怪怪的,勉强手下吧。
只有一半的flag,悲哀呀,是不是前面漏了什么细节被过滤了。根据提示,信息肯定是从服务器出去的,重点关注一下服务器的交互信息,将过滤条件改为:ip.addr==192.168.58.145
重新分析了服务器500错误附近的信息,发现入侵者POST /invoker/readonly 数据给服务器,虽然服务器报了500错误,但实现了反弹调用118.192.48.48。请求中泄露了一串奇怪的字符串,像是base64编码,莫非~~~
提取第一段YW5hY29uZGEtcG9zdC5sb2cKYmluCmJvb3QKZGV2CmV0YwpmbGF"e2RlM2VyMWFsMXphdGkwbgpo,由于字符串中"不是base64编码,故以"做分割分成两串,补齐后分别进行转义:
>>> "YW5hY29uZGEtcG9zdC5sb2cKYmluCmJvb3QKZGV2CmV0YwpmbGF=".decode("base64")
'anaconda-post.log\nbin\nboot\ndev\netc\nfla'
>>> 'e2RlM2VyMWFsMXphdGkwbgpo'.decode("base64")
'{de3er1al1zati0n\nh'
好像看到flag的前半部分:flag{de3er1al1zati0n
合并盲注分析出来的后半部分后得到:flag{de3er1al1zati0n_t1mebl1ndness}
这是flag么,看着怎么这么奇怪,越看越觉得像英文单词时间盲注,用s替代3,用i替代1,用o替代0,得到传说中的:flag{deserialization_timeblindness}
序列化_时间盲注,正好验证了入侵者的攻击手段。
7.crypto_Trsa
(1)题目
题目下载:https://pan.baidu.com/s/1MFzeM2v39VZAJjAbeebZKw 提取码: 9gad
from flag import flag
n=0xCE522FBBA31B08CEA95A54D9AC09BEC855CC927955FE1E6197EFFD693AA8F667F67C074B0390C66A0B8C11ABD11849CC570255FF8F982B236E34031711930AD4398D4E68FD279D4D0C7C7AC813BF5FF09AC58DDD35AA25F8D6BACD0B1A62261A81E7FB3F32D3C5C30802FA1EF78B5897CE65CDCD7EC6948FD86DC5ACD392C36B
e=0x010001
d=0x9AA40D34E566A0EE4D0EF0A40A076FE0B63653DEEFEE3D15470D50F1EB4EB3096F3CBD36A36082E6FEEAA86010A3D4C47CBEBA78874735A623B6864E6714C03AC2097F21CD6876BE31065FAA3E14194527E69CC37B6E535729FCFF8354D1BAFDA69845A0D9D3925019B0749B6B7B99D9D87E322E2F344B28130AF21BF7CE0C21
end=pow(flag,e,n)
print end
#29292378347128013190443474379188941158098023205802761774438019901525344990455045672895914920330818403708505560118235725959276565411191769689751391257043336700387783574633974398568843305193087795483042278466554619464690821717320592477304379124079059531958922420316205962660361070097828384029619923396330056729
提示诚实的RSA
(2)writeup
看了题目,再诚实不过了,RSA的所有因子都给全了,一道教科书式的题,更像是签到题,不需要思考,直接套公式就行了:
>>> import gmpy2
>>> c=29292378347128013190443474379188941158098023205802761774438019901525344990455045672895914920330818403708505560118235725959276565411191769689751391257043336700387783574633974398568843305193087795483042278466554619464690821717320592477304379124079059531958922420316205962660361070097828384029619923396330056729
>>> n=0xCE522FBBA31B08CEA95A54D9AC09BEC855CC927955FE1E6197EFFD693AA8F667F67C074B0390C66A0B8C11ABD11849CC570255FF8F982B236E34031711930AD4398D4E68FD279D4D0C7C7AC813BF5FF09AC58DDD35AA25F8D6BACD0B1A62261A81E7FB3F32D3C5C30802FA1EF78B5897CE65CDCD7EC6948FD86DC5ACD392C36B
>>> e=0x010001
>>> d=0x9AA40D34E566A0EE4D0EF0A40A076FE0B63653DEEFEE3D15470D50F1EB4EB3096F3CBD36A36082E6FEEAA86010A3D4C47CBEBA78874735A623B6864E6714C03AC2097F21CD6876BE31065FAA3E14194527E69CC37B6E535729FCFF8354D1BAFDA69845A0D9D3925019B0749B6B7B99D9D87E322E2F344B28130AF21BF7CE0C21
>>> m=pow(c,d,n)
>>> (hex(m))[2:-1].decode('hex')
'flag{0a9a6225-055c-4e0b-9852-29e6427dd60e}'