[2019红帽杯]easyRE

2023-10-22 21:50
文章标签 2019 红帽 easyre

本文主要是介绍[2019红帽杯]easyRE,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先ida64打开,shift+f12查看字符串,发现有you found me字段,跟进查看调用了它的函数。

发现是sub_4009C6()函数,分析

__int64 sub_4009C6()
{__int64 result; // raxint i; // [rsp+Ch] [rbp-114h]__int64 v2; // [rsp+10h] [rbp-110h]__int64 v3; // [rsp+18h] [rbp-108h]__int64 v4; // [rsp+20h] [rbp-100h]__int64 v5; // [rsp+28h] [rbp-F8h]__int64 v6; // [rsp+30h] [rbp-F0h]__int64 v7; // [rsp+38h] [rbp-E8h]__int64 v8; // [rsp+40h] [rbp-E0h]__int64 v9; // [rsp+48h] [rbp-D8h]__int64 v10; // [rsp+50h] [rbp-D0h]__int64 v11; // [rsp+58h] [rbp-C8h]char v12[13]; // [rsp+60h] [rbp-C0h] BYREFchar v13[4]; // [rsp+6Dh] [rbp-B3h] BYREFchar v14[19]; // [rsp+71h] [rbp-AFh] BYREFchar v15[32]; // [rsp+90h] [rbp-90h] BYREFint v16; // [rsp+B0h] [rbp-70h]char v17; // [rsp+B4h] [rbp-6Ch]char v18[72]; // [rsp+C0h] [rbp-60h] BYREFunsigned __int64 v19; // [rsp+108h] [rbp-18h]
​v19 = __readfsqword(0x28u);qmemcpy(v12, "Iodl>Qnb(ocy", 12);v12[12] = 127;qmemcpy(v13, "y.i", 3);v13[3] = 127;qmemcpy(v14, "d`3w}wek9{iy=~yL@EC", sizeof(v14));memset(v15, 0, sizeof(v15));v16 = 0;v17 = 0;sub_4406E0(0LL, v15, 37LL);v17 = 0;if ( sub_424BA0(v15) == 36 ){for ( i = 0; i < (unsigned __int64)sub_424BA0(v15); ++i ){if ( (unsigned __int8)(v15[i] ^ i) != v12[i] ){result = 4294967294LL;goto LABEL_13;}}sub_410CC0("continue!");memset(v18, 0, 65);sub_4406E0(0LL, v18, 64LL);v18[39] = 0;if ( sub_424BA0(v18) == 39 ){v2 = sub_400E44(v18);v3 = sub_400E44(v2);v4 = sub_400E44(v3);v5 = sub_400E44(v4);v6 = sub_400E44(v5);v7 = sub_400E44(v6);v8 = sub_400E44(v7);v9 = sub_400E44(v8);v10 = sub_400E44(v9);v11 = sub_400E44(v10);if ( !(unsigned int)sub_400360(v11, off_6CC090) ){sub_410CC0("You found me!!!");sub_410CC0("bye bye~");}result = 0LL;}else{result = 4294967293LL;}}else{result = 0xFFFFFFFFLL;}
LABEL_13:if ( __readfsqword(0x28u) != v19 )sub_444020();return result;
}

首先该函数对v12,v13,v14,v15进行了初始化操作,然后sub_4406E0是一个相当于gets的函数,将用户输入的字符串保存到v15中

接下来可以看出sub_424BA0函数是一个相当于strlen的函数,判断输入的字符串长度是否等于36,如果是再进行下一步操作,后续的you found me 输出刚好是在这第一个if条件里面,所以首先flag长度为36,具体是什么再继续进行分析。

下面for循环里面的if条件是一个关键,如果v15里面有一个字符异或i之后和v12里对应的字符不同,就会进行goto 操作,然后结束这个函数。

if ( sub_424BA0(v15) == 36 ){for ( i = 0; i < (unsigned __int64)sub_424BA0(v15); ++i ){if ( (unsigned __int8)(v15[i] ^ i) != v12[i] ){result = 4294967294LL;goto LABEL_13;}}
LABEL_13:if ( __readfsqword(0x28u) != v19 )sub_444020();

flag要满足的条件之2就是,v15[i] ^ i == v12[i], v12已经给出

但是具体 i 的范围是0~strlen(v15), 也就是说 0<= i < 36,而v12长度只有13,但是注意到这三个数组是连续存放的,所以再访问的时候应该也是连续访问,所以实际上就是三个数组合在一起成为目标数组。

char v12[13]; // [rsp+60h] [rbp-C0h] BYREF
char v13[4]; // [rsp+6Dh] [rbp-B3h] BYREF
char v14[19]; // [rsp+71h] [rbp-AFh] BYREF

按照逻辑,可以编写python脚本:

hint = []
str1 = "Iodl>Qnb(ocy"
for i in range(len(str1)):hint.append(ord(str1[i]))
hint.append(127)
​
str2 = "y.i"
for i in range(len(str2)):hint.append(ord(str2[i]))
hint.append(127)
​
str3 = "d`3w}wek9{iy=~yL@EC"
​
for i in range(len(str3)):hint.append(ord(str3[i]))
str = ""
for i in range(len(hint)):str += chr(hint[i] ^ i)
print(str)

结果是

提示说flag的前四位是flag。。。。。

关于v12,v13,v14三个数组是连续的, ida+Ubuntu动态调试证明一下

首先先在调用数组前下断点

进程停留在这里

可以看出这里是连续执行了36次mov操作,将存储在v12,v13,v14中的所有字符都放在了连续的地址中

那么在循环异或的时候,当i大于了v12的数组长度时,实际上取到的值就是v13的元素,类推。

而后是sub_400E44函数被调用了十次,双击查看发现函数的功能是base64编码。

也就是v18被base64编码了10次,最终的结果储存在v11中

然后是if判断,调用了sub_400360函数,是一个类似于strcmp的函数,如果off_6CC090和v11的所有元素都相等,就输出you found me

也就是找到了flag。

然后就是写脚本解码

import base64
lis =           "Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=="
for i in range(10):lis = base64.b64decode(lis)
print(lis)

最后得到的结果是一个网址。。。。

看来是被坑了,这里面应该没有想要的flag

参考WP,发现程序在正常执行后要执行在这里的sub_400D35函数:

跟进查看:

unsigned __int64 sub_400D35()
{unsigned __int64 result; // raxunsigned int v1; // [rsp+Ch] [rbp-24h]int i; // [rsp+10h] [rbp-20h]int j; // [rsp+14h] [rbp-1Ch]unsigned int v4; // [rsp+24h] [rbp-Ch]unsigned __int64 v5; // [rsp+28h] [rbp-8h]
​v5 = __readfsqword(0x28u);v1 = sub_43FD20(0LL) - qword_6CEE38;for ( i = 0; i <= 1233; ++i ){sub_40F790(v1);sub_40FE60();sub_40FE60();v1 = sub_40FE60() ^ 0x98765432;}v4 = v1;if ( ((unsigned __int8)v1 ^ byte_6CC0A0[0]) == 102 && (HIBYTE(v4) ^ (unsigned __int8)byte_6CC0A3) == 103 ){for ( j = 0; j <= 24; ++j )sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v4 + j % 4)));}result = __readfsqword(0x28u) ^ v5;if ( result )sub_444020();return result;
}

关键代码区域是第二十行那里的if和for循环,第一个if判断, 可以根据flag和已知数组反向解出v1

后边的for循环可以根据已知数组和v4解出flag

这就是已知数组:

v1 = ''
enc1 = 'flag'
flag = ''
str = [0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
for i in range(4):v1 += chr(str[i] ^ ord(enc1[i]))
print (v1)
​
for i in range(len(str)):flag += chr(str[i] ^ ord(v1[i % 4]))
print(flag)

str里是已知数组对应的ASCII码16进制数,变量v1中存放的就是它的地址,然后将其赋值给v4后再在for循环中进行引用。

(&v4 + j % 4也就是v4[j % 4])参考C语言运算符优先级, % > + > &

最后的输出是

也就是说最终结果为

flag{Act1ve_Defen5e_Test}

这篇关于[2019红帽杯]easyRE的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/263799

相关文章

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

2019学习计划

工作三年了,第一年感觉是荒废的,第二年开始学习python,第三年开始自动化 感觉自己会的东西比较少,而且不够深入,流于表面 现制定一下今年大概的学习计划 需持续巩固加强:python、ui自动化、接口自动化、sql等 代码量需提升,敲的不够(重点) 学习: 1.移动端测试,appium等 2.前端知识系统整理学习  3.性能测试 4.docker入门,环境搭建 5.shell

红帽RHEL8 多路径配置详解

本文为云贝教育 刘老师 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 引言 在现代数据中心中,为了提高存储系统的可靠性和性能,多路径技术成为了一种重要的解决方案。多路径技术允许多条物理路径同时连接到同一个存储设备,从而提高了系统的可用性和I/O性能。本文将详细介绍如何在Linux系统中配置多路径技术,包括多路径的基本原理、配置步骤以及常见问题的解决方法。

最简单的使用JDBC[连接数据库] mysql 2019年3月18日

最极简版本的, 我们这里以mysql为例: 首先要创建maven工程, 需要引入jar包:,这里需要注意, 如果你安装的是mysql最新版本8以上的, 下面有些地方需要更改,具体就是mysql连接的url, 和5版本的不一样,具体解决请自行百度哈.这里只演示mysql5版本的? 依赖: <dependency>   <groupId>mysql</groupId>   <artifactId

(php伪随机数生成)[GWCTF 2019]枯燥的抽奖

审核源码发现加载check.php,审计发现使用了mt_rand()函数,这个函数生成的值是伪随机的 参考下面这篇文章 PHP mt_rand安全杂谈及应用场景详解 - FreeBuf网络安全行业门户 kali里面输入下载工具 git clone https://github.com/openwall/php_mt_seed.git cd进去输入make后编译出的文件先

2019年2月17日

今天又重新看了一下输出第1500个丑数 在我错了八次之后发现要输出一个句号还要输出换行 接下来的两天应该进入复习阶段了。

National Contest for Private Universities (NCPU), 2019 E. Generalized Pascal's Triangle

编辑代码 2000ms 262144K Generalized Pascal's Triangle Pascal's triangle is a triangular array in which each number can be calculated by the sum of the two numbers directly above that number as shown i

Hinton等人最新研究:大幅提升模型准确率,标签平滑技术 2019-7-8

导读:损失函数对神经网络的训练有显著影响,也有很多学者人一直在探讨并寻找可以和损失函数一样使模型效果更好的函数。后来,Szegedy 等学者提出了标签平滑方法,该方法通过计算数据集中 hard target 的加权平均以及平均分布来计算交叉熵,有效提升了模型的准确率。近日,Hinton 团队等人在新研究论文《When Does Label Smoothing Help?》中,就尝试对标签平滑技术对

Photoshop CC 2019圆形的抠图

快速进入矩形选区 快速在矩形和圆形选区之前切换: shift+M 选择的时候,按住shift,可以选中正方形/圆形   以中心点画圆: alt + 拖拽 再利用变换选区功能即可实现圆的选中 效果如图所示: 再使用自由变换,即可放大,缩小球的大小: ctrl + T 阴影部分的处理: 1)去其他球那里选择个椭圆形选区 2)选择编辑-填充 3)使用滤镜里

Windows Server 2019 中文版、英文版下载 (updated Aug 2024)

Windows Server 2019 中文版、英文版下载 (updated Aug 2024) Windows Server 2019 Version 1809 请访问原文链接:https://sysin.org/blog/windows-server-2019/,查看最新版。原创作品,转载请保留出处。 本站将不定期发布官方原版风格月度更新 ISO。 Windows Server