攻防世界逆向刷题笔记(新手模式9-1?)

news2025/7/15 20:34:36

bad_python

看样子是pyc文件损坏了。利用工具打开,发现是MAGIC坏了。搜下也没有头绪。

攻防世界-难度1- bad_python - _rainyday - 博客园

python Magic Number对照表以及pyc修复方法 - iPlayForSG - 博客园

看WP才知道36已经提示了pyc版本了。参考第二个文章,除了魔法数字还有8字节的额外信息。

但是我填充之后还是bad magic,再看看WP咋说的。原来代表文件大小的地方还不能为0.也就是第12个字节。

我们只需要修复一下就可以了。 妈的,用FF也不行,看来必须中规中矩才行。用E5成功了。、

 识别出是XTEA加密,写出解密即可。后期我这又出问题了,这一步就不搞了吧

ereere

左边没有main了,依据start必定会出现main函数,一个个点找到了疑似main的函数。

base64换表+RC4。思路同攻防世界RE_ereere_攻防世界ereere-CSDN博客

用cyberchef解决的

easyEZbaby_app

定位到关键代码。主要看checkpass和checkUsername函数

首先是username,密码是zhishixuebao的MD5,以2为步长取。结果是:7afc4fcefc616ebd

pass则是如下。长度显然是15位,注意算法要求是char数组=0,说明赋值等式右边值是0(也就是48)。写出Python代码即可。

a=''
for i in range(15):
   a+=chr(((255 - i) + 2) - 98-48)
print(a)

toddler_regs 

导入pdb文件,放进IDA分析。

持续跟踪,首先看到stage1,要求参数必须是要求的值,只能动调修改这个参数。

但是看起来没啥用啊,看看stage2.

发现stage1的用处了,他会把黄框部分设置为23.我们直接找到这个对应的值即可。注意team是个字符串数组,我们导出来看看,直接在C里面运行吧。

第一个team输出了:0Int

第二个代码和上面一样,结果是:nTJnU

组合起来就是flag{0Int_1s_n1c3_but_nTJnU_is_we1rd}

上面显然是错误的,可能会遇到这个地方刚好是\0直接截断。保险的做法是先定义好数组大小(如char[512][10],再直接去掉&运行即可)

exp:

也可以动调做,我电脑不知为何运行不起来这个软件,只能静态分析了。

easyre-xctf

看题目简介估计有壳。是UPX原版壳,官方工具就可以脱壳了。

但并没有明显的算法,只在字符部分看到了疑似flag的后半段。双击这里有一个符号名part2。

动调看看有没有提示,拿拿数据。

在内存发现了疑似的部分

根据其地址定位到函数,这就是第一个flag。函数名字有个part1,对应着part2.两个16进制转换为字符后就是part1.

七分靠猜,这里有运气成分,正常来说估计得搜part1了。

CatFly(还没有写出来)

看主函数很复杂。慢慢来看吧。

运行出来是个这,输入的东西会在左下角显示。那么main函数有的部分就可以不看了。

看到一个提示:

要记住逃逸密码??

难道是迷宫,分析这部分,\x1Bxxx是终端转义啊,看着是打印图形用的。

百思不得姐,还是看看WP吧。

re学习(29)攻防世界-CatFly(复原反汇编)_攻防世界catfly-CSDN博客

粗略浏览下发现没有我想要的,不过突然想到可以给main函数拷贝到VC,删去已知功能的函数再仔细分析看看。

暂时跳过,下次再看。

IgniteMe

跟进到主函数。

首先str长度需要大于4.

先来一个循环把str循环复制给v7。后两个if判断意思是大写转小写,小写转大写。

最关键的在后院吗,str2我们已经知道了,这就是目标。byte我们也知道,目标就是求v7。接下来的sub_4013c0跟进一下。

 是一个表达式,相当于v7^0x55+72.那就很明显了,写出对应exp:

str2='GONDPHyGjPEKruv{{pj]X@rF'
byte=[ 0x0D, 0x13, 0x17, 0x11, 0x02, 0x01, 0x20, 0x1D, 0x0C, 0x02, 
  0x19, 0x2F, 0x17, 0x2B, 0x24, 0x1F, 0x1E, 0x16, 0x09, 0x0F, 
  0x15, 0x27, 0x13, 0x26, 0x0A, 0x2F, 0x1E, 0x1A, 0x2D, 0x0C, 
  0x22, 0x04]
flag=''
#根据str2猜测长度是24
for i in range(24):
    flag+=chr(((byte[i]^ord(str2[i]))-72)^0x55)
print(flag)
print(flag.lower())

出来的flag都是大写,不要忘记两个if判断是大写转小写小写转大写,因此再次转为小写即可

BABYRE

main函数看着很简单

需要注意:在 C 语言中,(*judge)(s) 这种语法表示通过函数指针调用函数。在 C 语言中,函数名本质上是指向函数代码起始地址的指针。可以将这个地址存储在一个函数指针变量中,然后通过该变量调用函数。

也就是说这是一段自修改代码。judge是函数,需要解密这段judge。

先用AI生成(因为我不太会IDA python)一段解密的脚本在IDA运行,然后C--P加载为函数即可

import idautils
import idaapi

base = 0x600b00

# 处理182个字节(与原始代码一致,0到181共182次)
for i in range(182):
    # 读取原始字节
    original_byte = idaapi.get_byte(base + i)
    
    # 异或解密
    decrypted_byte = original_byte ^ 0xC
    
    # 写入解密后的字节
    idaapi.patch_byte(base + i, decrypted_byte)
    
    # 标记为数据(这一行删了就行)无用
    idaapi.create_data(base + i, FF_BYTE, 1, idaapi.BADADDR)

print(f"已解密 {base:X} 开始的182个字节")

再次从main函数进入judge即可了。 直接点进去judge好像部分代码还是错误,重新从main进去就好了。

这个加密逻辑就很明显了。

a='fmcd\x7Fk7d;V`;np'
flag=''
for i in range(len(a)):
    flag+=chr(ord(a[i])^i)
print(flag)

parallel-comparator-200

这一题直接给了C代码。有点意思。

注意到代码的flag_len是20.

首先认识一个新函数

逐步分析,main函数调用了下图的highly_.....函数。

跟进此函数。根据is_ok的判断条件,着重关注此部分,说明result值是0.因为is_ok的条件为generated==just_a_string。

查找用到result的地方。注意到只有first_letter未知,user_string是我们的目标。

最后一行代码实际上经过上文知识点铺垫,调用了checking函数。

由于result==0,说明argument[0]+argument[1]严格相等于argument[2]。会循环20次这个checking函数(因为pthread_creat函数在for循环内部循环了20次)

0我们不知道,(起码知道是某个小写字母)2是目标,1知道了。而且2就等于1+0.但是这还不太够啊,看看还有没有其余条件,似乎没了。

先尝试写一个爆破脚本试试。这里要注意,一定要多生成几个flag,因为不同的frist_letter对应不同的flag,我们试着a~z都搞一遍。第一次没想到这样遍历。而且代码美观不如豆包写的,还得多写多练。

、注意{}是占位符,可以写任意的表达式。

a = [0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7]

# 尝试所有可能的基准值b (97-122)
for base in range(97, 123):
    flag = []
    valid = True
    
    for i in a:
        char_code = base + i
        if 32 <= char_code <= 126:
            flag.append(chr(char_code))
        else:
            valid = False
            break  # 这个基准值无效
    
    if valid:
        print(f"基准值 {chr(base)} ({base}): {''.join(flag)}")

发现flag 

很让我开心的是我找到了大致思路!哈哈哈哈哈。只是脚本功底还比较薄弱。

secret-galaxy-300

注意到程序是打印了类似于星球的东西。

但是观察函数发现其实并没有完全打印出来,a1这个数组的部分内容并没有完全用到,所以我打算动调拿一波数据看看。

动调看a1并没发现明显的字符串

攻防世界逆向高手题之secret-galaxy-300-CSDN博客

看了别人的wp,反思一下,还是思路错了,这时候可以结合题目的提示,隐藏的星系,确实发现一个没有被打印出来的星系,点击ctrl+x查看交叉引用:

(而且我说为啥有三个代码差不多的文件,原来对应不同平台)

其实这里就可以看出来这估计就是flag了,这里偷了个懒,使用了AI。

# 定义各个星系名称字符串
ngs_2366 = "NGS 2366"
andromeda = "Andromeda"
messier = "Messier"
sombrero = "Sombrero"
triangulum = "Triangulum"
dark_secret_gala = "DARK SECRET GALAXY"

# 将各个星系名称转换为字符列表,方便按索引取值
galaxy_strings = {
    "ngs_2366": list(ngs_2366),
    "andromeda": list(andromeda),
    "messier": list(messier),
    "sombrero": list(sombrero),
    "triangulum": list(triangulum),
    "dark_secret_gala": list(dark_secret_gala)
}

def build_result_string():
    """构建结果字符串"""
    result_chars = [
        galaxy_strings["andromeda"][8],
        galaxy_strings["triangulum"][7],
        galaxy_strings["messier"][4],
        galaxy_strings["andromeda"][6],
        galaxy_strings["andromeda"][1],
        galaxy_strings["messier"][2],
        '_',
        galaxy_strings["andromeda"][8],
        galaxy_strings["andromeda"][3],
        galaxy_strings["sombrero"][5],
        '_',
        galaxy_strings["andromeda"][8],
        galaxy_strings["andromeda"][3],
        galaxy_strings["andromeda"][4],
        galaxy_strings["triangulum"][6],
        galaxy_strings["triangulum"][4],
        galaxy_strings["andromeda"][2],
        '_',
        galaxy_strings["triangulum"][6],
        galaxy_strings["messier"][3]
    ]
    return ''.join(result_chars)

# 直接构建并打印结果字符串
print("构建的结果字符串:", build_result_string())

其实直接动调很快

simple-check-100

打开也是三个文件,有了前面的经验,这里面的代码一定是一样的

不如直接打开exe,动调起也方便

怀疑这部分的result就是最终的flag。

为了便于调试分析,我想使用动调的方法来做这道题。目前有两个思路,一个是直接改汇编代码,让这个条件强制为真,另一个是利用check_key来找v8的值,但是很遗憾看代码这个是v7地址对应的数组,估计不方便寻找和爆破。方便起见,先直接改汇编代码看看。

好吧,这种思路看着不太行的样子。OD出来的是乱码。估计是GBK编码不可以处理,这个估计不是GBK编码,

需要注意用X32得用管理员模式,刚才我patch了估计就是没管理员模式,他不认,IDA动调的patch估计没有静态的好使,patch了还是说wrong.

参考了攻防世界-simple-check-100_攻防世界 simple-check-100-CSDN博客看来这种动调还是找专业的调试器吧

我看人家都是用GDB动调的。linux估计不乱码。

新学的调试指令:set $eax=1

这里需要注意在这里改:,估计箭头跑到这里意思就是这个指令执行完毕了已经。

果不其然出来了flag。

接下来试试静态分析

注意参数本来是字符,搞成了int,因此本来一字节,导致合并为4字节。

还要注意这是一个嵌套for循环。 

这借鉴了攻防世界 simple-check-100(非常好的一篇wp,日后还得多多观看,受益匪浅)-CSDN博客

#include <stdio.h>
int main(int argc, char *argv[])
{
    unsigned char flag_data[] = {
        220, 23, 191, 91, 212, 10, 210, 27, 125, 218,
        167, 149, 181, 50, 16, 246, 28, 101, 83, 83,
        103, 186, 234, 110, 120, 34, 114, 211};
    char v7[] = {
        84, -56, 126, -29, 100, -57, 22, -102, -51, 17,
        101, 50, 45, -29, -45, 67, -110, -87, -99, -46,
        -26, 109, 44, -45, -74, -67, -2, 106};
    unsigned int v2;
    unsigned char *v3;
    // v11 = -478230444;
    // v12 = -1709783196;
    // v13 = 845484493;
    // v14 = 1137959725;
    // v15 = -761419374;
    // v16 = -752063002;
    // v17 = -74;
    // v18 = -67;
    // v19 = -2;
    // v20 = 106;
    // 方法一:类比写
    for (int i = 0; i <= 6; ++i)
    {
        v2 = ((v7[4 * i] & 0x000000FF) + ((v7[4 * i + 1] & 0x000000FF) << 8) + ((v7[4 * i + 2] & 0x000000FF) << 16) + ((v7[4 * i + 3] & 0x000000FF) << 24)) ^ 0xDEADBEEF;
        v3 = (unsigned char *)&v2;
        for (int j = 3; j >= 0; --j)
        {
            printf("%c", *(v3 + j) ^ flag_data[4 * i + j]);
        }
    }
    // 方法二:按位异或,小端字节序,低位在低地址
    // for (int i = 0; i <= 6; ++i) {
    // printf("%c", v7[4 * i + 3] ^ 0xDE ^ flag_data[4 * i + 3]);
    // printf("%c", v7[4 * i + 2] ^ 0xAD ^ flag_data[4 * i + 2]);
    // printf("%c", v7[4 * i + 1] ^ 0xBE ^ flag_data[4 * i + 1]);
    // printf("%c", v7[4 * i] ^ 0xEF ^ flag_data[4 * i]);
    // }
    return 0;
}

代码分析:v2 的计算逻辑

这行代码的核心是 将 4 个有符号字节组合成一个 32 位无符号整数,然后与 0xDEADBEEF 进行异或运算。让我逐步拆解这个过程:

1. 为什么需要 & 0x000000FF

  • v7 是一个 有符号字符数组char v7[]),其中的负数(如 -56)在内存中以补码形式存储(例如 -56 的补码是 0xC8,即十进制的 200)。

  • 问题:当将有符号数扩展为更大的类型(如 int)时,符号位会被保留。例如:

    • v7[1] 的值是 -56(二进制 0xC8),如果直接转换为 int,会变成 0xFFFFFFC8(因为符号位扩展)。

    • 这会导致后续的位运算(如 << 8)结果错误。

  • 解决方法:通过 & 0xFF 将其截断为无符号字节:

    • -56 & 0xFF → 0xC8(十进制 200),确保高 24 位为 0

2. 为什么要进行位移操作(<< 8<< 16<< 24)?

这是 小端序(Little Endian)字节组合 的过程:

  • 假设有 4 个字节 b0, b1, b2, b3,对应的索引为 4*i 到 4*i+3

  • 在小端序中,低字节存放在低地址,高字节存放在高地址。因此,组合成 32 位整数的公式是:

    plaintext

    value = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24)
    
  • 示例
    假设 v7[4*i] 到 v7[4*i+3] 的值为 [84, -56, 126, -29](即 [0x54, 0xC8, 0x7E, 0xE3]):

    • v7[4*i] & 0xFF → 0x54(低字节)

    • v7[4*i+1] & 0xFF → 0xC8

    • v7[4*i+2] & 0xFF → 0x7E

    • v7[4*i+3] & 0xFF → 0xE3(高字节)

    • 组合后的值:0xE37EC854(注意字节顺序颠倒,符合小端序)。

主要是因为将字符指针弄成整数的,再加上端序转换,搞得很麻烦。 

re1-100

开局这些都是反调试

函数功能与原理

  • 管道概念:管道是一种进程间通信(IPC,Inter - Process Communication)机制,用于在具有亲缘关系(如父子进程)的进程间传递数据。它本质上是一个特殊的文件,遵循先进先出(FIFO)原则。

  • 函数作用:在许多编程语言和系统(如 C、C++ 等基于 POSIX 标准的系统编程中),pipe 函数用于创建一个匿名管道pipe 函数通常接受一个包含两个文件描述符的数组作为参数(这里 pParentWrite 应该是数组首地址),其中一个文件描述符用于读取管道数据(通常是数组的第一个元素,记为 fd[0]),另一个用于向管道写入数据(通常是数组的第二个元素,记为 fd[1]

  • 成功时:返回 0
  • 失败时:返回 -1,并设置 errno 来指示具体错误类型。

由此我们已经知道pparentread/pparentwrite都是什么意思。

这个代码大概意思就是判断输入的是不是完整。根据我的判断。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2387784.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制作一款打飞机游戏58:子弹模式组合

今天我们将继续深入探讨子弹模式系统&#xff0c;并在我们的模式编辑器上做一些收尾工作。 子弹模式系统的乐趣 首先&#xff0c;我想说&#xff0c;这个子弹模式系统真的非常有趣。看着屏幕上不断喷射的子弹&#xff0c;感觉真是太棒了&#xff01; 合并修饰符 今天&#…

使用新一代达梦管理工具SQLark,高效处理 JSON/XML 数据!

在应用开发领域&#xff0c;JSON/XML数据结构因其灵活性和通用性&#xff0c;成为开发者存储和交换数据的首选。然而&#xff0c;传统管理工具在处理这些半结构化数据时&#xff0c;往往存在可视化效果差、编辑效率低等问题&#xff0c;严重影响开发者的工作效率。 现在&#…

深入了解PyTorch:起源、优势、发展与安装指南

深入了解PyTorch&#xff1a;起源、优势、发展与安装指南 目录 引言PyTorch简介PyTorch的优势 动态计算图直观易用的API强大的社区支持丰富的生态系统高性能与可扩展性 PyTorch的发展历程PyTorch的主要组件 Torch.TensorAutograd自动求导nn模块TorchvisionTorchText和TorchAu…

DeepSeek智能对话助手项目

目录&#xff1a; 1、效果图2、实现代码3、温度和TopK的作用对比 1、效果图 2、实现代码 # import gradio as gr# def reverse_text(text): # return text[::-1]# demogr.Interface(fnreverse_text,inputs"text",outputs"text")# demo.launch(share&q…

浅谈Mysql的MVCC机制(RC与RR隔离级别)

MVCC&#xff08;Multi-Version Concurrency Control&#xff09;多版本并发控制 说这个我们先来了解一下Mysql的隔离级别&#xff0c;因为MVCC和Mysql的隔离级别是有关的。 Mysql默认的隔离级别是RR&#xff08;可重复读&#xff09; 其他的隔离级别是读未提交&#xff08;…

uniapp-商城-72-shop(5-商品列表,购物车实现回顾)

我们通过前面的章节已经将数据添加到了购物车,但实际上购物车的处理还有很多东西需要完成。 我们看看如何将商品添加到购物车。 本文介绍了购物车功能的实现方式,重点讲解了如何将商品添加到购物车以及购物车状态管理的处理机制。主要内容包括:1. 通过Vuex管理购物车状态,包…

MySQL#Select语句执行过程

服务端程序架构 MySQL 是典型的 C/S 架构&#xff0c;即 Client/Server 架构&#xff0c;服务器端程序mysqld。 Select语句执行过程 连接层 客户端和服务器端建立连接&#xff0c;客户端发送 SQL 至服务器端 SQL层 SQL语句处理 查询缓存&#xff1a; 缓存命中该SQL执行结果直…

hbuilder中h5转为小程序提交发布审核

【注意】 [HBuilder] 11:59:15.179 此应用 DCloud appid 为 __UNI__9F9CC77 &#xff0c;您不是这个应用的项目成员。1、联系这个应用的所有者&#xff0c;请求加入项目成员&#xff08;https://dev.dcloud.net.cn "成员管理"-"添加项目成员"&#xff09;…

【数据结构】单链表练习

1.链表的中间节点 https://leetcode.cn/problems/middle-of-the-linked-list/description/ 用快慢指针来解决 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* middleNode(struct ListNode* he…

学习vue3:跨组件通信(provide+inject)

目录 一&#xff0c;关于跨组件通信概述 二&#xff0c;跨组件传值 案例1(爷传孙&#xff09; 三&#xff0c;跨组件传函数 案例2(爷传孙&#xff09; 疑问&#xff1a;孙子传给爷爷是否可行呢&#xff1f; 一&#xff0c;关于跨组件通信概述 之前我们学习了父子组件的传…

【菜狗work前端】小程序加if判断时不及时刷新 vs Web

零、前提&#xff1a; 实现input输入数字不大于10000&#xff08;需要配合typenumber&#xff0c;maxlength5&#xff0c;这里没写&#xff09; 一、探究代码&#xff1a; <input v-model"model1" input"changeModel1" placeholder"请输入拒收件…

TCP 三次握手:详解与原理

无图、长文警告&#xff01;&#xff01;&#xff01;&#xff01; 文章目录 一、引言二、TCP 三次握手的过程&#xff08;一&#xff09;第一次握手&#xff1a;SYN&#xff08;同步序列号&#xff09;&#xff08;二&#xff09;第二次握手&#xff1a;SYN-ACK&#xff08;同…

LabVIEW累加器标签通道

主要展示了 Accumulator Tag 通道的使用&#xff0c;通过三个并行运行的循环模拟不同数值的多个随机序列&#xff0c;分别以不同频率向累加器写入数值&#xff0c;右侧循环每秒读取累加器值&#xff0c;同时可切换查看每秒内每次事件的平均值&#xff0c;用于演示多线程数据交互…

永磁同步电机控制算法--IP调节器

一、基本原理 在电机控制领域&#xff0c;现今普遍使用的是比例-积分(PI)控制器。然而&#xff0c;PI控制器有一些缺点&#xff0c;可能会在某些应用中产生一些问题&#xff0c;例如:一个非常快的响应&#xff0c;也同时具有过大的超调量。虽然设计PI控制器时&#xff0c;可以…

Ubuntu 25.04 锁屏不能远程连接的解决方案

最近安装了一个 Ubuntu 25.04&#xff0c;偶然发现可以通过 windows 自带的 rdp 远程工具进行连接&#xff0c;内心狂喜。此外&#xff0c;还支持启动 VNC 协议&#xff0c;也就是默认支持了 rdp 和 vnc 连接。 看了以下&#xff0c;ubuntu 在用户级别下创建了一个远程桌面服务…

Java 自动装箱和拆箱还有包装类的缓存问题

自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5 后&#xff0c; Java 引入了自动装箱(autoboxing)/拆箱(unboxing)。 自动装箱&#xff1a; 基本类型的数据处于需要对象的环境中时&#xff0c;会自动转为“对象”。 我们以 Integer 为例&#xff1a;…

java-jdk8新特性Stream流

一、Stream流 是专业用于对集合或者数组进行便捷操作的。 1.1 Stream流的创建 主要分为Collection&#xff08;List与Set&#xff09;、Map、数组三种创建方式&#xff1a; //1.Collection集合的创建List<String> names new ArrayList<>();Collections.addAll(…

大语言模型 21 - MCP 自动操作 Figma+Cursor 实现将原型转换为代码

MCP 基本介绍 官方地址&#xff1a; https://modelcontextprotocol.io/introduction “MCP 是一种开放协议&#xff0c;旨在标准化应用程序向大型语言模型&#xff08;LLM&#xff09;提供上下文的方式。可以把 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 提供了一种…

QNAP NEXTCLOUD 域名访问

我是用docker compose方式安装的&#xff0c;虽然不知道是不是这么个叫法&#xff0c;废话不多说。 背景&#xff1a;威联通container station安装了nextcloud和lucky&#xff0c;lucky进行的域名解析和反代 先在想安装的路径、数据存储路径、数据库路径等新建文件夹。再新建…

华为OD机试真题——信道分配(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…