Writeup丨国赛线上初赛解题第二波~

接着昨天的...

今天主要放送Reverse类型题的writeup~所谓知其然也要知其所以然,逆向给小讲的感觉就像要去探索宇宙起源辣么新奇~

--------------- 特别感谢BXS战队 ---------------

噢,对了,Mobile和Pwn明天见哦~

PART4. RE

1.RE

逆向第一个题,简直就是个misc。不多说。但是拿了个一血,美滋滋,哈哈。

用ida看下,对输入分段处理,进入三个不同的函数,功能差不多。

一开始判断第一部分,和明文比较。

将输入分段,以_为界。然后进入三个函数中。

这几个函数就是md5了,初始化向量用了2步,估计是怕直接被看出来吧,只是很简单的xor处理了下。其实也没什么用,最后一个应该是修改过了,将hex转ascii输出32位。

然后进行简单的处理,如果是字符就变换,加上一个值,字母不动。

然后和一串md5 hash比较,很简单吧,直接逆上面那个算法,然后去网上查md5 就行了。

第二个函数和第一个差不多。

多出来的是个亦或的表,也就是输出hash后进行xor变换,然后hex2ascii,最后再处理,然后比较,和第一个函数差不多,算法可逆,也很简单。

然后进入第三个函数。

前半部分和第二个一模一样,我也同样算了一次,但是去网上查md5并没有结果。于是开始怀疑人生了。但是前面两个部分是有解的,说明我的理解是对的,真的查不到的话。对hash应该有2种方法。1.爆破部分位。2.有后门。

然后往下看发现了不得了的东西。

开始写文件,很奇怪,为什么要写文件,写的是什么格式是文件。而且和smc差不多,自带亦或,防止直接看出来文件的格式。然后我们简单的分析一下这个原始部分的hex。

如图所示,根据多年做misc的经验,感觉不会是txt文件,应该是二进制文件,具体是什么不好说。而且这还不是最后的文件,还未处理,但是有的值引起了我的注意。特别是9n这个值。如果是二进制文件的话,正常情况下不会有9n这种值重复多遍,有可能是00、ff这种或者其他的值。一开始分析了很久,后来突然想起来,这种xor的文件是有方法可以快速解的。很久以前用过python的xortool库,可以自动分析xor的密钥值和密钥长度。然后我就试了试。

先dump文件,方便分析。

检测xor密钥长度,其实这里根据第三个函数已经知道了,奇偶使用不同密钥亦或,这样长度的话就是2,,这里只是参考的。

Xortool库自动分析xor密钥,给出了一个9n,和我预期的差不多,这样原来那些9n就变成00了。然后得到xor后的文件。

这个文件还是不对,不知道是什么,但是看看头部和一些信息,感觉不是很陌生。

再看看尾部。。。。简直了,这应该就是个jpg文件。密钥用错了。经过测试后,我使用了8o来作为密钥,看看得到的是不是jpg文件。

我以为得到了flag,然而并没有,这个文件是个什么东西。(不知道哪出了问题,我觉得没错)

无奈之下,回过头分析第三个函数给出的那个部分,发现前面2个函数的hash输出都有被引用到。如下图

具体是引用在下面,相当于是CRC吧,完整性校验hash的四部分,然后产生密钥就应该是我上面用的8o。

然后反推第三部分的2位,可以得到第三部分的2位是De。

其实到这里就不知道该怎么办了,尝试写了个md5爆破了几位,都没有和hash匹配。无奈之下,直接动态调试,然后动态patch,过掉hash匹配那步,然后就得到了一个文件。我以为是和我解密一样,但是竟然是不一样的。。。

不知道为什么。。。然后尝试结合前面两部分输入运行了下,不对。又试了下,最后加个},提示congratulations。。。拿到flag。

部分脚本:

cipher1 = "5BH8170528842F510K70EGH31F44M24B"

get1=[]

for i in xrange(len(cipher1)):

if ord(cipher1[i])<=0x39:

get1.append(cipher1[i])

else:

get1.append(chr(ord(cipher1[i])-i%10))

cipher2 =''.join(get1).decode('hex')

#tima

xor = "92 84 3D A7 14 F2 FB 4B EE 8A C2 C3 76 68 13 1E".replace(' ','').decode('hex')

get2 =[]

for i in xrange(len(cipher2)):

get2.append(hex(ord(cipher2[i]) ^ ord(xor[i])))

print ''.join(map(lambda x:x[2:],get2))

#yefb

cipher3 ="6F20IHJ2J8897I1G972LA2688F2492B8"

get3=[]

for i in xrange(len(cipher3)):

if ord(cipher3[i])<=0x39:

get3.append(cipher3[i])

else:

get3.append(chr(ord(cipher3[i])-i%10))

t = ''.join(get3).decode('hex')

get4 =[]

for i in xrange(len(t)):

get4.append(hex(ord(t[i]) ^ ord(xor[i])))

print ''.join(map(lambda x:x[2:],get4))#

xxx= 0x7ca

print chr(ord("8")^(xxx >>4))

print chr(ord("o")^xxx &0xf)

Flag:CISCN{tima_yefb_MayDetyU$hhtIm2}

2.2ex

又是mips。(最近mips怎么那么多)

分析了一下,好乱,不知道是什么鬼,然后开了qemu运行了下,指令不支持。不知道为什么。就没做了。

晚上没其他题做,又开始分析这个题。ida分析是mips大端。。。惊了,然后开了个大端的虚拟机,运行了下,不像对称加密,感觉是分段处理的,和base64类似。但是给的out文件长度和我得到的长度不一样,程序运行输出只有24位,给的out文件很长。可见字符有25个。即│_r-+_Cl5;vgq_pdme7#7eC0=。我也没细想,直接暴力求解。。。用python编程的话,本地程序的读写不是很熟,然后就挂在端口上了。用socat挂载程序。

socat tcp-l:1234,fork exec:./mx,reuseaddr &

本地没有pwn库,还装了个socket库。。。

脚本:

import os

import threading

import time

import socket

decode="|_r-+_Cl5;vgq_pdme7#7eC0="

HOST='192.168.137.198'

PORT=1234

def find_lcsubstr(s1, s2):

i=0

while i<len(s1) and i<len(s2):

if s1[i]==s2[i]:

i+=1

else:

break

return i

def baopo():

flag=""

print flag

maxnum = 0

for a in xrange(0x30,0x7f):

for b in xrange(0x30,0x7f):

temp=flag + chr(a)+chr(b)

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((HOST,PORT))

s.sendall(temp+'\n')

recv=s.recv(50)[:-1]

#print chr(a),chr(b),recv

if find_lcsubstr(recv,decode)>=maxnum:

maxnum=find_lcsubstr(recv,decode)

index1=chr(a)

index2=chr(b)

print maxnum,index1,index2

s.close()

具体的算法就是最长前缀匹配,因为base64是一套编码,前后是有关的,不能只爆破一位,我这里使用2位爆破,然后和cipher匹配最长的前缀,即能得到第一位的极大可能解,依次往复,可以解码整个base64串。实现方式是半自动方式,考虑到有些位置上最大的长度相同,候选值不止一个,全自动的话可能会有问题。

说了这么多,跑了n编。没结果。。。惊了。

之后用ida找到了关键的base64编码表。。。其实shitf+f12 第一行就是了。早没看见,唉。

然后仔细分析的话,可以发现,没有|这个符号,应该不是编码的结果。这样的话程序输出长度和给的cipher长度就一致了,而且也可以解释为什么上面那个脚本没有结果。

Emm,既然找到table了,还用什么socket,直接解密base64就行了。

就拿到flag了。

Flag:flag{change53233})

-END-

原文发布于微信公众号 - 安恒网络空间安全讲武堂(cyberslab)

原文发表时间:2018-05-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏iKcamp

手把手教你撸一个 Webpack Loader

文:小 boy(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 ? 经常逛 webpack 官网的同学应该会很眼熟上面的图。正如它宣传的一样,w...

3684
来自专栏SHERlocked93的前端小站

JS 静态类型检查工具 Flow

本文主要介绍了解决JS作为弱类型语言没有类型检查痛点的静态类型检查工具 Flow ,并且介绍了在WebStorm中使用Flow的方法,最后介绍了一些常用的Flo...

1085
来自专栏安恒网络空间安全讲武堂

技术分享 | 浅谈 RAS

一 首先介绍一下什么是RSA RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。 RSA的算法涉及...

1936
来自专栏信安之路

pydictor 爆破字典生成指南

pydictor 是一个使用 python 语言开发,遵循 GPLv3 协议的开源命令行工具,主要用来帮助安全研究人员生成称心如意的暴力破解字典。

860
来自专栏MelonTeam专栏

What's New in LLVM 9

导语 :这绝不仅仅是一篇 WWDC 2017 Session 411 学习笔记。除了有关 LLVM 9.0 的新特性之外,还有关于静态分析器和 Clang 5 ...

23910
来自专栏编程

云平台渗透之-python shell获取root权限

2018年的第一天,祝大家365天元气满满! 话不多说,先打响新年第一炮(不好意思,我又污了=.=) ***本系列内容仅用于技术分享,请勿对号入座*** 之前有...

2245
来自专栏Golang语言社区

Golang将时间戳转为字符串

在golang里面获取时间戳并不难。只要加载time包。然后time.Now().Unix(),就可以了,但接下来转成string就麻烦了 本来,加载strco...

2775
来自专栏鬼谷君

python3模块: uuid

1062
来自专栏xiaoxi666的专栏

C++编程规范(不断更新)

  有时候在windows系统下编译没问题,但是在linux系统下就不行了,那是因为linux下有同名函数。

872
来自专栏mathor

第六届蓝桥杯决赛B组C/C++——密文搜索

812

扫码关注云+社区