2021年10月广东强网杯,REVERSE的simplere

99 篇文章 32 订阅

2021年10月广东强网杯,REVERSE的simplere

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述
.
.
64ELF文件,无壳,照例先运行一下程序,查看主要回显信息:
在这里插入图片描述
.
.
照例扔入IDA中查看伪代码信息,有main函数看main函数:
在这里插入图片描述
.
.
(这里积累第一个经验)
上图分析了前半部分,现在跟踪那个关键自定义函数v10 = sub_401192(v5);这是对前15个字符组成的迷宫进行操作。

点进去查看逻辑,是一个走迷宫,输入15步的wasd,要从A开始走,必须走到.上,最后必须走到B上。

根据11可以判断是二维数组,这也是我第一次学到迷宫的维数判断。因为一个走11步,另一个一步一步走,所以一维字符串最后得出二维迷宫,长11宽5的5*11型,sw字符一下走11步就是上下移动ad一下走1步就是左右移动。也就是说走得多的就是行移动,走得少的就是列移动。

A********
.*
*.
*******
******B

手扒得到ssddddwddddssas

在这里插入图片描述
.
.
然后上半部分条件就过了,开始分析后半部分:
在这里插入图片描述
.
.
先跟踪分析src = (void *)sub_40126F();函数:
在这里插入图片描述
.
.
(这里积累第二个经验)
这里的dest是在内存中的,这里静态修补我不太会,因为destsrc都是在栈中的所以直接用动态调试,用前面得出的前半部分搭配其它字符来运行ssddddwddddssas-666666666666666666
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
.
.
所以这题就是base64变码加密了,继续跟踪最后的自定义函数v10 = sub_401342(v7);
在这里插入图片描述
.
.
密文也有了,可以写逻辑了,首先求出base64变形码表,从
src = (void *)sub_40126F();处导出数组:

key2=[  0x4D, 0x20, 0x07, 0x05, 0x43, 0x15, 0x7A, 0x73, 0x39, 0x01, 
  0x7F, 0x53, 0x66, 0x4E, 0x0D, 0x18, 0x60, 0x76, 0x75, 0x00, 
  0x58, 0x15, 0x00, 0x32, 0x68, 0x3F, 0x78, 0x7F, 0x7B, 0x64, 
  0x4E, 0x49, 0x0F, 0x2E, 0x3F, 0x0D, 0x0D, 0x0D, 0x64, 0x66, 
  0x61, 0x53, 0x06, 0x44, 0x34, 0x6E, 0x69, 0x2F, 0x20, 0x14, 
  0x37, 0x6A, 0x49, 0x55, 0x36, 0x37, 0x23, 0x23, 0x2A, 0x6B, 
  0x73, 0x06, 0x78, 0x0B]

key3=[  0x3E, 0x7A, 0x40, 0x64, 0x27, 0x25, 0x48, 0x04, 0x4F, 0x63, 
  0x19, 0x60, 0x0B, 0x3A, 0x75, 0x5D, 0x11, 0x4E, 0x07, 0x44, 
  0x30, 0x4C, 0x4B, 0x06, 0x5F, 0x73, 0x0D, 0x1A, 0x38, 0x08, 
  0x34, 0x78, 0x45, 0x47, 0x58, 0x3B, 0x74, 0x7D, 0x2C, 0x2B, 
  0x4A, 0x3C, 0x29, 0x13, 0x01, 0x3F, 0x03, 0x61, 0x70, 0x52, 
  0x65, 0x09, 0x22, 0x00, 0x7F, 0x59, 0x6C, 0x77, 0x72, 0x3D, 
  0x32, 0x55, 0x41, 0x49]


for i in range(len(key3)):
	key2[i]^=key3[i]
print(key2)
print(''.join(map(chr,key2)))		#base64变表码

结果:
在这里插入图片描述
.
.
然后把变形码表替换传统base64加密码表,这里用的是我以前写过的base64 python编码实现

base64="sZGad02wvbf3mtxEq8rDhYK47LueClz1Jig6ypHM+o/W5QjNPFRckUInOTXVAS9B"			#准备好base64的基表
def encryption(inputstring):		#定义加密函数
	ascii=['{:0>8}'.format(str(bin(ord(i))).replace('0b','')) for i in inputstring]	#把每个输入字符保证8位一个,才能3*8变4*6。
#{:0>8}是右对齐8位然后左边补0,因为python是自己判断数据大小类型的,所以必须强制满足8位。bin转化二进制会带0b前缀,所以要用replace('0b','')去掉。
	encrystr='' #while外的变量,返回base64加密后的字符串
	equalnumber=0 #while外的变量,记录拆分后不足4的倍数时需要补齐的等号个数
	while ascii:
		subascii=ascii[:3] #用一个子列表subascii每次取输入的三位进行操作,前面操作后每位都是8位
		while len(subascii)<3:   #这里其实是最后一段截取中才会用上的,不满足3位时要单独取出,记录equalnumber数量用于后期补'='号,然后补齐8位的0免得干扰后面3*8拆分成4*6
			equalnumber+=1		#计算要补‘=’的个数
			subascii+=['0'*8]	#补8个0来填充够3的倍数,这然后面就不会出错。			
		substring=''.join(subascii)#用substring合并subascii的3个8位,准备进行拆分操作
		encrystringlist=[substring[x:x+6] for x in [0,6,12,18]]   #开始进行3*8变4*6的拆分,每次拆分一组24位。
		encrystringlist=[int(x,2) for x in encrystringlist]		#把前面拆分的6位一组转成10进制,就不用进行位数补齐操作了,这是用来后面对应base64基表的下标。
		if equalnumber:
			encrystringlist=encrystringlist[0:4-equalnumber]	#如果前面不足3字符补了0,比如2个8位字符16位,拆分后就要用3个6位共18位,所以有效位是4-equalnumber
		encrystr+=''.join(base64[x] for x in encrystringlist)	#这里encrystringlist已经在前面拆分成4*6且转换成10进制了,所以对应基表的下标。
		ascii=ascii[3:]		#每次向后取3个列表元素,对应while循环条件
	encrystr+='='*equalnumber		#因为前面encrystringlist[0:4-equalnumber]去掉了补0位,所以这里最后补齐'='号
	return encrystr

def decryption(inputstring):
	ascii=['{0:0>6}'.format(str(bin(base64.index(i))).replace('0b',''))for i in inputstring if i!='=']#从加密字符中取除补位'='之外加密字符,即6位生成的base64基表下标的数,按6位一组排列,准备拆分
	decrystr=''#准备while外的解密后的字符
	equalnumber=inputstring.count('=')#这里计数补位的'='号的个数,后面不够8位时会根据'='号补加位数。
	while ascii:	
		subascii=ascii[:4]#取加密字符的4个6位一组共24位准备拆分合并成3*8
		substring=''.join(subascii)#先连成一串24位
		if len(substring)%8!=0:
			substring=substring[0:-1*equalnumber*2] 
#截取到倒数第equalnumber*2个元素。对不足8位的组补位,因为加密时1个8位要来2个6位,两个'='号,截取到8位就是倒数第4位1*2*2。2个8位要3个6位,要一个'='号,截取到16位就是倒数第2位1*1*2。			
		decrystringlist=[substring[x:x+8] for x in [0,8,16]]#开始进行4*6变3*8的拆分,每次拆分4个6位一组24位。
		decrystringlist=[int(x,2) for x in decrystringlist if x]#把前面拆分的8位一组转成10进制,用来对应十进制ASCII码,if x功能不清楚,但不可缺少,应该是要排除空格吧。
		decrystr+=''.join([chr(x) for x in decrystringlist])#这里decrystringlist已经在前面拆分成3*8且转换成10进制了,现在转换成ASCII码。
		ascii=ascii[4:]#每次向后取4个列表元素,对应while循环条件
	return decrystr

if __name__=="__main__":
	#print(encryption('abcd'))
	print(decryption('r60ihyZ/m4lseHt+m4t+mIkc'))

.
结果:
在这里插入图片描述
.
.
所以最终flag

flag{ssddddwddddssas-J1aR@j1w@nch1sh3m3}

.
.
总结:

1:
(这里积累第一个经验)
上图分析了前半部分,现在跟踪那个关键自定义函数v10 = sub_401192(v5);这是对前15个字符组成的迷宫进行操作。
.
点进去查看逻辑,是一个走迷宫,输入15步的wasd,要从A开始走,必须走到.上,最后必须走到B上。
.
根据11可以判断是二维数组,这也是我第一次学到迷宫的维数判断。因为一个走11步,另一个一步一步走,所以一维字符串最后得出二维迷宫,长11宽5的5*11型,sw字符一下走11步就是上下移动ad一下走1步就是左右移动。也就是说走得多的就是行移动,走得少的就是列移动。
.
A********
.*
*.
*******
******B
.
手扒得到ssddddwddddssas
在这里插入图片描述
在这里插入图片描述

2:
(这里积累第二个经验)
这里的dest是在内存中的,这里静态修补我不太会,因为destsrc都是在栈中的所以直接用动态调试,用前面得出的前半部分搭配其它字符来运行ssddddwddddssas-666666666666666666
在这里插入图片描述

解毕!敬礼!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值