“安洵杯“全国精英赛-SYCTF2023-REVERSE(AK)


(还是太菜啦~,做题太慢了,有两道题赛后才出

ezr3

(赛后出的)
首先010查看下文件
在这里插入图片描述
发现有HCK字眼,猜测是UPX加壳,搜索下HCK
在这里插入图片描述
确认是UPX4.02版本加的壳,将HCK替换为UPX,然后UPX脱壳即可
IDA分析代码,在main函数中可以找到两个关键函数,v()和p()函数
在这里插入图片描述
在v()函数中,对程序中的一些数据进行异或操作
在这里插入图片描述
在p()函数中,首先对输入的数据以字节为单位进行操作,将前四位和后四位进行交换,例如0x7b变为0xb7,然后进行异或操作,最后验证flag是否正确
在这里插入图片描述

memStore=[3361, 0, 157, 0, 2379, 0, 969, 0, 3135, 0, 6121, 0, 4878, 0, 136, 0, 1158, 0, 8239, 0, 8752, 0, 9396, 0, 2225, 0, 2719, 0, 6866, 0, 9195, 0, 3198, 0, 1067, 0, 1471, 0, 4412, 0, 1097, 0, 5969, 0, 2766, 0, 6292, 0, 8330, 0, 3714, 0, 1725, 0, 3310, 0, 9094, 0, 5076, 0, 273, 0, 3356, 0, 9102, 0, 5977, 0, 299, 0, 8525, 0, 46656, 0]
auth=[244841, 868256, 239946, 281343, 283220, 52689, 6165, 15112, 460904, 812384, 415330, 546248, 56566, 19686, 1371842, 184278, 206694, 1373882, 155241, 436643, 1187517, 366876, 327702, 19005, 619653, 577696, 243990, 347224, 618388, 66356, 896290, 307764, 196246, 996300, 1229288, 1347486]
flag=[]

v2=0
for i in range(0,len(auth),6):
    for j in range(6):
        auth[i+j]^=memStore[v2+j*12]
    v2+=2

v2=0
for i in range(0,len(auth),6):
    for j in range(6):
        flag.append(auth[i+j]//memStore[(v2+j*6)*2])
    v2+=1

for i in range(len(flag)):
    flag[len(flag)-1-i]^=flag[i]
    flag[len(flag)-1-i]=(flag[len(flag)-1-i]>>4|flag[len(flag)-1-i]<<4)&0xff

print(bytes(flag))#SYC{1_w4Nn4_buy_4_c4R_G1V3_M3_50w_$}

BabySnake

(赛后出的)
刚开始看还以为很简单,以为patch个值就能出,刚开始直接改了判断是否吃到金币的逻辑,让其不管在哪都当作吃到金币来执行
由于地图不够大,即便吃满整个屏幕分数也不够,所以还要把这里的判断nop掉,开启无敌模式(x
在这里插入图片描述

没想到还是太年轻了,每次跑出的flag都不一样,原来是出题人加了逻辑验证,以此来生成随机数,先看看主要函数
在这里插入图片描述
sub_401E40函数判断是否吃到金币
sub_401B90函数按照我的理解是,先判断了蛇头部的位置是否在生成的金币位置上,如果是,则按照正常执行,否则获取当前时间并将其作为随机数种子
在这里插入图片描述
于是我将这三处函数逻辑改了下,不过得在调试中进行修改,得先让程序执行一遍,让数值正常定义
在这里插入图片描述
开始patch程序,先将以下代码nop掉,让其无论是撞墙还是碰到身子都能继续运行
在这里插入图片描述
patch前:
在这里插入图片描述
patch后:
在这里插入图片描述

将此处改为jnz判断,让其即使没吃到金币,也正常加分,将84改为85即可
在这里插入图片描述
在判断位置是否和金币位置一样的地方,把逻辑改为直接跳转到正常吃到金币后执行的代码
将前五个字节patch成E8 3D 00 00 00 ,然后运行
在这里插入图片描述
在调试中吃到金币会报异常,改为以下接着运行即可
在这里插入图片描述
然后等分数自己加就好
在这里插入图片描述
分数够后,得到flag
在这里插入图片描述

ez_cpp

关键函数
在这里插入图片描述
调试跟进函数看看,第一处sub_CD1136函数是做凯撒加密,key为13
第二处sub_CD1136函数根据opcode值做异或或者减法操作
sub_CD1177函数做以下操作
在这里插入图片描述
于是先爆破出凯撒加密后的密文

result=[]
opcode=[0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

cmp=[0x22, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0xFF, 0xFF, 0x72, 0x00, 
  0x00, 0x00, 0xE6, 0xFF, 0xFF, 0xFF, 0x52, 0x00, 0x00, 0x00, 
  0x8C, 0xFF, 0xFF, 0xFF, 0xF2, 0xFF, 0xFF, 0xFF, 0xD4, 0xFF, 
  0xFF, 0xFF, 0xA6, 0xFF, 0xFF, 0xFF, 0x0A, 0x00, 0x00, 0x00, 
  0x3C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0xA6, 0xFF, 
  0xFF, 0xFF, 0x9C, 0xFF, 0xFF, 0xFF, 0x86, 0xFF, 0xFF, 0xFF, 
  0x24, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0xD4, 0xFF, 
  0xFF, 0xFF, 0x22, 0x00, 0x00, 0x00, 0xB6, 0xFF, 0xFF, 0xFF, 
  0x14, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0xCE, 0xFF, 
  0xFF, 0xFF, 0xAC, 0xFF, 0xFF, 0xFF, 0x14, 0x00, 0x00, 0x00, 
  0x6A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x7C, 0x00, 
  0x00, 0x00, 0xE4, 0xFF, 0xFF, 0xFF, 0xE4, 0xFF, 0xFF, 0xFF, 
  0xE4, 0xFF, 0xFF, 0xFF, 0x1E, 0x00, 0x00, 0x00]

for i in range(32):
    for j in range(0x100):
        if i<=16:
            if i>=16:
                a=j^4
            else:
                if opcode[i*4]==1:
                    a=j^9
                else:
                    a=j-2
        else:
            if opcode[i*4]==1:
                a=j^6
            else:
                a=j-5
        v2=0
        v3=0
        v4=7
        a2=8
        while v3<a2:
            v2|=((a>>v3)&1)<<v4
            v3+=1
            v4-=1
        a=1^(v2+1)
        if a==cmp[i*4]:
            result.append(j)

print(bytes(result))#b'FLPnL3F-lR5-l0h-F0Ir-Gu3-P9C!!!}'

接着凯撒解密
在这里插入图片描述
把a改为{,即为flag
在这里插入图片描述

3D_maze

一道迷宫题,首先根据迷宫规律打印出迷宫
在这里插入图片描述

#迷宫数据
a=[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00...]
  
maze=[]

for i in range(0,len(a),4):
    maze.append(a[i])
    
for i in range(len(maze)):
    if i!=0 and i%10==0:
        print()
    print(maze[i],end='')

接着手搓路径

#0
0010000000	v4 = 9
0010000100
0010111100
0010100000
0010111111
0010100000
0011111111
0050100000	
0003000000	 v3 = 1
0001000000	 D
#1
0000000000
0111100000
0100111111
0100000000
1100000000
0000000000
1111100000
0000000000	 v3 = 2
0000000000	 D
0000000000   v5=0
#2
1000000000
1000000000
1001010001
0010101010
0010000100
0001000100
0000100100
0010100100	 v5=0
0001000100	 W
0000000000   v3=4
#3
0010000000
0010000000
0010110000
0011001000
0011000000
0011000000
0011001000	 v3 = 5
0010110000	 S
0010000000	 v4 = 0
0010000000   v5 = 2
#4
0000000011
0000000010
1111111110
0000000000
0000000000
0000000000
0000000000	
0000000000	v3 = 3
0000000000	 A
0000000000	v5=9
#5
0001000000
0001000000
0001000000
0001000000
0001000000
0011000000
0010000000	W
1110000000	v3 = 0
0000000000	v4 = 7
0000000000	v5 = 0

wddwwdddddDdwwwdddsdddddDwwWassaaaaaaaaAsssssssssSddwwdwwwwwWw
SYCTF{wddwwdddddDdwwwdddsdddddDwwWassaaaaaaaaAsssssssssSddwwdwwwwwWw}

babythread

RC4加密在这里插入图片描述
先随便输入字符,取出rc4加密后的字符,再进行异或操作还原flag

cmp=[0xDE, 0x1C, 0x22, 0x27, 0x1D, 0xAE, 0xAD, 0x65, 0xAD, 0xEF, 
  0x6E, 0x41, 0x4C, 0x34, 0x75, 0xF1, 0x16, 0x50, 0x50, 0xD4, 
  0x48, 0x69, 0x6D, 0x93, 0x36, 0x1C, 0x86, 0x3B, 0xBB, 0xD0, 
  0x4C, 0x91]

input='1'*32
result=[0xBC, 0x74, 0x50, 0x6D, 0x78, 0xF7, 0xAD, 0x27, 0xC3, 0xB7, 
  0x2C, 0x2F, 0x3D, 0x5A, 0x01, 0xA1, 0x54, 0x38, 0x3E, 0xD6, 
  0x17, 0x3B, 0x2E, 0xDB, 0x77, 0x59, 0xF8, 0x2B, 0xAB, 0xC0, 
  0x5C, 0xDD]

flag=[]

for i in range(len(result)):
	flag.append(ord(input[i])^result[i]^cmp[i])

print(bytes(flag))#SYC{Th1s_is_@_EasY_3ncryptO!!!!}

gowhere

一道go去符号题,先用GolangHelper还原符号
在main_main函数中找到主要对比逻辑
在这里插入图片描述
byte_55D1D0数组存放的是根据输入的字符串进行加密后得到的数组
unk_517E60数组存放的是密文
通过交叉引用,观察byte_55D1D0数组在哪被用到
在这里插入图片描述
分别跳转到相应位置下断点,然后调试理清代码逻辑
最后编写解密脚本

def enc1(input,x):
    for i in range(len(input)):
        input[i]=((input[i]+x)^0x17)
    return input

def enc2(input):
    input[0]+=2
    input[1]-=28
    input[2]^=0x47
    input[3]+=input[4]
    input[5]+=73
    input[6]+=12
    input[7]-=input[8]
    input[8]^=0x5a
    input[9]^=0x22
    input[10]+=20
    input[12]+=0x0FFFFFFAC
    input[13]^=4
    input[14]^=0x1c
    input[17]-=1
    input[27]^=0x11
    input[28]^=3
    for i in range(len(input)):
        input[i]&=0xff
    return input

def enc3(input):
    for i in range(len(input)//2):
        input[i],input[29-i]=input[29-i],input[i]
    return input

def enc1_rev(input,x):
    for i in range(len(input)):
        input[i]=((input[i]^0x17)-x)
    return input

def enc2_rev(input):
    input[0]-=2
    input[1]+=28
    input[2]^=0x47
    input[3]-=input[4]
    input[5]-=73
    input[6]-=12
    input[8]^=0x5a
    input[7]+=input[8]
    input[9]^=0x22
    input[10]-=20
    input[12]-=0x0FFFFFFAC
    input[13]^=4
    input[14]^=0x1c
    input[17]+=1
    input[27]^=0x11
    input[28]^=3
    for i in range(len(input)):
        input[i]&=0xff
    return input

def enc3_rev(input):
    for i in range(len(input)//2):
        input[i],input[29-i]=input[29-i],input[i]
    return input

#encode
# input=[]
# for i in '123456789012345678901234567890':
    # input.append(ord(i))
# input=enc1(input,0xa)
# input=enc2(input)
# input=enc3(input)
# input=enc2(input)
# input=enc3(input)
# input=enc1(input,0x10)
# input=enc2(input)
# input=enc3(input)
# input=enc2(input)
# input=enc3(input)
# print(input)

#decode
result=[0x4D, 0x63, 0x5D, 0x34, 0x43, 0x09, 0xA2, 0x77, 0x0A, 0xBF, 
  0xC9, 0xB3, 0xE9, 0x6F, 0x79, 0x7D, 0x7B, 0xE8, 0x99, 0x90, 
  0x43, 0x08, 0xBB, 0x99, 0x0E, 0x2E, 0xD4, 0x7B, 0x27, 0xB7]
result=enc3_rev(result)
result=enc2_rev(result)
result=enc3_rev(result)
result=enc2_rev(result)
result=enc1_rev(result,0x10)
result=enc3_rev(result)
result=enc2_rev(result)
result=enc3_rev(result)
result=enc2_rev(result)
result=enc1_rev(result,0xa)

print(bytes(result))#SYC{I_h0pE_you_cAn_FInd_d4eam}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值