BUU reverse (随机做题)

准备随机找点不同难度【不同考点】的题目做。

rsa

给了一个enc,好像是RSA加密后的,public key好像是AES加密,反正不是base64,这里卡住了,也没有明显的可执行文件让我分析下,只能看WP了

原来需要公钥解析!!

那就好办了,一下子得到了公钥、n等信息。但是,这竟然是逆向题

from Crypto.Util.number import inverse, long_to_bytes
q = 285960468890451637935629440372639283459
p = 304008741604601924494328155975272418463
e = 65537
c_hex = '4196c0594a5e000a96b878b67cd724795b13a8f2ca54da06d0f19c28be689b62'
n = p * q
fi = (p - 1) * (q - 1)
d = inverse(e, fi)
c = int(c_hex, 16)
m = pow(c, d, n)
print(long_to_bytes(m))

[WUSTCTF2020]level1 

附件给了output.txt:

可能软件内实现了一些算法。

看到代码:应该是对flag这个流里面的内容进行这样的操作。写个代码反着来。

#include <stdio.h>
int main()
{
//必须保证数字在范围之内,这里用long long
    long long ptr[] = {198, 232, 816, 200, 1536, 300, 6144, 984, 51200, 570, 92160, 1200, 565248, 756, 1474560, 800, 6291456, 1782, 65536000};
    for (int i = 1; i <= 19; ++i)
    {

        if ((i & 1) != 0)
            printf("%c", (ptr[i - 1] >> i));
        else
            printf("%c", (ptr[i - 1] / i));
    }
    return 0;
}

 [GUET-CTF2019]re

有壳

 IDA没找到main函数,其实64位的start函数的rdi地址就是main地址。

主要代码:
 

BOOL8 __fastcall sub_4009AE(char *a1)
{
  if ( 1629056 * *a1 != 166163712 )
    return 0LL;
  if ( 6771600 * a1[1] != 731332800 )
    return 0LL;
  if ( 3682944 * a1[2] != 357245568 )
    return 0LL;
  if ( 10431000 * a1[3] != 1074393000 )
    return 0LL;
  if ( 3977328 * a1[4] != 489211344 )
    return 0LL;
  if ( 5138336 * a1[5] != 518971936 )
    return 0LL;
  if ( 7532250 * a1[7] != 406741500 )
    return 0LL;
  if ( 5551632 * a1[8] != 294236496 )
    return 0LL;
  if ( 3409728 * a1[9] != 177305856 )
    return 0LL;
  if ( 13013670 * a1[10] != 650683500 )
    return 0LL;
  if ( 6088797 * a1[11] != 298351053 )
    return 0LL;
  if ( 7884663 * a1[12] != 386348487 )
    return 0LL;
  if ( 8944053 * a1[13] != 438258597 )
    return 0LL;
  if ( 5198490 * a1[14] != 249527520 )
    return 0LL;
  if ( 4544518 * a1[15] != 445362764 )
    return 0LL;
  if ( 3645600 * a1[17] != 174988800 )
    return 0LL;
  if ( 10115280 * a1[16] != 981182160 )
    return 0LL;
  if ( 9667504 * a1[18] != 493042704 )
    return 0LL;
  if ( 5364450 * a1[19] != 257493600 )
    return 0LL;
  if ( 13464540 * a1[20] != 767478780 )
    return 0LL;
  if ( 5488432 * a1[21] != 312840624 )
    return 0LL;
  if ( 14479500 * a1[22] != 1404511500 )
    return 0LL;
  if ( 6451830 * a1[23] != 316139670 )
    return 0LL;
  if ( 6252576 * a1[24] != 619005024 )
    return 0LL;
  if ( 7763364 * a1[25] != 372641472 )
    return 0LL;
  if ( 7327320 * a1[26] != 373693320 )
    return 0LL;
  if ( 8741520 * a1[27] != 498266640 )
    return 0LL;
  if ( 8871876 * a1[28] != 452465676 )
    return 0LL;
  if ( 4086720 * a1[29] != 208422720 )
    return 0LL;
  if ( 9374400 * a1[30] == 515592000 )
    return 5759124 * a1[31] == 719890500;
  return 0LL;
}

借助AI快速写一个反着来的就行了,估计这题考点就是UPX解压。

buu刷题 [GUET-CTF2019]re1_[guet-ctf2019]re 1-CSDN博客

参考人家WP,a6的地方还需要小爆破下

CrackRTF

找到这个函数了,很明显是哈希。

询问豆包,这是windows里面哈希的一个东西 

估计一个是SHA-1,一个是md5,都可以在MD5免费在线解密破解_MD5在线加密-SOMD5查询到。

第一段解密:123321

第二段:~!3a@0

但是不知道为啥不对

参考BUUCTF reverse:CrackRTF_cryptcreatehash(phprov, 0x8004u, 0, 0, &phhash)-CSDN博客

忘记分析if里面的函数,他也会被执行。

这也是windows平台下的C语言函数

简单说,这是一个 “提取程序内部资源 → 处理数据 → 写入外部文件” 的功能:

  1. 从程序里找 ID 为 0x65、类型 AAA 的自定义资源;
  2. 加载资源数据并做处理(sub_401005 逻辑未知);
  3. 把处理后的数据写入 dbapp.rtf 文件。---豆包

会在程序执行后出来个文件。里面有flag,我懒得一步步分析逆向代码了。

[WUSTCTF2020]level2 

脱壳之后在main函数就看到明文flag

[MRCTF2020]Transform

选取特定的位进行异或,但是我搞得脚本一直是不对,无奈看WPbuuctf——(MRCTF2020)Transform_buuctf [mrctf2020]transform-CSDN博客

原来数据提取错了,一定在shift+e细心!

a = [9, 10, 15, 23, 7, 24, 12, 6, 1, 16, 3, 17, 32, 29, 11, 30, 27, 22, 4, 13, 19, 20, 21, 2, 25, 5, 31, 8, 18, 26, 28, 14]
final = [103, 121, 123, 127, 117, 43, 60, 82, 83, 121, 87, 94, 93, 66, 123, 45, 42, 102, 66, 126, 76, 87, 121, 65, 107, 126, 101, 60, 92, 69, 111, 98]

flag = [''] * 33  # 初始化flag列表,长度33以覆盖最大索引32

for i in range(32):
    final[i] ^= a[i]
    flag[a[i]] = chr(final[i])

print(''.join(flag))  # 转换列表为字符串并输出

[2019红帽杯]easyRE

依旧先找到main函数

本来以为这里是,没想到这是一个网址。

看这里,写出一个脚本,只解出了前几个字符是flag(细心点,这里还有对字符串字符改变的操作)

a='Iodl>Qnb(ocy\x7Fy.i\x7Fd`3w}wek9{iy=~yL@EC'
b=''
for i in range(len(a)):
    b+=chr(ord(a[i])^i)
print(b)

 还是得有点小取巧,看WP:

BUUCTF-REVERCE-[2019红帽杯]easyRE - 古明地核 - 博客园

这个就是关键代码:

特别注意中间的if判断,就是通过f和g来判断这是关键函数的

而且这是异或key这个数组的,通过v4=v1=4字节,且v1是flag异或后的结果,及%4综合推断出的。

key=[0]*4
a=[64, 53, 32, 86]
b=['f','l','a','g']
for i in range(4):
    key[i]=a[i]^ord(b[i])
c=[ 64,  53,  32,  86,  93,  24,  34,  69,  23,  47, 
   36, 110,  98,  60,  39,  84,  72, 108,  36, 110, 
  114,  60,  50,  69,  91]
flag=''
for i in range(24):
    flag+=chr(c[i] ^ key[i%4])
print(flag)

[MRCTF2020]Xor

随波逐流一把下来了。去IDA反编译不成,估计有花指令之类,看看WP咋说。

buuoj-[MRCTF2020]Xor - 今天吃大鸡腿 - 博客园估计是IDA识别栈指针原因,先点进去再出来就行了。

[NewStarCTF 公开赛赛道]Baby_Re 

本来的数据拿出来解密是:flag{Something_run_before_main?}

猜测有的函数修改了程序的内容,选择动调后拿数据。

得到真正flag:flag{S0meth1ng_run_bef0re_main!}

a = [102, 109,  99, 100, 127,  86,  54, 106, 109, 125, 
   98,  58,  98, 106,  81, 125, 101, 127,  77, 113, 
  113, 115,  38, 101, 125,  70, 119, 122, 117, 115, 
   63,  98]

flag = ''
for i in range(len(a)): 
    flag += chr(a[i] ^ (i))  
print(flag)

 [NewStarCTF 2023 公开赛道]花

花指令的题目。

通过拿字符串先找到了要去花的地方。

一个junk code:E8,正常去花+P定义函数就拿到main函数。

明显是RC4,厨子登场

为解决--[XMAN2018排位赛]easyvm

虚拟化的题目,先找到机器码,根据main函数跟踪就是这部分

暂时还不会 

[UTCTF2020]png2

这是我没有接触过的文件,没有思路了。

看原题目的描述:
 

.PNG2
50
In an effort to get rid of all of the bloat in the .png format, I'm proud to announce .PNG2!
The first pixel is #7F7F7F, can you get the rest of the image?

by bnuno

参阅了部分WP+问豆包,其实png2是一种文件格式,需要写脚本将其转化为png才可以。

接下来,我就开始问豆包怎么转换,但是豆包不靠谱。只能找官方的解题脚本。

#!/usr/bin/env python3
import os
from PIL import Image
import re

def convert_png2_to_png(input_file, output_file):
    """将PNG2格式文件转换为标准PNG格式"""
    
    # 获取脚本所在目录
    script_dir = os.path.dirname(os.path.abspath(__file__))
    input_path = os.path.join(script_dir, input_file)
    output_path = os.path.join(script_dir, output_file)
    
    # 检查输入文件是否存在
    if not os.path.exists(input_path):
        print(f"错误:输入文件不存在 - {input_path}")
        return False
    
    # 读取PNG2文件内容
    try:
        with open(input_path, "rb") as f:
            contents = f.read()
    except Exception as e:
        print(f"错误:读取文件失败 - {str(e)}")
        return False
    
    # 验证文件大小是否合理
    if len(contents) < 20:  # 最小可能的文件大小
        print(f"错误:文件太小,不像是有效的PNG2文件 - 仅{len(contents)}字节")
        return False
    
    # 解析文件头和尺寸信息
    m0 = re.match(b"PNG2width=(..)height=(..)(.+)", contents, re.DOTALL)
    if m0 is None:
        print("错误:无法识别PNG2文件格式")
        print("请确认文件是否符合预期格式:PNG2width=(xx)height=(xx)")
        return False
    
    # 解析宽度和高度
    width = int.from_bytes(m0.group(1), "big")
    height = int.from_bytes(m0.group(2), "big")
    
    # 验证尺寸是否合理
    if width <= 0 or height <= 0:
        print(f"错误:无效的图像尺寸 - {width}x{height}")
        return False
    
    # 提取像素数据
    pixels = list(m0.group(3))
    
    # 验证像素数据长度
    expected_pixels = width * height * 3
    if len(pixels) != expected_pixels:
        print(f"警告:像素数据长度不匹配!预期 {expected_pixels},实际 {len(pixels)}")
        # 使用可用的像素数据
        pixels = pixels[:expected_pixels]
    
    # 验证第一个像素是否为#7F7F7F
    if pixels and pixels[0] == 127 and pixels[1] == 127 and pixels[2] == 127:
        print("✓ 第一个像素验证成功:#7F7F7F")
    else:
        print(f"⚠ 第一个像素不匹配:RGB({pixels[0]},{pixels[1]},{pixels[2]})")
    
    # 打印图像信息
    print(f"图像尺寸: {width}x{height}")
    print(f"像素数量: {len(pixels)//3} (预期: {width*height})")
    
    # 创建图像并填充像素
    try:
        im = Image.new('RGB', (width, height))
        i = 0
        for h in range(height):
            for w in range(width):
                if i + 2 < len(pixels):
                    im.putpixel((w, h), (pixels[i], pixels[i+1], pixels[i+2]))
                    i += 3
                else:
                    break  # 像素数据不足,提前结束
        
        # 保存为PNG文件
        im.save(output_path)
        print(f"✓ 转换完成:{input_path} -> {output_path}")
        return True
    
    except Exception as e:
        print(f"错误:创建或保存图像失败 - {str(e)}")
        return False

if __name__ == "__main__":
    # 可以从命令行参数获取文件名,或者直接指定
    input_file = "pic.png2"
    output_file = "output.png"
    convert_png2_to_png(input_file, output_file)

感觉有点象是杂项了,不知为何在逆向这里。

未解决--[DASCTF 2024金秋十月|秋意浓,战火燃,码上见真章]EZRE

DIE扫描出保护器: Themida/Winlicense(3.XX)

有工具可以脱壳(32位和64不一样)

Releases · ergrelet/unlicense

然后正常分析。

字符串定位,似乎还有个花指令

上面是main函数的花,main里面也调用了一个花

 还有若干花,去除之后,看到这个函数,怀疑是RC4

但细看,其实并不是,代码实现了两种的加密,我们首先脱去第一层加密

 

我们已经知道了最终的结果,所以只需要逆向写出一个即可。 我现在思路是先脱去第一层加密拿数据,然后再分析。

但是我不会搞。

看了WP:[复现]DASCTF_2024金秋十月 丨 St4rdd3n's blog,一个是魔改RC4,一个是魔改TEA

但是我暂时还不会弄出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值