open-source write up

open-source write up

前两道逆向的题目,我们已经尝试使用了一些逆向必备工具,如IDA Pro、Ollydbg等等,但是在二进制逆向学习除了灵活使用工具外,强大的代码分析能力也是必备的技能之一。那么今天这道非常简单基础的逆向题目open-source,就是一道不需要使用太多工具,直接考察代码分析能力的题目。

本题需要的技巧:

  • 简单C语言代码阅读能力
  • 简单python脚本书写能力(二进制学习需要对python有基础了解,有基本脚本书写能力,会让你的做题速度提升很多)
  • 一颗细致的心嘿嘿嘿

那么我们直接来看看今天的题目。

下载附件拿到一段C语言源代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {
    	printf("what?\n");
    	exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");
    	exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
    	printf("ha, you won't get it!\n");
    	exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {
    	printf("so close, dude!\n");
    	exit(4);
    }

    printf("Brr wrrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

代码不多,运行之后程序打印“what?”,没有什么用处。那么我们仔细看一下代码。

通常来说我们拿到一段代码,都先从main函数开始分析,

int main(int argc, char *argv[]) {
    if (argc != 4) {
    	printf("what?\n");
    	exit(1);
    }

这时候我们发现这一段是迷惑代码,char 根本没有使用。那么关键代码到底在哪儿呢。

printf("Get your key: ");
printf("%x\n", hash);

看到这最后一段,它告诉我们Key就是hash。那我们找到hash。

unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

现在得知我们要想知道hash,需要求到firstsecondstrlen(argv[3])的值。我们再往上看看代码,有提到那三个变量。

求first的源代码:

unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");
    	exit(2);
    }

如此我们可以知道,first就是0xcafe。注意,一定要看清楚不是cafe,而是一个16进制的数字,它才是first的值。

求second的源代码:

 unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
    	printf("ha, you won't get it!\n");
    	exit(3);
    }

看到了如果(second % 5 == 3 || second % 17 != 8),则输出“ha, you won’t get it!”。也就是说,需要second % 5 != 3 && second % 17 != 8

。我们可以暂时取一个值second==25(随便取了一个满足条件的最小的数)。

求strlen(argv[3])的源代码:

if (strcmp("h4cky0u", argv[3])) {
    	printf("so close, dude!\n");
    	exit(4);
    }

直接可以知道argv[3]==“h4cky0u”,strlen(argv[3])=7。

三个值都知道了,我们就可以计算hash了。注意:计算过程中可以有比较大的数字出现,使用C语言可能导致溢出得到错误答案,我们在这里使用python脚本进行运算。

为什么用python不会溢出而C语言会?

在python3后,统一使用了长整型,长整型不存在溢出问题,即可以存放任意大小的整数。这也是吸引科研人员的一部分了,适合大数据运算,不会溢出,也不会有其他语言那样还分短整型,整型,长整型…而在C 语言中,整型所表示的大小是有范围的,但是 python 代码是保存到文本文件中的。

那么就可以写python脚本啦:

first = 0xcafe
second = 25
argv = "h4cky0u"
hash = first * 31337 + (second % 17) * 11 + len(argv) - 1615810207
print(hash)

运行得到结果:12648430,但是这不是flag。为什么呢?

关注一下这一行代码:

printf("%x\n", hash);

明白了,%x需要我们以16进制的方式输出,我们可以直接在网上转化,也可以在python中使用 print(hex(hash)),得到结果长得就很像flag的flag:0xc0ffee。

注意:结果中的0xc0ffee的0x说明这个数是16进制的数字,并不是数字部分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值