re_signin 【ctfshow_元旦水友赛】Reserve
题目:

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的更多相关文章
- 第一次线上OJ水友赛
偶然的机会遇到了这个神奇的网站http://www.luogu.org/ 巧遇今天又有小比赛果断去试试,为我的蓝桥北京之旅练练手. 苦苦的在机房刷了一下午,大概做到了6点半. 最激动的是等成绩了, ...
- 【题解】LFYZNoip前水题赛 T6
垃圾出题人们在30分钟内完成了讨论,出题,命题,造数据,跑std的所有环节 luv的化学竞赛题 题目背景 luv_letters 在肝化学竞赛题,他的梦想是混个省一,但是遗憾的是他今年的省二莫名消失了 ...
- 0RAYS元旦招新赛
一共有4道pwn题,题目不算难,但是挺考验调试能力的. pie 一个main函数就四次溢出... 第一次leak canary,第二次leak libc,第三次直接覆盖返回地址为one_gadgets ...
- 【Cocos2d-x游戏引擎开发笔记(25)】XML解析
原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善 ...
- CQOI2019(十二省联考)游记
CQOI2019(十二省联考)游记 Day -? 自从联赛爆炸,\(THUWC\)爆炸,\(WC\)爆炸(就没有不爆炸的)之后我已经无所畏惧... 听说是考\(4.5 h\)吗? Day -1 \(Z ...
- 魔兽争霸RPG游戏-军团战争-游戏经验总结
终于要写这篇了,上一篇是个意外. 2015年关注,一代鬼王Xun和GGL比赛.晚上11点之后,经常有水友赛.主播xun,会带着一帮小弟,玩一些游戏.比如魔兽争霸6v6,2v2,RPG游戏-军团战争,疯 ...
- 【集训第二天·翻水的老师】--ac自动机+splay树
今天是第二天集训.(其实已经是第三天了,只是昨天并没有机会来写总结,现在补上) 上午大家心情都很愉快,因为老师讲了splay树和ac自动机. 但到了下午,我们的教练竟然跑出去耍了(excuse me? ...
- dota有哪些经典的典故或笑话?
----------------------------------------------------dota有哪些经典的典故或笑话?虽然现在玩游戏也没什么热情了, 但是看到这些还是笑尿,笑点低 = ...
- 聚光灯下的熊猫TV技术架构演进
2015年开始的百播大战,熊猫TV是其中比较特别的一员. 说熊猫TV是含着金钥匙出生的公子哥不为过.还未上线,就频频曝光,科技号,微博稿,站上风口浪尖.内测期间更是有不少淘宝店高价倒卖邀请码,光内测时 ...
- 【网络可靠版】Extjs4 Treegrid 使用实例
最近调试EXTJS 4的treegrid实例,看了很多水友的文章,以及官方的demo, 没一个可靠的,全都无法显示出来.像对于我们习惯用C++的coder来说,EXTJS简直就是一群无政府土匪来维护的 ...
随机推荐
- 49从零开始用Rust编写nginx,我竟然在同一个端口上绑定了多少IP
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 负载均衡, 静态文件服务器,websocket代理,四层TCP/UDP转发,内网穿透等,会将实 ...
- 【Unity3D】UI Toolkit元素
1 前言 UI Toolkit简介 中介绍了 UI Builder.样式属性.UQuery.Debugger,UI Toolkit容器 中介绍了 VisualElement.ScrollView. ...
- 建立DNS隧道绕过校园网认证
建立DNS隧道绕过校园网认证 因为之前在本科的时候破解过校园网三次,主要就是利用其业务逻辑上的漏洞.53端口未过滤包.重放攻击的手段,然后就是一个博弈的过程,这三次加起来用了大概有一年的时间就被完全堵 ...
- Vue+SpringBoot+ElementUI实战学生管理系统-10.学生管理模块
1.章节介绍 前一篇介绍了教师管理模块,这一篇编写学生管理模块,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.实现效果 学生列表 修改学生 4.模块 ...
- 在PL/SQL中使用日期类型
在PL/SQL中使用日期类型 之前的文章介绍了在PL/SQL中使用字符串和数字了下.毫无疑问,字符串和数字很重要,但是可以确定的是没有哪个应用不依赖于日期的. 你需要记录事件的发生事件,人们的出生日期 ...
- 网站(>???<)
http://cpeditor.org/ https://csacademy.com/app/graph_editor/ https://www.cnblogs.com/zhangyi1357/p/1 ...
- SpringBoot整合Swagger2实现接口文档
展示一下 访问方式一 访问地址:http://localhost:8080/swagger-ui.html#/ 首页 详情页 访问方式二 访问地址:http://localhost:8080/doc. ...
- 【Android 逆向】【攻防世界】Ph0en1x-100
1. apk 安装到手机,老套路需要输入flag 2. jadx 打开apk,没有加壳 ...... public void onGoClick(View v) { String sInput = t ...
- 关于json序列化时报错json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
1.今天在写客户端与服务端交互的程序的时候,发现了一个问题 客户端代码 #客户端程序主要是发送注册请求/登录请求给服务端,服务端接收响应后回应对应的应答给客户端,客户端接收响应后,然后做一些操作 # ...
- kafka节点故障恢复原理
Kafka的LEO和HW LEO LEO是Topic每一个副本的最后的偏移量offset+1 HW(高水位线) High WaterMark是所有副本中,最小的LEO Follower副本所在节点宕机 ...