NSSCTF-[NSSRound#X Basic]ez_z3 && [MoeCTF 2022]Art &&[HDCTF2023]basketball

目录

NSSCTF-[NSSRound#X Basic]ez_z3

 [MoeCTF 2022]Art

[HDCTF2023]basketball


NSSCTF-[NSSRound#X Basic]ez_z3

题目下载:下载

查壳:

发现有upx壳,但是使用upx -d命令不能脱壳,载入十六进制编辑器查看
把XYU改为UPX,就可以成功使用upx -d脱壳了。

载入IDA(部分使用了自定义命名)

 倒着往前看,输出“you get the flag”就要dword_1400254C4==1,而dword_1400254C4由sub_1400110E6()函数赋值而来,所以跟进sub_1400110E6()函数:

 要想返回1,则这个等式成立,即这两个数组相同。

返回到主函数,看其他的函数

看一下sub_1400112F8()函数:

这就是一个简单的异或。

看sub_14001103C()函数:是很多等式,可以用z3求出a1[0]-a1[19]。

看一下sub_140014CC0()函数:这是一个指数折半快速幂求法,可以参考:快速幂算法 超详细教程_qascetic的博客-CSDN博客
我在这里在简单阐述一下上面的这个快速幂流程,具体地大家可以参考上面的链接。a1是底数,a2是指数,首先判断指数是奇数还是偶数。

如果是偶数即if条件不成立,那么就a1*a1底数变为平方,a2>>2相当于除以2,指数折半,这样一直执行下去,直到a2为1,是奇数,这样就执行if的子句1把结果赋值给v3返回。

如果是奇数,就先分离出一个,然后在采用快速幂法,最后通过v3返回。

好了关键的函数都分析完了,整体思路就是:

1.先用z3约束器求出a1数组的值,也即异或操作里的a1数组
2.通过异或操作,a1已知,求出dword_140025520[]数组
3.dword_140025520[]已知,通过快速幂爆破出str

所以代码如下

from z3 import *
#z3约束器
a1=[0]*20
for i in range(20):
    a1[i]=Int('a1['+str(i)+']')

s = Solver()
s.add((20 * a1[19] * 19 * a1[18]
      + 14 * a1[13]
      + 13 * a1[12]
      + 11 * a1[10] * 10 * a1[9]
      + 30 * a1[5]
      + 5 * a1[4]
      + a1[0]
      + 2 * a1[1]
      - 3 * a1[2]
      - 4 * a1[3]
      - 7 * a1[6]
      + 8 * a1[7]
      - 9 * a1[8]
      - 12 * a1[11]
      - 16 * a1[15] * 15 * a1[14]
      - 17 * a1[16]
      - 18 * a1[17]) == 2582239)
s.add((20 * a1[19] * 19 * a1[18]
      + 14 * a1[13]
      + 13 * a1[12]
      + 11 * a1[10] * 10 * a1[9]
      + 30 * a1[5]
      - 7 * a1[6]
      + 8 * a1[7]
      - 9 * a1[8]
      + 5 * a1[4]
      + 3 * a1[2]
      + 2 * a1[1] * a1[0]
      - 4 * a1[3]
      - 12 * a1[11]
      - 16 * a1[15] * 15 * a1[14]
      - (18 * a1[17]
         + 17 * a1[16])) == 2602741)
s.add((19 * a1[18]
      + 18 * a1[17]
      + 14 * a1[13] * 13 * a1[12]
      + 12 * a1[11] * 11 * a1[10]
      + 9 * a1[8]
      + 7 * a1[6] * 30 * a1[5]
      + a1[0]
      - 2 * a1[1]
      - 4 * a1[3] * 3 * a1[2]
      - 5 * a1[4]
      + 8 * a1[7]
      - 10 * a1[9]
      - 15 * a1[14]
      - 17 * a1[16] * 16 * a1[15]
      - 20 * a1[19]) == 2668123)
s.add((20 * a1[19] * 19 * a1[18]
      + 14 * a1[13]
      + (13 * a1[12] + 11 * a1[10] - 12 * a1[11]) * 10 * a1[9]
      + 30 * a1[5]
      + 5 * a1[4]
      + a1[0]
      + 2 * a1[1]
      - 3 * a1[2]
      - 4 * a1[3]
      - 7 * a1[6]
      + 8 * a1[7]
      - 9 * a1[8]
      - 16 * a1[15] * 15 * a1[14]
      - 17 * a1[16]
      - 18 * a1[17]) == 2520193)
s.add((18 * a1[17]
      + 17 * a1[16]
      + 15 * a1[14]
      + 13 * a1[12] * 12 * a1[11]
      + 10 * a1[9]
      + 9 * a1[8] * 8 * a1[7]
      + 3 * a1[2] * 2 * a1[1] * a1[0]
      - 4 * a1[3]
      - 5 * a1[4]
      - 30 * a1[5]
      - 7 * a1[6]
      - 11 * a1[10]
      - 14 * a1[13]
      - 16 * a1[15]
      - 19 * a1[18]
      - 20 * a1[19]) == 8904587)
s.add((18 * a1[17]
      + 7 * a1[6] * 30 * a1[5] * 5 * a1[4]
      + 4 * a1[3]
      + 8 * a1[7]
      + a1[0]
      - 2 * a1[1]
      - 3 * a1[2]
      - 9 * a1[8]
      - 11 * a1[10] * 10 * a1[9]
      - 16 * a1[15] * (13 * a1[12] + 12 * a1[11] - 14 * a1[13] - 15 * a1[14])
      - 17 * a1[16]
      - 19 * a1[18]
      - 20 * a1[19]) == 1227620874)
s.add((20 * a1[19] * 19 * a1[18]
      + 17 * a1[16]
      + 14 * a1[13]
      + 13 * a1[12]
      + 12 * a1[11] * 11 * a1[10] * 10 * a1[9]
      + 7 * a1[6] * 30 * a1[5]
      + 5 * a1[4]
      + 3 * a1[2]
      + a1[0]
      + 2 * a1[1]
      + 4 * a1[3]
      + 8 * a1[7]
      - 9 * a1[8]
      - 16 * a1[15] * 15 * a1[14]
      - 18 * a1[17]) == 1836606059)
s.add((20 * a1[19] * 19 * a1[18]
      + 16 * a1[15] * 15 * a1[14]
      + 14 * a1[13]
      + 13 * a1[12]
      + 12 * a1[11]
      + 7 * a1[6] * 30 * a1[5]
      + 5 * a1[4]
      + 2 * a1[1] * a1[0]
      - 3 * a1[2]
      + 4 * a1[3]
      + 8 * a1[7]
      - 9 * a1[8]
      - 10 * a1[9]
      - 11 * a1[10]
      - 17 * a1[16]
      - 18 * a1[17]) == 8720560)
s.add((20 * a1[19] * 19 * a1[18]
      + 14 * a1[13]
      + 13 * a1[12]
      + 11 * a1[10] * (10 * a1[9] + 30 * a1[5] + 5 * a1[4] + 4 * a1[3] - 7 * a1[6] + 8 * a1[7] - 9 * a1[8])
      + a1[0]
      + 2 * a1[1]
      - 3 * a1[2]
      - 12 * a1[11]
      - (16 * a1[15] - 17 * a1[16] - 18 * a1[17]) * 15 * a1[14]) == 11387045)
s.add((20 * a1[19] * 19 * a1[18]
      + 16 * a1[15] * 15 * a1[14]
      + 14 * a1[13]
      + 11 * a1[10] * 10 * a1[9]
      + 9 * a1[8]
      + 3 * a1[2]
      + a1[0]
      - 2 * a1[1]
      + 4 * a1[3]
      - 5 * a1[4]
      - 30 * a1[5]
      - 7 * a1[6]
      + 8 * a1[7]
      - 12 * a1[11]
      - 13 * a1[12]
      - 17 * a1[16]
      - 18 * a1[17]) == 7660269)
s.add((20 * a1[19] * 19 * a1[18]
      + 14 * a1[13]
      + 13 * a1[12]
      + 11 * a1[10] * 10 * a1[9]
      - 12 * a1[11]
      + a1[0]
      + 2 * a1[1]
      - (4 * a1[3] * 3 * a1[2]
         - 5 * a1[4]
         - 30 * a1[5])
      - 7 * a1[6]
      + 8 * a1[7]
      - 9 * a1[8]
      - 16 * a1[15] * 15 * a1[14]
      - 17 * a1[16]
      - 18 * a1[17]) == 2461883)
s.add((14 * a1[13]
      + 11 * a1[10] * 10 * a1[9]
      + 9 * a1[8] * 8 * a1[7]
      + 7 * a1[6]
      + 2 * a1[1] * a1[0]
      - 4 * a1[3] * 3 * a1[2]
      - 5 * a1[4]
      - 30 * a1[5]
      - 12 * a1[11]
      - 13 * a1[12]
      - 15 * a1[14]
      - 17 * a1[16] * 16 * a1[15]
      - 18 * a1[17]
      - 19 * a1[18]
      - 20 * a1[19]) == -966296)
s.add((14 * a1[13]
      + 13 * a1[12]
      + (11 * a1[10] * 10 * a1[9] + 30 * a1[5] + 5 * a1[4] + 3 * a1[2] + 4 * a1[3] - 7 * a1[6] + 8 * a1[7] - 9 * a1[8])
      * 2
      * a1[1]
      + a1[0]
      - 12 * a1[11]
      - 15 * a1[14]
      - 16 * a1[15]
      - 17 * a1[16]
      - 18 * a1[17]
      - 20 * a1[19] * 19 * a1[18]) == 254500223)
s.add((16 * a1[15] * 15 * a1[14]
      + 14 * a1[13]
      + 11 * a1[10] * 10 * a1[9]
      + 7 * a1[6] * 30 * a1[5]
      + a1[0]
      - 2 * a1[1]
      - 3 * a1[2]
      - 5 * a1[4] * 4 * a1[3]
      + 8 * a1[7]
      - 9 * a1[8]
      - 12 * a1[11]
      - 13 * a1[12]
      - 17 * a1[16]
      - 18 * a1[17]
      - 19 * a1[18]
      - 20 * a1[19]) == 6022286)
s.add((18 * a1[17]
      + 16 * a1[15]
      - 17 * a1[16]
      + 14 * a1[13]
      + 12 * a1[11]
      + 11 * a1[10] * 10 * a1[9]
      + 30 * a1[5]
      + 5 * a1[4]
      + 4 * a1[3] * 3 * a1[2]
      + 2 * a1[1] * a1[0]
      - 9 * a1[8] * 8 * a1[7] * 7 * a1[6]
      - 13 * a1[12]
      - 15 * a1[14]
      - 19 * a1[18]
      - 20 * a1[19]) == -636956022)
s.add((20 * a1[19] * 19 * a1[18]
      + 13 * a1[12]
      + 12 * a1[11]
      + 11 * a1[10] * 10 * a1[9]
      + 7 * a1[6]
      + 30 * a1[5]
      + 5 * a1[4]
      + 3 * a1[2] * 2 * a1[1] * a1[0]
      - 4 * a1[3]
      - 9 * a1[8] * 8 * a1[7]
      - 14 * a1[13]
      - 15 * a1[14]
      - 16 * a1[15]
      - 17 * a1[16]
      - 18 * a1[17]) == 10631829)
s.add((20 * a1[19] * 19 * a1[18]
      + 16 * a1[15]
      - 17 * a1[16]
      - 18 * a1[17]
      + 15 * a1[14] * 14 * a1[13]
      + 13 * a1[12]
      + 11 * a1[10] * 10 * a1[9]
      - 12 * a1[11]
      + 7 * a1[6]
      + (4 * a1[3] - 5 * a1[4] - 30 * a1[5]) * 3 * a1[2]
      + a1[0]
      + 2 * a1[1]
      + 8 * a1[7]
      - 9 * a1[8]) == 6191333)
s.add((14 * a1[13]
      + 10 * a1[9] * 9 * a1[8] * 8 * a1[7]
      + 5 * a1[4]
      + 4 * a1[3] * 3 * a1[2]
      + 2 * a1[1] * a1[0]
      - 7 * a1[6] * 30 * a1[5]
      - 11 * a1[10]
      - 13 * a1[12] * 12 * a1[11]
      - 16 * a1[15] * 15 * a1[14]
      - 18 * a1[17] * 17 * a1[16]
      - 20 * a1[19] * 19 * a1[18]) == 890415359)
s.add((20 * a1[19]
      + 19 * a1[18]
      + 18 * a1[17]
      + 16 * a1[15]
      - 17 * a1[16]
      + 12 * a1[11]
      + 11 * a1[10]
      + 10 * a1[9]
      + 9 * a1[8]
      + 30 * a1[5]
      + a1[0]
      + 4 * a1[3] * 3 * a1[2] * 2 * a1[1]
      - 5 * a1[4]
      - 7 * a1[6]
      + 8 * a1[7]
      - 13 * a1[12]
      - 14 * a1[13]
      - 15 * a1[14]) == 23493664)
s.add((20 * a1[19] * 19 * a1[18]
      + 13 * a1[12]
      + 12 * a1[11]
      + 10 * a1[9]
      + 3 * a1[2] * 2 * a1[1]
      + a1[0]
      - 4 * a1[3]
      - 5 * a1[4]
      + 8 * a1[7] * 7 * a1[6] * 30 * a1[5]
      - 9 * a1[8]
      - 11 * a1[10]
      - 14 * a1[13]
      - 16 * a1[15] * 15 * a1[14]
      - 17 * a1[16]
      - 18 * a1[17]) == 1967260144)
for i in range(20):
    s.add(a1[i]<=0xFF)      #每个字符是char类型
    s.add(a1[i]>=0)
if s.check() == sat:
    print(s.model())

#求dword_140025520[]
a1=[104,97,104,97,104,97,116,104,105,115,105,115,102,97,99,107,102,108,97,103][::-1]
d4D0=[4615, 19616, 20257, 57, 107811, 570, 2342, 19623, 25952,54, 108955, 19624, 113632, 14085, 2342, 30675, 39576,
      25979, 24, 2833]
#倒序
d520=[]

for i in range(len(a1)):
    b=a1[i]^d4D0[i]
    d520.append(b)
print(d520)

#求str,即flag
flag=''
a3= [7, 7, 7, 9, 5, 6, 7, 7, 7, 9, 7, 7, 5, 7, 7, 7, 5, 7, 9, 7]

for i in range(20):   #j是要求的
    for k in range(32,128):
        v3=1
        k1=k
        a2=a3[i]
        while(a2):
            if (a2 & 1):
                v3=v3*k1
            k1=k1*k1%1000
            a2=a2>>2
        if v3==d520[i]:
            flag+=chr(k)
            break
print(flag)



 [MoeCTF 2022]Art

题目下载:下载

首先看一看题目标签和描述,可以获得一些小提示

可以知道考点是upx和dfs。

脱壳:直接upx -d 文件名就可以脱壳,载入IDA

 从上面提示可以知道这个方程有多个解,所以需要爆破来解,其中只有一个加密算法且存在多解的情况,所以采用dfs爆搜,代码如下:

check = [0x2, 0x18, 0xf, 0xf8, 0x19, 0x4, 0x27, 0xd8, 0xeb, 0x0, 0x35, 0x48, 0x4d, 0x2a, 0x45, 0x6b, 0x59, 0x2e, 0x43, 0x1, 0x18, 0x5c, 0x9, 0x9, 0x9, 0x9, 0xb5, 0x7d]
tmp = [0]*28
tmp[len(check)-1]=check[-1]
#(check[-1])

def DFS(deep):
    if deep == 0:
        print(bytes(tmp))
    else:
        for i in range(0xff):
            if (i ^ 0x19) ^ (i % 0x11 + tmp[deep]) == check[deep - 1]:
                #print(i)
                tmp[deep - 1] = i
                DFS(deep - 1)
DFS(len(check)-1)

[HDCTF2023]basketball

题目下载:下载

载入IDA,先看第一部分

 首先获得两个key,然后进行输入,输入到s数组。进入f()函数,

进行异或操作,里面有一个text_66函数,跟进:

容易知道text_66是辗转相除,这里的关键是求这两个key,采用爆破枚举方式,代码如下:
 

str=[85, 105, 104, 120, 33, 104, 114, 33, 96, 33, 105, 98, 101, 117, 33, 124, 105, 106, 117, 33, 72, 33, 105, 100, 109, 113, 43, 120, 110, 116, 33, 104, 114, 43, 115, 100, 108, 104, 111, 101, 33, 120, 110, 116, 33, 117, 110, 33, 98, 73, 100, 98, 106, 33, 117, 105, 100, 33, 96, 115, 115, 96, 120, 33, 96, 111, 101, 33, 117, 105, 115, 100, 100, 33, 111, 116, 102, 99, 100, 115, 114, 33, 98, 96, 111, 33, 119, 98, 100, 118, 33, 96, 114, 33, 96, 33, 102, 115, 110, 116, 113]

def f(k1_0,k2_0):
    for i in range(len(str)):
        k1_0 = (str[i] + k1_0) % 300
        k2_0 = (str[i] + k2_0) % 300
        str[i] ^= text_66(k1_0, k2_0)

def text_66(a,b):
    aa=a
    ba=b
    if a<b:
        aa,ba=ba,aa
    if ba:
        result = text_66(ba, aa % ba)
    else:
        result = aa
    return result

for x in range(100):
    for y in range(100):
        str=[85, 105, 104, 120, 33, 104, 114, 33, 96, 33, 105, 98, 101, 117, 33, 124, 105, 106, 117, 33, 72, 33, 105, 100, 109, 113, 43, 120, 110, 116, 33, 104, 114, 43, 115, 100, 108, 104, 111, 101, 33, 120, 110, 116, 33, 117, 110, 33, 98, 73, 100, 98, 106, 33, 117, 105, 100, 33, 96, 115, 115, 96, 120, 33, 96, 111, 101, 33, 117, 105, 115, 100, 100, 33, 111, 116, 102, 99, 100, 115, 114, 33, 98, 96, 111, 33, 119, 98, 100, 118, 33, 96, 114, 33, 96, 33, 102, 115, 110, 116, 113]
        f(x,y)
        flag=1
        for i in str:
            if i>=127 or i<32:
                flag=0
                break
        if flag==1:
            print(bytes(str))

 观察结果:I help you is remind you to check the array and three numbers can view as a group可以知道提示三个数可以看成一组,就可以想到RGB(之前没见过,所以我不能反应过来这个是RGB)

在根据给的hint:
可以写有关RGB的代码(这里学习一下)

from PIL import Image

with open('array.txt绝对地址', 'r') as f:
    data = f.readlines()  # txt中所有字符串读入data

    for line in data:
        list = line.split(' ')  # 将单个数据分隔开存好
f.close()

x = 637  # x坐标  通过对txt里的行数进行整数分解 宽度
y = 561  # y坐标  x * y = 行数              高度

im = Image.new("RGB", (x, y))  # 创建图片

index = 0

for j in range(0, y):  # 通过每个rgb点生成图片
    for i in range(0, x):
        im.putpixel((i, j), (int(list[index]), int(list[index + 1]), int(list[index + 2])))  # 将rgb转化为像素
        index += 3

im.show()

 运行后发现图片

再根据提示

 message是英文形式,根据我想打篮球得到:I want to play basketball,又因为要凑够28个,所以是I want to play basketballI w

在看main第二部分代码:

 刚才得到的便是str数组,num数组又已知,可以异或得到flag

flag=[1, 100, 52, 53, 40, 15, 4, 69, 46, 109, 47, 40, 55, 55, 92, 94, 62, 70, 23, 72, 8, 82, 29, 65, 16, 117, 117, 10]
xor_key='I want to play basketballI w'
for i in range(len(flag)):
    flag[i]^=ord(xor_key[i])
print(bytes(flag))

#HDCTF{$1AM_DVN|<_5|-|0|-|<U}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值