【攻防世界】reverse | answer_to_everything 详细题解 WP

【攻防世界】reverse | answer_to_everything 详细题解 WP

下载附件

main函数伪代码:

c 复制代码
int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned int v4; // [rsp+Ch] [rbp-4h] BYREF

  printf("Gimme: ");
  __isoc99_scanf("%d", &v4);
  not_the_flag(v4);
  return 0;
}

not_the_flag函数伪代码:

c 复制代码
__int64 __fastcall not_the_flag(int a1)
{
  if ( a1 == 42 )
    puts("Cipher from Bill \nSubmit without any tags\n#kdudpeh");
  else
    puts("YOUSUCK");
  return 0LL;
}

分析这两个函数,结合题目描述,将原始字符串kdudpeh进行 sha1 加密加上 flag{} 即可得到 flag,这里写了一个exp方便进行加密

exp:

python 复制代码
import hashlib
import sys
import argparse

def string_to_sha1(input_str: str, uppercase: bool = True, with_space: bool = False) -> str:
    """
    计算字符串的SHA1哈希值(CTF中最常用场景)
    :param input_str: 待加密的字符串
    :param uppercase: 是否输出大写(CTF中多要求大写/小写统一)
    :param with_space: 是否每2个字符加空格(部分题目格式要求)
    :return: SHA1哈希值字符串
    """
    try:
        # 字符串转bytes(UTF-8编码,兼容中文/特殊字符)
        str_bytes = input_str.encode('utf-8')
        # 计算SHA1哈希
        sha1_obj = hashlib.sha1()
        sha1_obj.update(str_bytes)
        # 获取十六进制结果
        sha1_hex = sha1_obj.hexdigest()
        
        # 格式处理:大写/小写、空格分隔
        if uppercase:
            sha1_hex = sha1_hex.upper()
        if with_space:
            sha1_hex = ' '.join([sha1_hex[i:i+2] for i in range(0, len(sha1_hex), 2)])
        
        return sha1_hex
    except Exception as e:
        raise ValueError(f"字符串SHA1加密失败:{e}")

def file_to_sha1(file_path: str, uppercase: bool = True, with_space: bool = False, chunk_size: int = 4096) -> str:
    """
    计算文件的SHA1哈希值(验证文件完整性/匹配题目哈希)
    :param file_path: 文件路径
    :param uppercase: 是否输出大写
    :param with_space: 是否每2个字符加空格
    :param chunk_size: 读取文件的块大小(避免大文件内存溢出)
    :return: 文件的SHA1哈希值
    """
    try:
        sha1_obj = hashlib.sha1()
        with open(file_path, 'rb') as f:
            # 分块读取大文件(避免内存占用过高)
            while chunk := f.read(chunk_size):
                sha1_obj.update(chunk)
        # 格式处理
        sha1_hex = sha1_obj.hexdigest()
        if uppercase:
            sha1_hex = sha1_hex.upper()
        if with_space:
            sha1_hex = ' '.join([sha1_hex[i:i+2] for i in range(0, len(sha1_hex), 2)])
        
        return sha1_hex
    except FileNotFoundError:
        raise FileNotFoundError(f"文件不存在:{file_path}")
    except PermissionError:
        raise PermissionError(f"无权限读取文件:{file_path}")
    except Exception as e:
        raise ValueError(f"文件SHA1加密失败:{e}")

def main():
    """
    命令行交互入口(支持参数化调用,CTF中直接运行)
    """
    # 解析命令行参数
    parser = argparse.ArgumentParser(description="CTF专用SHA1加密工具:支持字符串/文件加密")
    parser.add_argument('-s', '--string', type=str, help='待加密的字符串(与-f二选一)')
    parser.add_argument('-f', '--file', type=str, help='待加密的文件路径(与-s二选一)')
    parser.add_argument('-u', '--uppercase', action='store_true', default=True, help='输出大写(默认开启)')
    parser.add_argument('-l', '--lowercase', action='store_false', dest='uppercase', help='输出小写(覆盖-u)')
    parser.add_argument('-ws', '--with-space', action='store_true', default=False, help='每2个字符加空格(默认关闭)')
    
    args = parser.parse_args()
    
    # 校验参数:必须指定-s或-f
    if not args.string and not args.file:
        print("❌ 错误:必须指定 -s <字符串> 或 -f <文件路径>")
        parser.print_help()
        sys.exit(1)
    
    # 执行加密并输出结果
    try:
        if args.string:
            sha1_result = string_to_sha1(args.string, args.uppercase, args.with_space)
            print(f"✅ 字符串SHA1加密结果:")
            print(f"   原始字符串:{args.string}")
            print(f"   SHA1哈希值:{sha1_result}")
            print(f"   flag:flag{{{sha1_result}}}")
        else:
            sha1_result = file_to_sha1(args.file, args.uppercase, args.with_space)
            print(f"✅ 文件SHA1加密结果:")
            print(f"   文件路径:{args.file}")
            print(f"   SHA1哈希值:{sha1_result}")
    except Exception as e:
        print(f"❌ 加密失败:{e}")
        sys.exit(1)

if __name__ == "__main__":
    # 示例调用(直接运行脚本时使用命令行参数,也可在代码中调用函数)
    main()

运行 exp 脚本

得到flag:

复制代码
flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}

【攻防世界】reverse | answer_to_everything 详细题解 WP 原理深度解析:

CTF 逆向实战:answer_to_everything 详细解题指南与原理深度解析

一、题目背景与初始分析

在 CTF 逆向工程领域,"answer_to_everything" 这类题目属于典型的 "输入验证 + 简单加密" 类型,适合逆向入门但又包含实战必备的分析思路。本题的核心目标是通过逆向程序逻辑,找到触发关键信息的条件,最终破解并生成符合格式的 flag。

从题目名称 "answer_to_everything"(万物的答案),我们可以联想到经典科幻小说《银河系漫游指南》中 "42 是宇宙的终极答案" 这一彩蛋,这其实已经暗示了输入的关键数值,为后续分析提供了隐性线索。

二、程序逆向分析:从伪代码到核心逻辑

2.1 主函数(main)逻辑拆解

程序的主函数伪代码如下:

c 复制代码
int __fastcall main(int argc, const char **argv, const char **envp)
{
  unsigned int v4; // [rsp+Ch] [rbp-4h] BYREF

  printf("Gimme: ");
  __isoc99_scanf("%d", &v4);
  not_the_flag(v4);
  return 0;
}

关键分析

  • 程序首先输出提示语 "Gimme:",等待用户输入
  • 通过__isoc99_scanf("%d", &v4)读取一个整数(%d明确输入类型为十进制整数)
  • 将输入的整数传入not_the_flag函数进行处理
  • 无复杂逻辑,核心功能是 "读取输入→传递给验证函数"

2.2 验证函数(not_the_flag)逻辑解析

验证函数是本题的核心,伪代码如下:

c 复制代码
__int64 __fastcall not_the_flag(int a1)
{
  if ( a1 == 42 )
    puts("Cipher from Bill \nSubmit without any tags\n#kdudpeh");
  else
    puts("YOUSUCK");
  return 0LL;
}

关键分析

  • 函数接收一个整数参数a1(即 main 函数中输入的v4
  • 核心判断:当输入的整数等于 42 时,输出三段关键信息;否则输出 "YOUSUCK"(输入错误)
  • 输出的关键信息包含三个部分:
    • "Cipher from Bill":表面是加密相关提示(实际本题加密方式更直接)
    • "Submit without any tags":明确要求提交时去除 "标签"(即去掉#符号)
    • "#kdudpeh":核心字符串(去除#后为kdudpeh

2.3 逆向结论:触发条件与关键信息

通过对两个函数的分析,可直接得出:

  • 触发关键信息的输入为整数42(与题目名称的彩蛋呼应)
  • 关键字符串为kdudpeh (去除#后)
  • 后续需对kdudpeh进行处理以生成 flag

三、flag 生成逻辑:从关键字符串到最终答案

3.1 加密方式识别

题目提示 "将原始字符串 kdudpeh 进行 sha1 加密加上 flag {} 即可得到 flag",明确了加密算法为SHA1

SHA1 是一种密码散列函数,可将任意长度的输入转换为固定长度(160 位,40 个十六进制字符)的哈希值,在 CTF 中常用于对关键字符串进行加密生成 flag,具有不可逆性(无法从哈希值反推原始字符串)。

3.2 实战操作:使用 Python 脚本计算 SHA1 哈希

提供的 Python 脚本专门用于 CTF 场景下的 SHA1 加密,支持字符串和文件两种模式,我们需要用它计算kdudpeh的 SHA1 值。

脚本核心函数解析
python 复制代码
def string_to_sha1(input_str: str, uppercase: bool = True, with_space: bool = False) -> str:
    # 字符串转bytes(UTF-8编码,兼容特殊字符)
    str_bytes = input_str.encode('utf-8')
    # 计算SHA1哈希
    sha1_obj = hashlib.sha1()
    sha1_obj.update(str_bytes)
    sha1_hex = sha1_obj.hexdigest()  # 获取十六进制结果
    # 格式处理(大写/小写、空格分隔)
    if uppercase:
        sha1_hex = sha1_hex.upper()
    if with_space:
        sha1_hex = ' '.join([sha1_hex[i:i+2] for i in range(0, len(sha1_hex), 2)])
    return sha1_hex

功能说明

  • 将输入字符串转为 UTF-8 编码的字节流(确保特殊字符正确处理)
  • 调用hashlib.sha1()计算哈希值
  • 支持格式调整:默认输出大写十六进制,可通过参数改为小写或添加空格分隔
执行步骤与结果
  1. 运行脚本,指定字符串kdudpeh

    bash 复制代码
    python sha1_tool.py -s "kdudpeh" -l(小写)
  2. 输出结果:

    plaintext 复制代码
    ✅ 字符串SHA1加密结果:
       原始字符串:kdudpeh
       SHA1哈希值:80ee2a3fe31da904c596d993f7f1de4827c1450a
       flag:flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}
  3. 包装为 flag 格式:flag{80ee2a3fe31da904c596d993f7f1de4827c1450a}

四、原理深度解析:逆向与加密的核心逻辑

4.1 逆向分析的本质

本题的逆向过程体现了 "输入 - 验证 - 输出" 的经典模型:

  • 输入层 :明确输入类型(整数)和范围(通过unsigned int可推断为 0~4294967295,但实际有效输入仅 42)
  • 验证层 :通过简单的条件判断(a1 == 42)决定输出内容,无复杂算法(如混淆、加密验证)
  • 输出层:直接暴露关键字符串,降低了解题难度

4.2 SHA1 加密的 CTF 应用场景

SHA1 在 CTF 中常见于:

  • 对已知明文生成 flag(如本题,直接对关键字符串加密)
  • 文件完整性验证(通过比对文件的 SHA1 哈希判断是否被篡改)
  • 简单登录验证(程序存储密码的 SHA1 哈希,输入密码加密后比对)

其核心特点是固定输出长度单向性,使得它适合作为 "不可逆转换" 的工具。

五、同类题目解题方法论:举一反三

5.1 题型特征识别

"输入验证 + 哈希加密" 类题目通常具有以下特征:

  • 主函数逻辑简单:读取输入→调用验证函数→输出结果
  • 验证条件明确:多为简单的数值 / 字符串比对(如等于某个固定值)
  • 关键信息直接暴露:在验证通过的分支中直接输出待处理的字符串
  • 加密方式提示清晰:通过输出文本或函数名暗示加密算法(如 "sha"、"hash" 等关键词)

5.2 快速解题步骤

  1. 定位输入与验证逻辑
    • 找到scanf/gets等输入函数,确定输入类型(整数 / 字符串)
    • 跟踪输入值的传递路径,找到验证函数(通常是输入值直接作为参数的函数)
    • 分析验证条件,确定触发关键信息的输入(如本题的 42)
  2. 提取关键字符串
    • 在验证通过的分支中寻找字符串输出(如puts/printf函数的参数)
    • 注意处理特殊符号(如本题需去除#
  3. 识别并应用加密算法
    • 根据提示确定加密算法(SHA1/SHA256/MD5 等哈希算法,或凯撒 / 异或等简单加密)
    • 使用工具快速计算结果(如本题的 Python 脚本,或在线哈希工具)
    • 按题目要求包装格式(如添加flag{}

5.3 工具推荐

  • 逆向分析工具:IDA Pro(静态分析伪代码)、x64dbg(动态调试验证输入)
  • 哈希计算工具 :Pythonhashlib库(灵活编程)、在线哈希计算器(快速验证)
  • 自动化脚本:如本题提供的 SHA1 工具,可提前准备各类加密算法的通用脚本,解题时直接调用

六、总结

"answer_to_everything" 作为一道入门级逆向题,核心考察了:

  1. 基础逆向分析能力:从伪代码中提取输入验证逻辑和关键信息
  2. 加密算法应用能力:识别 SHA1 算法并计算结果
  3. 格式处理能力:按要求处理字符串(去标签)和包装 flag

通过本题可掌握 "输入验证→关键字符串提取→加密计算" 的经典解题流程,这类思路可直接应用于大部分同类型逆向题目。记住:在 CTF 中,复杂的题目往往始于简单的逻辑,耐心分析每一个函数和字符串,就能找到破解的关键。

相关推荐
vortex51 小时前
反弹Shell场景中bash -c与直接bash -i的适用差异解析
c语言·chrome·bash
lly2024061 小时前
Go 语言数组
开发语言
FreeBuf_1 小时前
恶意 Rust 包瞄准 Web3 开发者窃取加密货币
开发语言·rust·web3
白帽黑客-晨哥1 小时前
零基础转行网络安全需要学多久?
网络·安全·web安全·网络安全·零基础·就业·转行
豐儀麟阁贵1 小时前
9.4字符串操作
java·linux·服务器·开发语言
Ynchen. ~1 小时前
[工程实战] 攻克“数据孤岛”:基于隐语纵向联邦学习的金融风控建模全解析
算法·金融·逻辑回归·隐语
程序员-King.1 小时前
day107—同向双指针—无重复字符的最长字串(LeetCode-3)
算法·leetcode·双指针
风掣长空1 小时前
【LeetCode】面试经典150题:合并两个有序数组
算法·leetcode·面试
weixin_307779131 小时前
Jenkins Gson API插件:统一JSON处理的基础库
java·运维·开发语言·架构·jenkins