题目:


IDA反编译

主函数

 1 int __cdecl main(int argc, const char **argv, const char **envp)
2 {
3 char s2[144]; // [rsp+0h] [rbp-1A0h] BYREF
4 char s1[128]; // [rsp+90h] [rbp-110h] BYREF
5 char input[136]; // [rsp+110h] [rbp-90h] BYREF
6 int key; // [rsp+198h] [rbp-8h]
7 int input_len; // [rsp+19Ch] [rbp-4h]
8
9 memset(input, 0, 0x80uLL);
10 memset(s1, 0, sizeof(s1));
11 memset(s2, 0, sizeof(s2));
12 s2[0] = 0x9C;
13 s2[1] = 0xCC;
14 s2[2] = 0x88;
15 s2[3] = 0x76;
16 s2[4] = 0xD7;
17 s2[5] = 0x89;
18 s2[6] = 0x78;
19 s2[7] = 0xEC;
20 s2[8] = 0x7C;
21 s2[9] = 0xD7;
22 s2[10] = 0x89;
23 s2[11] = 0x71;
24 s2[12] = 0xE3;
25 s2[13] = 0x6D;
26 s2[14] = 0x98;
27 s2[15] = 0x17;
28 s2[16] = 0x94;
29 s2[17] = 0xF;
30 s2[18] = 0xCA;
31 s2[19] = 0x9F;
32 s2[20] = 0x7E;
33 s2[21] = 0xD9;
34 s2[22] = 0xA0;
35 s2[23] = 0x8A;
36 s2[24] = 0x79;
37 s2[25] = 0xD1;
38 s2[26] = 0x80;
39 s2[27] = 0x77;
40 printf(&byte_400A66, s2, 18LL);
41 fgets(input, 128, stdin);
42 input_len = strlen(input);
43 if ( input[input_len - 1] == 10 )
44 input[input_len - 1] = 0;
45 key = generate_key(877);
46 encrypt((__int64)input, (__int64)s1, 2024, key);
47 if ( !memcmp(s1, s2, 128uLL) )
48 puts("success");
49 else
50 puts("fail");
51 return 0;
52 }

加密函数

 1 __int64 __fastcall encrypt(__int64 input, __int64 s1, int num2024, int key)
2 {
3 __int64 result; // rax
4 int i; // [rsp+20h] [rbp-8h]
5 int v6; // [rsp+24h] [rbp-4h]
6 unsigned int v7; // [rsp+24h] [rbp-4h]
7
8 v6 = 0;
9 for ( i = 0; i <= 127; ++i )
10 {
11 result = *(unsigned __int8 *)(i + input); // input[i]=result
12 if ( (_BYTE)result )
13 {
14 v7 = key + num2024 + v6;
15 *(_BYTE *)(i + s1) = *(_BYTE *)(i + input) + v7;// s1[i]=input[i]+v7
16 // v7是偏移量
17 result = (v7 >> 4) ^ *(unsigned __int8 *)(i + s1);// 等于没有
18 v6 = (v7 >> 4) ^ *(unsigned __int8 *)(i + s1);// v6储存的是上一个result的值
19 }
20 }
21 return result;
22 }

KEY

1 __int64 __fastcall generate_key(int a1)
2 {
3 return (unsigned int)(1540483477 * a1 + 305419896) >> 16;
4 }

输入值

s2 = [
0x9C, 0xCC, 0x88, 0x76, 0xD7, 0x89, 0x78, 0xEC,
0x7C, 0xD7, 0x89, 0x71, 0xE3, 0x6D, 0x98, 0x17,
0x94, 0x0F, 0xCA, 0x9F, 0x7E, 0xD9, 0xA0, 0x8A,
0x79, 0xD1, 0x80, 0x77
]

个人记录

获得key值——C代码

参考大佬的部分wp:2024ctfshow元旦水友赛 RE re_signin-CSDN博客

 1 #include<stdio.h>
2
3 unsigned int ge(unsigned int s) {
4 s = 1540483477 * s + 305419896;
5 return (s >> 16);
6 }
7
8 int main() {
9 unsigned int k = 877; // 为变量 k 赋一个初始值
10 unsigned int key = ge(k); // 调用 ge 函数来计算密钥 key
11 printf("%x", key); // 使用 %x 格式化字符串打印无符号整数值(十六进制)
12 return 0;
13 }

最初的代码11行用的是"%u"——打印出来的是十进制数:41041

但是参考了大佬的py代码:ctfshow 元旦水友赛部分wp | M4sh1r0の万事屋 (m4shir0.com)

大佬用的是十六进制,写解题脚本的时候也是多用0xA051这种十六进制数,就改成"%x"

关于大佬解题wp的疑惑

大佬代码

 1 key = 0xA051
2 num = 2024
3 table = []
4 cmp = [0x9C, 0xCC, 0x88, 0x76, 0xD7, 0x89, 0x78, 0xEC, 0x7C, 0xD7, 0x89, 0x71, 0xE3, 0x6D, 0x98, 0x17, 0x94, 0x0F, 0xCA, 0x9F, 0x7E, 0xD9, 0xA0, 0x8A, 0x79, 0xD1, 0x80, 0x77]
5
6 tb = 0
7 flag = []
8 for i in range(28):
9 ta = key + num + tb
10 flag.append((cmp[i] - (ta&0xff)) & 0xff)
11 tb = (ta >> 4) ^ cmp[i]
12 print(''.join(chr(i) for i in flag))

flag.append((cmp[i] - (ta&0xff)) & 0xff)——这一部分的我没看懂

ta是偏移量,加密代码里是与偏移量相加,解题脚本里面就相减,这我能理解

(ta&0xff)) & 0xff——这个我就不太理解为什么这样写

以下是关于疑问的解答(参考:C语言的整数溢出机制 - 知乎 (zhihu.com)

ta&0xff——提取了ta中的最低8位,为了获取一个有效字节值(8位)

为什么是8位?

首先这是一个无符号位char类型数对于signed char,正整数最大值为127,负整数最小值为128。unsigned char所能表示的最大值为255。

有符号整型溢出又可分为向上溢出和向下溢出。假设用k个字节表示一个整型变量, 那么这个变量可以表示的有符号整数的范围是-2^(8k-1) ~ 2^(8k-1) – 1

那么两个正整数或者两个负整数相加就有可能超过这个整型变量所能表示的范围

向上超出>2^(8k-1) – 1我们称之为向上溢出

向下超出<-2^(8k-1), 我们称之为向下溢出

无论是向上溢出还是向下溢出,绝对值都在相对于无符号整型能表示的范围内————对于signed char,如果结果为400,超出了位数表示范围,取结果的低八位

& 0xff——这个操作是为了确保结果在一个字节范围内(0到255),因为解密的结果应该是一个字节

那可以去掉吗?

GPT回答:

在这种情况下,去掉 `(ta&0xff)` 后的 `& 0xff` 是可能的,但是需要对解密结果的范围进行一些考虑。

`(ta&0xff)` 的目的是确保偏移量 `ta` 的范围在0到255之间,因为偏移量是一个字节(8位)的值。在实际应用中,这个操作可以确保解密结果在0到255之间,即一个字节的范围内。

如果你确定在加密过程中偏移量的计算不会导致超出一个字节的范围(例如,`key`、`num` 和 `tb` 的取值都在合适的范围内),那么去掉 `(ta&0xff)` 后的 `& 0xff` 是可以的。

但是,如果你不确定加密过程中的偏移量是否会超出一个字节的范围,保留 `& 0xff` 可以确保解密结果始终在合适的范围内,这样更加安全可靠。


flag

ctfshow{happy_2024_jiayou_a}

re_signin 【ctfshow_元旦水友赛】Reserve的更多相关文章

  1. 第一次线上OJ水友赛

    偶然的机会遇到了这个神奇的网站http://www.luogu.org/   巧遇今天又有小比赛果断去试试,为我的蓝桥北京之旅练练手. 苦苦的在机房刷了一下午,大概做到了6点半. 最激动的是等成绩了, ...

  2. 【题解】LFYZNoip前水题赛 T6

    垃圾出题人们在30分钟内完成了讨论,出题,命题,造数据,跑std的所有环节 luv的化学竞赛题 题目背景 luv_letters 在肝化学竞赛题,他的梦想是混个省一,但是遗憾的是他今年的省二莫名消失了 ...

  3. 0RAYS元旦招新赛

    一共有4道pwn题,题目不算难,但是挺考验调试能力的. pie 一个main函数就四次溢出... 第一次leak canary,第二次leak libc,第三次直接覆盖返回地址为one_gadgets ...

  4. 【Cocos2d-x游戏引擎开发笔记(25)】XML解析

    原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善 ...

  5. CQOI2019(十二省联考)游记

    CQOI2019(十二省联考)游记 Day -? 自从联赛爆炸,\(THUWC\)爆炸,\(WC\)爆炸(就没有不爆炸的)之后我已经无所畏惧... 听说是考\(4.5 h\)吗? Day -1 \(Z ...

  6. 魔兽争霸RPG游戏-军团战争-游戏经验总结

    终于要写这篇了,上一篇是个意外. 2015年关注,一代鬼王Xun和GGL比赛.晚上11点之后,经常有水友赛.主播xun,会带着一帮小弟,玩一些游戏.比如魔兽争霸6v6,2v2,RPG游戏-军团战争,疯 ...

  7. 【集训第二天·翻水的老师】--ac自动机+splay树

    今天是第二天集训.(其实已经是第三天了,只是昨天并没有机会来写总结,现在补上) 上午大家心情都很愉快,因为老师讲了splay树和ac自动机. 但到了下午,我们的教练竟然跑出去耍了(excuse me? ...

  8. dota有哪些经典的典故或笑话?

    ----------------------------------------------------dota有哪些经典的典故或笑话?虽然现在玩游戏也没什么热情了, 但是看到这些还是笑尿,笑点低 = ...

  9. 聚光灯下的熊猫TV技术架构演进

    2015年开始的百播大战,熊猫TV是其中比较特别的一员. 说熊猫TV是含着金钥匙出生的公子哥不为过.还未上线,就频频曝光,科技号,微博稿,站上风口浪尖.内测期间更是有不少淘宝店高价倒卖邀请码,光内测时 ...

  10. 【网络可靠版】Extjs4 Treegrid 使用实例

    最近调试EXTJS 4的treegrid实例,看了很多水友的文章,以及官方的demo, 没一个可靠的,全都无法显示出来.像对于我们习惯用C++的coder来说,EXTJS简直就是一群无政府土匪来维护的 ...

随机推荐

  1. AT_arc125_c [ARC125C] LIS to Original Sequence 题解

    题目传送门 前置知识 贪心 | 构造 解法 对于任意一个未加入序列 \(P\) 的数 \(x<A_{i}(1 \le i \le k-1)\),如果其放在了 \(A_{i}\) 的前面,会导致最 ...

  2. Python 中global 关键字理解

    Python中的global关键字,你了解吗? 前言 今天来了解下 Python 中的 global 关键字. Python变量的作用域 实战案例演示之前,先要了解下 Python 的作用域. Pyt ...

  3. Linux 中hdparm命令参数说明

    hdparm命令提供了一个命令行的接口用于读取和设置IDE或SCSI硬盘参数. 语法 hdparm(选项)(参数) 选项 -a:设定读取文件时,预先存入块区的分区数,若不加上选项,则显示目前的设定: ...

  4. Lora 模块E22-400T22D(SX1268, 22dBm)

    无线串口(UART)模块, 基于SEMTECH SX1268射频芯片, 具有多种传输方式, 工作在410.125至493.125MHz频段(默认 433.125MHz). LoRa扩频技术, TTL电 ...

  5. Linux下csv转Excel xlsx文件保持身份证号后三位不被省略

    在Win下, 可以用Excel 或 WPS Spreadsheet里面的Data->Import, 将csv内容正确导入. 但是在Linux下, WPS的Spreadsheet不提供Data-& ...

  6. 【Unity3D】2D动画

    1 图片处理 ​ 通过 PS 软件将以下 gif 文件中的黑色背景删除,并将其中的 18 个图层分别保存为 png 格式图片. 2 游戏对象 ​ 1)游戏对象层级结构 ​ 2)Transform组件参 ...

  7. win32-ReadProcessMemory 的使用

    std::vector<std::byte> ReadBytes(PVOID address, SIZE_T length) { std::vector<std::byte> ...

  8. SpringBoot 服务接口限流,搞定!

    来源:blog.csdn.net/qq_34217386/article/details/122100904   在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流.限流可以认为服务降级的一种 ...

  9. .net core6 Autofac依赖注入

    一.引言 .net core6在文件方面是精简了,所以配置方面也发生了部分变化:下面记录下.net core6中怎么配置Autofac 进行依赖注入. 二.项目创建 1).首先引用两个包:在Nuget ...

  10. 【Azure事件中心】使用Python SDK(Confluent)相关方法获取offset或lag时提示SSL相关错误

    问题描述 使用Python SDK(Confluent)相关方法获取offset或lag时, 提示SSL相关错误, 是否有更清晰的实例以便参考呢? 问题解决 执行代码,因为一直连接不成功,所以检查 c ...