CTF Show Reverse - 【re3】

感谢@shimly清风师傅提供的题目

提交最小解即可,4位值

下载下来一个r3.r3文件,拖到ida中运行,是64位的,main函数并不是很复杂

strncpy(dest, v19, len - 6);

前面看着都还行,就是简单的赋值输入打印,但是strncpy这个地方让我有点奇怪,前面也没给v19赋值,这里怎么copy啊,回去看下地址,这里s的长度限制为5*sizeof(char),那么scanf多出来的就会覆盖到v19上

那么这行代码就可以这么转换,也就是取出了flag{}包裹的字符串

# v19就相当于是
v19 = s[5:]
# len(v19) = len(s)-5
# len - 6 = len(s) - 6  = len(v19) - 1
# strncpy(dest, v19, len - 6);就相当于
dest = s[5:-1]

__isoc99_sscanf(dest, "%x", &v5); 

这行代码也不是很懂,问了下gpt,主要作用就是把dest以十六进制转成数字赋值给v5,其实就是把flag转为数字

这行代码是在C语言中使用的,其功能是从字符串dest中按照%x的格式字符串提取一个十六进制的数值,并将这个数值赋给变量v5

具体来说:

  • __isoc99_sscanf 是C语言中的一个函数,它与sscanf函数类似,都是用于从一个字符串中按照指定的格式字符串提取数据的
  • dest 是需要从中提取数据的字符串
  • "%x" 是一个格式字符串,它告诉__isoc99_sscanf函数,从dest字符串中提取的是一个十六进制的数值
  • &v5 是一个指针,指向变量v5的内存地址。这样,提取出的十六进制数值就会被赋值给v5

所以,这行代码的整体含义是:从字符串dest中按照十六进制的格式提取一个数值,并赋给变量v5

赋值

根据上面一步,这个地方的赋值其他都是固定的值,只有v5是变化的

循环

根据上一步得出的结论,可以知道v17前6个值都是固定的,那么循环前五次的结果也是固定的

这个地方建议用ida的动态调试去看,提示中给出值为4位,那么就假设给的flag是flag{0000},调出来发现,i=6时,v16的值是000000000000E560,v17[6]=v5,那么v16+v5结果等于0xFFFF,退出循环,然后判断成功,所以v5=0xFFFF-v16=0x1A9F,提示也要求最小值,成功

提交flag也是成功,flag为:

flag{1a9f}


ida动态调试可能遇到的问题

ida不显示对应的debugger

不知道咋的,ida很久没用,突然debug选项少了remote windows debugger,网上几乎没有找到相关的信息,更多的是利用windbg,比如IDA win10 找不到 windbg 解决方案,不过讲的还行,有知道咋回事的大佬可以评论留言一下,感谢

我看到还支持Remote Linux debugger,就是IDA目录下面,找dbgsrv目录,下面有两个linux的,一般来说选64位的,可以尝试一下,拖到Linux系统下运行就行

zsh: permission denied

执行以下命令后,报错 zsh: permission denied

./linux_server64
# zsh: permission denied: ./linux_server64

这个是因为用户对这个文件没有权限,需要添加权限

chmod u+x linux_server64

chmod是权限管理命令change the permissions mode of a file的缩写
u代表所有者。x代表执行权限。’+’ 表示增加权限
chmod u+x linux_server64 就表示对当前目录下的file.sh文件的所有者增加可执行权限

参考这篇博客zsh: permission denied问题的解决办法 

分析的程序也要放入linux

文件先加载到ida中,debugger没有配置,用的是文件默认的值,然后就会提示报错,但是最后有个框弹出来确认以后,会自动传到虚拟机里,这个不知道为什么

后面再尝试的时候,会提示application和inputfile为空,然后焦点会在parameter上,后面又尝试了一下,又不需要了,有点奇怪的

注意,Hostname要填虚拟机的ip地址

自己在win下用ida分析,分析时间长了,就想用python写脚本跑一下

win下无法执行源程序,就想着换语言重写程序,甚至拖到linux运行写的程序

就是没想到在linux下运行源程序,找了大佬的博客,还奇怪人家怎么写的那么好,跟ida上伪代码几乎一模一样,结果还很快就出来了

REVERSE-PRACTICE-CTFSHOW-2_ctfshow reverse 武穆遗书-CSDN博客

CTFShow re3-CSDN博客

https://www.cnblogs.com/ethan269/p/ctfshow_re3.html

https://blog.51cto.com/u_15127693/3946419

https://www.cnblogs.com/cjjcn/p/16141836.html#r2


自己写了脚本,跑俩小时还在i=3,电脑都发烫了 

#include <stdio.h>
#include <string.h>
#include <stdint.h> // 引入 stdint.h 以便使用 uint64_t

int main() {
    // Initialize variables
    uint32_t v7 = 80;
    uint32_t v8 = 64227;
    uint32_t v9 = 226312059;
    uint32_t v10 = 1540056586; // 将负数转换为正数
    uint32_t v11 = 5;
    uint32_t v12 = 16;
    uint32_t v13 = 3833;
    uint32_t v5 = 0;
    uint64_t v16 = 0; // 使用 uint64_t 类型

    printf("plz input the key:\n");
    char s[100];
    scanf("%s", s);
    // printf("%s\n", s);

    char dest[100];
    strncpy(dest, &s[5], strlen(s) - 6); // 复制从第5个字符开始的部分
    dest[strlen(s) - 6] = '\0'; // 添加字符串结束符
    printf("%s\n", dest);

    // 将十六进制字符串转换为整数
    sscanf(dest, "%x", &v5);
    printf("%u\n", v5);


    uint32_t v17[] = {v7, v8, v9, v10, (v11 << 12) + v12, v13, v5};
    printf("[%u, %u, %u, %u, %u, %u, %u]\n", v17, v17[1], v17[2], v17[3], v17[4], v17[5], v17[6]);

    for (size_t i = 0; i < sizeof(v17); ++i) {
        v16 += v17[i];
        while (v16 > 0xFFFF) {
            uint32_t v15 = v16 >> 16;
            v16 = v15 + v16;
            // v16 = v16 % ((uint64_t)1 << 64); // 对2的64次方取余
            v16 &= 0xFFFFFFFFFFFFFFFF;
        }
        printf("%d: %d\n", i, v16);
    }

    if (v16 == 0xFFFF) {
        printf("OK\n");
    } else {
        printf("Error\n");
    }

    return 0;
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值