攻防世界Reverse三星题 zorropub
题目
分析过程
丢到PE里面,无壳,64bit
丢到IDA里面,查看mian函数
1 int __fastcall main(int a1, char **a2, char **a3)
2 {
3 size_t s_len; // rax
4 int drink_ID; // [rsp+1Ch] [rbp-104h] BYREF
5 int input; // [rsp+20h] [rbp-100h] BYREF
6 int i; // [rsp+24h] [rbp-FCh]
7 unsigned int seed; // [rsp+28h] [rbp-F8h]
8 unsigned int v9; // [rsp+2Ch] [rbp-F4h]
9 char MD5__[96]; // [rsp+30h] [rbp-F0h] BYREF
10 char MD5__1[16]; // [rsp+90h] [rbp-90h] BYREF
11 char v12[32]; // [rsp+A0h] [rbp-80h] BYREF
12 char s[32]; // [rsp+C0h] [rbp-60h] BYREF
13 char s1[40]; // [rsp+E0h] [rbp-40h] BYREF
14 unsigned __int64 v15; // [rsp+108h] [rbp-18h]
15
16 v15 = __readfsqword(0x28u);
17 seed = 0;
18 puts("Welcome to Pub Zorro!!");
19 printf("Straight to the point. How many drinks you want?");
20 __isoc99_scanf("%d", &drink_ID);
21 if ( drink_ID <= 0 )
22 {
23 printf("You are too drunk!! Get Out!!");
24 exit(-1);
25 }
26 printf("OK. I need details of all the drinks. Give me %d drink ids:", (unsigned int)drink_ID);
27 for ( i = 0; i < drink_ID; ++i ) // 输入的drink_ID决定了input的数量
28 {
29 __isoc99_scanf("%d", &input);
30 if ( input <= 16 || input > 65535 ) // 16<input<65535
31 {
32 puts("Invalid Drink Id."); // 无效的饮料ID。
33 printf("Get Out!!");
34 exit(-1);
35 }
36 seed ^= input; // 与自己异或
37 }
38 i = seed;
39 v9 = 0;
40 while ( i )
41 {
42 ++v9; // 循环了10次
43 i &= i - 1;
44 }
45 if ( v9 != 10 ) // v9=10
46 {
47 puts("Looks like its a dangerous combination of drinks right there.");// 看起来这是一种危险的饮品组合。
48 puts("Get Out, you will get yourself killed");
49 exit(-1);
50 }
51 srand(seed); // seed是rand()的种子,用来初始化rand()的起始值,该函数不返回任何值
52 MD5_Init(MD5__); // 产生一个128位(16字节)的哈希值,通常表示为一个32字符的十六进制数
53 for ( i = 0; i <= 29; ++i )
54 {
55 v9 = rand() % 1000; // 会自动调用srand(seed)一次来初始化它的起始值
56 // 随机数的范围限制在0到999
57 sprintf(s, "%d", v9); // 这一行将整数值v9转换为字符串表示,并将其存储在字符数组s
58 s_len = strlen(s);
59 MD5_Update(MD5__, s, s_len); // 执行MD5_Update函数更新md5的值
60 v12[i] = v9 ^ LOBYTE(dword_6020C0[i]); // 低字节进行按位异或操作
61 }
62 v12[i] = 0; // 加上终止符
63 MD5_Final(MD5__1, MD5__); // 计算MD__的哈希值放在前面
64 for ( i = 0; i <= 15; ++i )
65 sprintf(&s1[2 * i], "%02x", (unsigned __int8)MD5__1[i]);// 每个MD5哈希字节的十六进制表示占用两个字符的位置,所以这个2就是遍历吧
66 // X 表示以十六进制形式输出;02 表示不足两位,前面补0输出;如果超过两位,则实际输出
67 // 只取MD5__1[i]字节的低8位
68 if ( strcmp(s1, "5eba99aff105c9ff6a1a913e343fec67") )// s1=5eba99aff105c9ff6a1a913e343fec67
69 {
70 puts("Try different mix, This mix is too sloppy");// 试试不同的调料,这个调料太马虎了
71 exit(-1);
72 }
73 return printf("\nYou choose right mix and here is your reward: The flag is nullcon{%s}\n", v12);// \n您选择正确的混合,这是您的奖励:旗帜是空号{%S}\n
74 }
为了更好理解,注释中一些零碎知识点的补充:
MD5_Init(MD5__);MD5_Final(MD5__1, MD5__);MD5_Final(MD5__1, MD5__);int MD5_Init(MD5_CTX *c)函数:
初始化 MD5 Contex, 成功返回1,失败返回0
.
int MD5_Update(MD5_CTX *c, const void *data, size_t len)函数:
循环调用此函数,可以将不同的数据加在一起计算MD5,成功返回1,失败返回
.
int MD5_Final(unsigned char *md, MD5_CTX *c)函数:
输出MD5结果数据,成功返回1,失败返回0
.
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)函数:
MD5_Init,MD5_Update,MD5_Final三个函数的组合,直接计算出MD5的值
.
void MD5_Transform(MD5_CTX *c, const unsigned char *b)函数:
内部函数,不需要调用可以结合代码看:C语言 Openssl的md5使用方式_#include <openssl/md5.h>-CSDN博客
sprintf(&s1[2 * i], "%02x", (unsigned __int8)MD5__1[i])X 表示以十六进制形式输出
02 表示不足两位,前面补0输出;如果超过两位,则实际输出更多看:C语言中printf打印形式(%02X, %2X, %-2X, %.nf, %m.nf, %e, %m.ne, %2d, %-2d, %02d, %.2d)_printf %.2x-CSDN博客
补充结束,看看代码——
有两个输入(方便理解我改了名字):一个是drink_ID,另一个为input——>前者决定了后者的数量,两个一起决定了seed
seed满足一定条件后可以作为srand的种子:v9=10 以及 异或后得到赋值的i可以开启循环
这里涉及到伪随机数生成以及随机数种子的概念:
1.伪随机数生成器:计算机中的随机数通常是由伪随机数生成器生成的。这些生成器实际上是确定性算法,其输出看起来像是随机的序列,但实际上是基于一个称为“种子”的初始值来生成的。相同的种子将会生成相同的随机数序列。
2.srand() 和 rand() 函数:在 C 和 C++ 中,srand()用于设置随机数生成器的种子,而rand()用于生成随机数。如果你不调用srand()来设置种子,rand()将使用默认的种子(通常是系统时间),因此每次程序运行时都会生成不同的随机数序列。但是,如果你在每次运行程序时使用相同的种子,那么生成的随机数序列将始终相同。
v9是用特定 seed 随机数种子生成的特定的列表,后来由整数转化为字符串储存在 s 中
再把 s 更新到MD5__中,因为MD5__就只放了 s ,所以就是计算 s 的哈希值,储存在MD5__1中
MD5__1又经过遍历放在s1里面,最后s1要等于5eba99aff105c9ff6a1a913e343fec67——这就是v9经过MD5加密后得到的哈希值
v9还与dword_6020C0进行了异或操作,结果放在v12中,最后输出的flag就是v12
综上,只要v9满足条件:经过MD5加密后的值等于5eba99aff105c9ff6a1a913e343fec67,那么v9与dword_6020C0异或就可以得到flag
逆向脚本
不太会MD5py解密脚本,网上找到的没有运行出来的,就算拿5eba99aff105c9ff6a1a913e343fec67去MD5解密网站,也没有输出结果
搬了大佬的wp,下边就是爆破MD5等算法的爆破脚本
1 import subprocess
2 c=0
3 seed=[] #v5和v6都是用于生成seed种子,所以可以合并成一步
4 for i in range(16,65535,1): #源代码中是先i=seed再验证i的符合性,所以逆向的时候就要先验证i的符合性再seed=i
5 while(i):
6 c+=1
7 i&=i-1
8 if(c==10):
9 seed.append(i) #获取随机数种子列表,种子固定后rand生成的随机数就会固定。
10 flag=""
11 for i in seed: #传入符合的i值,其实就是传入一定的seed值,
12 proc=subprocess.Popen(['./zorropub'],stdin=subprocess.PIPE,stdout=subprocess.PIPE); #用subprocess的Popen方法开启proc子进程并用stdin和stdout获取子进程的输入和输出
13 out=proc.communicate(('1\n%s\n'%i).encode('utf-8'))[0] #传入参数,第一个传入1即可,第二个传入符合的seed种子,第一个无论传入多少生成的seed都只有一个,所以传入1即可。用.encode('utf-8')属性可以传入字符串参数,不然就要传入bytes类型的参数了
14 if "nullcon".encode('utf-8') in out:
15 print(out) #打印符合的输出字符串
16 print(i) #打印符合的seed值
这道题好像挺老的,我运行不出来(悲),但是学到了新的知识点:python subprocess模块 - lincappu - 博客园 (cnblogs.com)
我还发现一个pwn大佬的脚本
1 from pwn import*
2 import time
3 time1=time.time()
4 a=[]
5
6 for i in range(16,0xffff):
7 v9=0
8 i=i^0
9 j=i
10 while(i):
11 v9+=1
12 i&=i-1
13 if v9 ==10:
14 a.append(j)
15 //数组已经弄好了
16
17 for i in a:
18 p=process("./zorropub")
19 p.recv()
20 p.sendline('1')
21 p.sendline(str(i))//emmm,觉得int的也ok
22 result=p.recv()
23 if "null" in text:
24 print text
25 time2=time.time()
26 print "time %fs"%(time2-time1)
27 break
28 p.close()
还有吾爱破解大佬用动调试解出来了,我还不太会ubuntu中的VSCODE调试,插个眼以后再详细说说
这里也放上:CTF攻防世界Reverse018_zorropub逆向分析【原创】 - 『脱壳破解区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn
flag
nullcon{nu11c0n_s4yz_x0r1n6_1s_4m4z1ng}
攻防世界Reverse三星题 zorropub的更多相关文章
- 攻防世界 reverse 进阶 10 Reverse Box
攻防世界中此题信息未给全,题目来源为[TWCTF-2016:Reverse] Reverse Box 网上有很多wp是使用gdb脚本,这里找到一个本地还原关键算法,然后再爆破的 https://www ...
- 攻防世界Web刷题记录(进阶区)
攻防世界Web刷题记录(进阶区) 1.baby_web 发现去掉URLhttp://111.200.241.244:51461/1.php后面的1.php,还是会跳转到http://111.200.2 ...
- 攻防世界Web刷题记录(新手区)
攻防世界Web刷题记录(新手区) 1.ViewSource 题如其名 Fn + F12 2.get post 3.robots robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个 ...
- 攻防世界PWN简单题 level0
攻防世界PWN简单题 level0 开始考验栈溢出的相关知识了 Checksec 一下文件 看看都开了什么保护 和 是多少位的程序 发现是64位的程序, 扔进IDA64.IDA YYDS.. 进入主函 ...
- 攻防世界PWN简单题 level2
攻防世界PWN简单题 level2 此题考验的是对ROP链攻击的基础 万事开头PWN第一步checksec 一下 32位的小端程序,扔进IDA 进入函数,找出栈溢出漏洞. 又是这个位置的栈溢出,rea ...
- 攻防世界web进阶题—unfinish
攻防世界web进阶题-unfinish 1.看一下题目提示SQL 2.打开题目看一下源码,没有问题 3.查一下网站的组成:php+Apache/2.4.7+Ubuntu 4.扫一下目录,扫到一个注册页 ...
- 攻防世界web进阶题—bug
攻防世界web进阶题-bug 1.打开题目看一下源码,没有问题 2.扫一下目录,没有问题 3.查一下网站的组成:php+Apache+Ubuntu 只有登录界面 这里可以可以想到:爆破.万能密码.进行 ...
- 记录下做攻防世界的misc题
0x00 记录一下,代表自己做过 0x01 flag_universe 看简介是来自2018年的百越杯. 将文件下载下来后,就一个flag_universe.pcapng文件,wireshark打开. ...
- 攻防世界 reverse evil
这是2017 ddctf的一道逆向题, 挑战:<恶意软件分析> 赛题背景: 员工小A收到了一封邮件,带一个文档附件,小A随手打开了附件.随后IT部门发现小A的电脑发出了异常网络访问请求,进 ...
- 攻防世界 reverse tt3441810
tt3441810 tinyctf-2014 附件给了一堆数据,将十六进制数据部分提取出来, flag应该隐藏在里面,(这算啥子re,) 保留可显示字符,然后去除填充字符(找规律 0.0) 处理脚本: ...
随机推荐
- 【Azure 环境】微软云上主机,服务的安全更新疑问
[问题一]微软云上的虚拟机,不论是Windows系统or Linux 系统,系统的安全补丁是由微软云平台 打上补丁进行修复,还是使用虚拟机的用户手动更新修复呢? [答]这些补丁不会由平台来直接操作 ...
- 从全球顶级数据库大会 SIGMOD 看数据库发展趋势
本文来自 NebulaGraph 的软件工程师文豪在美国费城参加 2022 年 SIGMOD 大会时的见闻.SIGMOD 是数据库领域的顶级会议之一,是 CCF 数据库 / 数据挖掘 / 内容检索领域 ...
- mysql添加联合唯一索引与删除索引
-- 添加联合唯一索引 alter table <表名> add unique index <索引名称> (name, no, org_id); -- 删除索引 ALTER T ...
- 五: Mysql权限管理
# 权限管理 关于MySQL的权限简单的理解就是MySQL允许你做你权力以内的事情,不可以越界.比如只允许你执行SELECT操 作, 那么你就不能执行UPDATE操作.只允许你从某台机器上连接MySQ ...
- Java //在150之内 是三的倍数 输出Zzz 是5个倍数输出 Lll 是7的倍数输出zlzl
1 //在150之内 是三的倍数 输出Zzz 是5个倍数输出 Lll 是7的倍数输出zlzl 2 int i =1; 3 for(i = 1; i<=150;i++) 4 { 5 System. ...
- 面试官问我会ES么,我说不会,抓紧学起【ES(一)聚合分析篇】
ES聚合分析 1.metric(指标)聚合 1.1 单值分析 min 求指定字段的最小值 # 求价格的最小值 { "size":0, "aggs":{ &quo ...
- STM32标准库通用定时器输入捕获
STM32标准库定时器输入捕获 1.输入捕获介绍 输入捕获为STM32定时器的一个功能,可以用来测量输入信号的频率和占空比. 具体原理:当输入信号经过比较捕获通道时,STM32会依据通道的极性设置决定 ...
- 解决linux平台无法使用getch()的问题
参考https://www.cnblogs.com/jiangxinnju/p/5516906.html#:~:text=%E5%8F%A6%E5%A4%96%E5%A4%A7%E5%AE%B6%E5 ...
- stm32L4xx串口日志配置解析
前言: st这两年推出了一款超低功耗的芯片,stm32l4xx系列,该系列芯片有着功耗低,尺寸小等特点,非常适合应用在可穿戴式设备. 团队在这一领域深耕,所以不可避免的要用到这款芯片,这里就针对该芯片 ...
- Android resource DarkActionBar not found问题解决
原文: Android resource DarkActionBar not found问题解决 | Stars-One的杂货小窝 几天没改过的代码,突然就无法打开项目了 报错信息如下 在全网都找不到 ...