当前位置: 首页 > article >正文

逆向攻防世界CTF系列27-200simple-check-100

逆向攻防世界CTF系列27-200simple-check-100

巨难受的一题,gdb环境配了半天

32位无壳

image-20241111204514578

这里要check,先跟进下面的interesting_function看看

image-20241111204605642

putchar,这里就是输出,那我们只需要动调将check_key那修改为正确就行

image-20241111204712189

下断点

image-20241111204747074

右上角右键modify成1

image-20241111204856485

但是输出乱码。

查阅资料后可以用gbd动调

环境配了半天

如果是2024-11-11左右安装gbd如果出现报错,可以参考[Kali 2024 逆向调试 GDB 13.2 安装插件 Peda 不兼容报错解决方案_kali安装gdb-CSDN博客](https://blog.csdn.net/qq_51886509/article/details/141227182?ops_request_misc=%7B%22request%5Fid%22%3A%22984C9D72-904C-4F18-B580-8A359D6C46D7%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=984C9D72-904C-4F18-B580-8A359D6C46D7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~times_rank-2-141227182-null-null.142v100pc_search_result_base4&utm_term=no module named six gdb&spm=1018.2226.3001.4187)

开始

gbd

file task9_x86_64_46d01fe312d35ecf69c4ff8ab8ace75d080891dc

设置断点在main函数入口处

b main

开始运行

r

到这里继续单步执行,一直到test eax,eax那

n

查看eax寄存器值

i r eax

修改eax寄存器值

set $eax=1

image-20241111205118089

修改就行

直接运行至程序结束

c

flag:

flag_is_you_know_cracking!!!

到这,其实还有解法,那就是纯静态分析,来自攻防世界的wp

unsigned int *__cdecl interesting_function(int *a1)
{
  unsigned int *result; // eax
  unsigned int v2; // [esp+1Ch] [ebp-1Ch] BYREF
  unsigned int *v3; // [esp+20h] [ebp-18h]
  int *v4; // [esp+24h] [ebp-14h]
  int j; // [esp+28h] [ebp-10h]
  int i; // [esp+2Ch] [ebp-Ch]

  result = (unsigned int *)a1;
  v4 = a1;
  for ( i = 0; i <= 6; ++i )
  {
    v2 = v4[i] ^ 0xDEADBEEF;
    result = &v2;
    v3 = &v2;
    for ( j = 3; j >= 0; --j )
      result = (unsigned int *)putchar((char)(*((_BYTE *)v3 + j) ^ flag_data[4 * i + j]));
  }
  return result;
}

这里无非是对flag做处理,enc来自flag_data,都可以获取,要点耐心还是可以解密的

我们不用管check_key,它的作用只是验证,我们目的是输出flag

#include <stdio.h>

unsigned char flag_data[] = {
	220, 23, 191, 91, 212, 10, 210, 27, 125, 218,
	167, 149, 181, 50, 16, 246, 28, 101, 83, 83,
	103, 186, 234, 110, 120, 34, 114, 211 };
char v7[] = {
	84, -56, 126, -29, 100, -57, 22, -102, -51, 17,
	101, 50, 45, -29, -45, 67, -110, -87, -99, -46,
	-26, 109, 44, -45, -74, -67, -2, 106 };

unsigned int v2;
unsigned char* v3;

int main() {
	for (int i = 0; i <= 6; ++i) {
		v2 = ((v7[4 * i] & 0x000000FF) + ((v7[4 * i + 1] & 0x000000FF) << 8)
			+ ((v7[4 * i + 2] & 0x000000FF) << 16) + ((v7[4 * i + 3] & 0x000000FF) <<
				24)) ^ 0xDEADBEEF;
		v3 = (unsigned char*)&v2;
		for (int j = 3; j >= 0; --j) printf("%c", *(v3 + j) ^ flag_data[4 * i + j]);
	}
	printf("\n");
	for (int i = 0; i <= 6; ++i) {
		printf("%c", v7[4 * i + 3] ^ 0xDE ^ flag_data[4 * i + 3]);
		printf("%c", v7[4 * i + 2] ^ 0xAD ^ flag_data[4 * i + 2]);
		printf("%c", v7[4 * i + 1] ^ 0xBE ^ flag_data[4 * i + 1]);
		printf("%c", v7[4 * i] ^ 0xEF ^ flag_data[4 * i]);
	}
}

解释一下两种解法,第一种是直接模仿源码,第二种其实也是一样不过进一步理解了

第一种先进行处理,原文中的v4[i]其实是4个字节,从循环i<=6也可以猜到,是四个四个处理的

那么第二层循环只是挨个输出而已

第二种方法其实就是直接进行处理,因为是小端字节序,低位在低地址

所以我们看到的v7其实是小端序,我们要给它还原成我们熟知的顺序

for (int j = 3; j >= 0; --j) printf(“%c”, *(v3 + j) ^ flag_data[4 * i + j]);这个其实做的也是逆序

理,因为是小端字节序,低位在低地址

所以我们看到的v7其实是小端序,我们要给它还原成我们熟知的顺序

for (int j = 3; j >= 0; --j) printf(“%c”, *(v3 + j) ^ flag_data[4 * i + j]);这个其实做的也是逆序

image-20241111211020181


http://www.kler.cn/a/389739.html

相关文章:

  • ubuntu ros 解决建完图后 保存的地图非常小的问题
  • redhat虚拟机
  • centos7上安装mysql
  • 3.5【数据库系统】ER图
  • group_concat配置影响程序出bug
  • Django博客网站上线前准备事项
  • 【HarmonyNext】显示提示文字的方法
  • 【大数据学习 | HBASE高级】storeFile文件的合并
  • 【智谱开放平台-注册/登录安全分析报告】
  • 数据中心类DataCenter(二)
  • 【Linux 31】网络层协议 - IP
  • 【嵌入式设备】蓝牙鼠标使用教程——遥控器编码值
  • Netty篇(WebSocket)
  • VSCode + linux 远程免密登录
  • WSL 2 中 FastReport 与 FastCube 的设置方法与优化策略
  • Android 单元测试环境配置问题 Execution failed for task ‘:mergeDebugJavaResource‘.
  • J2EE平台
  • CompletableFuture:supplyAsync与runAsync
  • 【Spring】Spring框架中有有哪些常见的设计模式
  • macOS 下的 ARM 裸机嵌入式开发入门- 第二部分:实现第一个裸机应用并且调试
  • 深入提升Python编程能力的全方位指南
  • mac 安装指定的node和npm版本
  • 中间件安全
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:数据加载策略如何决定分析速度(上)(15/30)
  • 机器学习(基础1)
  • 基于springboot+小程序的鲜花管理系统(鲜花1)