HDCTF2023 - Reverse方向全WP

[HDCTF 2023]easy_re

在这里插入图片描述

UPX壳,脱壳

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一个base64编码。

在这里插入图片描述


[HDCTF 2023]easy_asm

在这里插入图片描述

在这里插入图片描述

ida打开后可以看到xor 10,al寄存器的内容不知道

在这里插入图片描述

WinHex打开,就能看到异或字符串了。

EXP:

enc = b'XTSDVkZecdOqOu#ciOqC}m'
flag = []
for i in range(len(enc)):
    flag.append(chr(enc[i]^0x10))
print("".join(flag))

# HDCTF{Just_a_e3sy_aSm}

[HDCTF 2023]fake_game

在这里插入图片描述

Pyinstaller编译的,用pyinstxtractor

在这里插入图片描述

将game.pyc反编译成py文件

在这里插入图片描述

在这里插入图片描述

找到对flag进行操作的俩个地方。

先用Z3求出xorr的值,然后再与flag异或得到真正的flag

EXP:

from z3 import *

xorr = [BitVec("num[%d]" % i, 32) for i in range(4)]
s = Solver()
s.add(xorr[0] * 256 - xorr[1] / 2 + xorr[2] * 23 + xorr[3] / 2 == 47118166)
s.add(xorr[0] * 252 - xorr[1] * 366 + xorr[2] * 23 + xorr[3] / 2 - 1987 == 46309775)
s.add(xorr[0] * 6 - xorr[1] * 88 + xorr[2] / 2 + xorr[3] / 2 - 11444 == 1069997)
s.add((xorr[0] - 652) * 2 - xorr[1] * 366 + xorr[2] * 233 + xorr[3] / 2 - 13333 == 13509025)

print(s.check())
for i in xorr:
    print(s.model()[i].as_long(), end=",")

# 178940,248,56890,2361
enc =[0x2bab4,0xbc,0xde79,0x96d,0x2baba,0x83,0xde7d,0x909,0x2bab3,0x9c,0xde65,0x949,0x2ba90,0xca,0xde43,0x90a,0x2ba8e,0xa7,0xde5c,0x909,0x2ba8e,0xa7,0xde6a,0x94f,0x2ba86,0xd9,0xde1b,0x944]
xorr=[178940,248,56890,2361]
flag = []
for i in range(len(enc)):
    flag.append(chr(enc[i] ^ xorr[i%4]))
print(''.join(flag))

# HDCTF{G0Od_pl2y3r_f0r_Pvz!!}

[HDCTF 2023]enc

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

sub_411523用了一个TEA加密

v9 就是 key,v7和v8是密文。

写个脚本逆向一下

#include <stdio.h>
#include <stdint.h>  // 使用uint32_t数据类型需要包含此头文件
#include <string.h>
#include<iostream>
using namespace std;
// 定义加密函数
void tea_decrypt(uint32_t *v, uint32_t *k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;  // 根据TEA算法,解密轮次的计算需要初始化sum
    uint32_t delta = 0x9e3779b9;
 
    for (i = 0; i < 32; i++) {
        v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
        v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
        sum -= delta;
    }
 
    v[0] = v0;
    v[1] = v1;
}
 
int main() {
    uint32_t enc[2]={0x60FCDEF7,0x236DBEC};
    uint32_t key[]={0x12,0x34,0x56,0x78};
    tea_decrypt(enc,key);
    cout<<enc[0];
    return 0;
}

得到 3

接着往下看,

在这里插入图片描述

在这里插入图片描述

不像是花指令,那应该就是SMC了,本来想用动调的,但这里加了反调试,不知道怎么去除,结合前面得到的key,找修改的地方。

在这里插入图片描述

在这里插入图片描述

最后找到,异或等于a3,可以知道a3 就是前面求出来的 3

写个idapython

for i in range(0x0041D000,0x0041E600):
    patch_byte(i,get_wide_byte(i)^3)
print('done')

之后,选中有用的数据U未定义一下,再P创建函数,F5反编译,得到。

在这里插入图片描述

这里是一个RC4加密

EXP:

def rc4_decrypt(ciphertext, key):
    # 初始化 S-box
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]

    # 初始化变量
    i = j = 0
    plaintext = []

    # 解密过程
    for byte in ciphertext:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = S[(S[i] + S[j]) % 256]
        plaintext.append(byte ^ k)

    return bytes(plaintext)


# 示例用法
encrypted_data = [0xF,0x94,0xAE,0xF2,0xC0,0x57,0xC2,0xE0,0x9A,0x45,0x37,0x50,0xF5,0xA0,0x5E,0xCB,0x2C,0x16,0x28,0x29,0xFE,0xFF,0x33,0x46,0xE,0x57,0x82,0x22,0x52,0x26,0x2B,0x6E,0xE4,0x82,0x24]
  # 替换成你的密文
encryption_key = b'you_are_master'  # 替换成你的密钥

decrypted_data = rc4_decrypt(encrypted_data, encryption_key)
print("Decrypted Data:", decrypted_data.decode('utf-8'))

# Decrypted Data: HDCTF{y0u_ar3_rc4_t3a_smc_m4ster!!}


[HDCTF 2023]double_code

在这里插入图片描述

在这里插入图片描述

打开来,慢慢看,start进去,一直进

在这里插入图片描述

找到一个Code

在这里插入图片描述

alloc:%p\n 在这里 接着进去,找到指向这里的指针。

在这里插入图片描述

找到了,根据output写个EXP:

enc = [0x48,0x67,0x45,0x51,0x42,0x7b,0x70,0x6a,0x30,0x68,0x6c,0x60,0x32,0x61,0x61,0x5f,0x42,0x70,0x61,0x5b,0x30,0x53,0x65,0x6c,0x60,0x65,0x7c,0x63,0x69,0x2d,0x5f,0x46,0x35,0x70,0x75,0x7d]
flag = []
for i in range(len(enc)):
    x = i % 5
    match x:
        case 0:
            flag.append(chr(enc[i]))
        case 1:
            flag.append(chr(enc[i]^0x23))
        case 2:
            flag.append(chr(enc[i]-2))
        case 3:
            flag.append(chr(enc[i]+3))
        case 4:
            flag.append(chr(enc[i]+4))
        case 5:
            flag.append(chr(enc[i]+25))
print("".join(flag))

# HDCTF{Sh3llC0de_and_0pcode_al1_e3sy}

[HDCTF 2023]买了些什么呢

在这里插入图片描述

题目运行起来,

在这里插入图片描述

一个01背包问题,动态规划,写个EXP解决。

def knapsack(weights, values, capacity):
    n = len(weights)
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]

    for i in range(1, n + 1):
        for w in range(capacity + 1):
            if weights[i - 1] <= w:
                dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1])
            else:
                dp[i][w] = dp[i - 1][w]

    selected_items = []
    i, w = n, capacity
    while i > 0 and w > 0:
        if dp[i][w] != dp[i - 1][w]:
            selected_items.append(i-1)
            w -= weights[i - 1]
        i -= 1
    return dp[n][capacity], selected_items


# 商品信息
weights = [2, 5, 10, 9, 3, 6, 2, 2, 6, 8, 2, 3, 3, 2, 9, 8, 2, 10, 8, 6, 4, 3, 4, 2, 4, 8, 3, 8, 4, 10, 7, 1, 9, 1, 5, 7, 1, 1, 7, 4]
values = [8, 1, 5, 9, 5, 6, 8, 2, 3, 7, 5, 4, 3, 7, 6, 7, 9, 3, 10, 5, 2, 4, 5, 2, 9, 5, 8, 10, 2, 9, 6, 3, 7, 3, 9,  6, 10, 1, 2, 9]

# 背包容量
capacity = 50

max_value, selected_items = knapsack(weights, values, capacity)

print("最大价值:", max_value)
print("选择的商品编号:", selected_items)
selected_items = selected_items[::-1]
for i in range(len(selected_items)):
    print(selected_items[i],end=' ')
    
# 最大价值: 116
# 选择的商品编号: [39, 36, 34, 33, 31, 26, 24, 22, 21, 18, 16, 13, 11, 10, 6, 4, 0]
# 0 4 6 10 11 13 16 18 21 22 24 26 31 33 34 36 39 

[HDCTF2023]basketball

在这里插入图片描述

在这里插入图片描述

俩处加密,第一处对一句话进行一个f(x,y)的加密,这里加密用到了俩个伪随机数。加密后的密文是Str2

在这里插入图片描述

写一个爆破脚本枚举一下

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:
        return text_66(ba, aa % ba)
    else:
        return aa


for x in range(100):
    for y in range(100):
        str = [0x55, 0x69, 0x68, 0x78, 0x21, 0x68, 0x72, 0x21, 0x60, 0x21,
               0x69, 0x62, 0x65, 0x75, 0x21, 0x7C, 0x69, 0x6A, 0x75, 0x21,
               0x48, 0x21, 0x69, 0x64, 0x6D, 0x71, 0x2B, 0x78, 0x6E, 0x74,
               0x21, 0x68, 0x72, 0x2B, 0x73, 0x64, 0x6C, 0x68, 0x6F, 0x65,
               0x21, 0x78, 0x6E, 0x74, 0x21, 0x75, 0x6E, 0x21, 0x62, 0x49,
               0x64, 0x62, 0x6A, 0x21, 0x75, 0x69, 0x64, 0x21, 0x60, 0x73,
               0x73, 0x60, 0x78, 0x21, 0x60, 0x6F, 0x65, 0x21, 0x75, 0x69,
               0x73, 0x64, 0x64, 0x21, 0x6F, 0x74, 0x66, 0x63, 0x64, 0x73,
               0x72, 0x21, 0x62, 0x60, 0x6F, 0x21, 0x77, 0x62, 0x64, 0x76,
               0x21, 0x60, 0x72, 0x21, 0x60, 0x21, 0x66, 0x73, 0x6E, 0x74,
               0x71, 0x00]
        f(x, y)
        for i in str:
            if i < 33 or i > 127:
                break
            else:
                print(''.join(chr(j) for j in str))

得到的结果不是很准确,

在这里插入图片描述

只能大概看出,this is a hint i help you is remind you to check the array and three numbers can view as a group

翻译后大概就是,数组三个为一组?附件有一个array.txt。

附件内

在这里插入图片描述

全是300以内的数字,结合 三个为一组,联想到RGB。可以利用python的PTL库来构造一张彩色图像。

from PIL import Image

# 从文件中读取数据
with open('C:\\Users\\Sciurdae\\Downloads\\basketball\\array.txt', 'r') as f:
    data = f.read().split()  # 假设数据是空格分隔的

# 指定图像的宽度和高度
width = 637
height = 561

# 创建图像对象
image = Image.new("RGB", (width, height))

# 遍历数据并设置像素值
index = 0
for y in range(height):
    for x in range(width):
        r, g, b = int(data[index]), int(data[index + 1]), int(data[index + 2])
        image.putpixel((x, y), (r, g, b))
        index += 3

# 保存图像
image.save('output_image.png')

# 展示图像
image.show()

这一题看了官方的wp,根据hint?

在这里插入图片描述

没有在程序中找到o(╥﹏╥)o。只能暂时放一边了。

在这里插入图片描述

得到一张写着,我想打篮球的图片。翻译成英语,“I want to play basketball”

再结合flag 为 28 位,可以得到,“I want to play basketballI w”

之后再与code异或就好了。

code = [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]
str = 'I want to play basketballI w'
flag = ''
for i in range(28):
    flag += chr(ord(str[i]) ^ code[i])
print(flag)
#HDCTF{$1AM_DVN|<_5|-|0|-|<U}

.(img-x58Np97x-1700493600487)]

得到一张写着,我想打篮球的图片。翻译成英语,“I want to play basketball”

再结合flag 为 28 位,可以得到,“I want to play basketballI w”

之后再与code异或就好了。

code = [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]
str = 'I want to play basketballI w'
flag = ''
for i in range(28):
    flag += chr(ord(str[i]) ^ code[i])
print(flag)
#HDCTF{$1AM_DVN|<_5|-|0|-|<U}
  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

znonono

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

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

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

打赏作者

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

抵扣说明:

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

余额充值