陕西省赛2023-部分Reverse复现

news2024/11/25 6:50:31

目录

我的upx -d怎么坏了

动调脱upx壳:

babypython

BadCoffee

ob混淆:


我的upx -d怎么坏了

打开附件,发现是upx壳,应该是修改了区段名或者特征码

 

 但是修改过还是不对.....(哭.jpg)应该还是改了其他

好学长告诉我直接动态调试脱壳

动调脱upx壳:

在吾爱破解版OD里面打开,

 打开位置可以看到上面一点就有popad指令,在上面下断点

 F9程序运行到下一个断点

1 处是循环处理栈空间, 2 处有个大跳转,从0x41C131跳转到0x4012D0处,可能是程序的ope入口,F7跟进0x4012D0,在此处用插件dump程序出来

 

 直接点脱壳保存,就可以得到脱壳后的程序

 没显示壳了,放入到ida中,迷宫题

int sub_40143C()
{
  char Str[100]; // [esp+1Ch] [ebp-74h] BYREF
  int len; // [esp+80h] [ebp-10h]
  int v3; // [esp+84h] [ebp-Ch]
  int v4; // [esp+88h] [ebp-8h]
  int i; // [esp+8Ch] [ebp-4h]

  sub_401B10();
  printf("Please input your flag: ");
  scanf("%s", Str);
  len = strlen(Str);
  v4 = 1;
  v3 = 1;
  for ( i = 0; i < len; ++i )
  {
    switch ( Str[i] )
    {
      case 'U':                                 // 上
        --v4;
        break;
      case 'D':                                 // 下
        ++v4;
        break;
      case 'L':                                 // 左
        --v3;
        break;
      case 'R':                                 // 右
        ++v3;
        break;
    }
    if ( sub_401410(v4, v3) )                   // 迷宫图
      break;
    if ( aS0000000000000[15 * v4 + v3] == 35 )  // 走合适路线是值最终为35
    {
      printf("You are right!\nflag is flag{md5(your put)}");
      return 0;
    }
  }
  puts(Buffer);
  return 0;
}

 推荐一位学长的博客,自动走迷宫脚本(膜拜大佬.jpg):(124条消息) C语言实现自动走迷宫 自动输出迷宫路径_OrientalGlass的博客-CSDN博客

下面是引用的博客代码:


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <Windows.h>
// 枚举一些关键常量,可以根据迷宫的不同而修改
enum state
{
	start = 'S', end = '#', road = '0', wall = '*', visited = '1', successPath = '%', currentPosition = '@'
}State;
//路径操作符枚举
enum operate {
	up = 'U', right = 'R', down = 'D', left = 'L'
}Operate;
//保存路径
struct
{
	int len;
	unsigned char arr[1000];
}Path;
//输入路径
void inputPath(unsigned char op)
{
	Path.arr[Path.len] = op;
	Path.len++;
}
//输出路径
void printPath()
{
	printf("\nPath:");
	while (Path.len > 0)
	{
		Path.len--;
		putchar(Path.arr[Path.len]);
	}
	printf("\n");
}
//判断是否在迷宫范围内以及是否可以走这一步
bool isLegal(int x, int y, int row, int col, unsigned char* p)
{
	if (x >= 0 && y >= 0)
		if (x < row && y < col)
			return (p[x * col + y] == road || p[x * col + y] == end);
	return false;
}
//输入迷宫图
//支持以矩阵形式输入,也可以输入一整行,自动处理换行符,直到读取到整个迷宫图为止
void inputMaze(unsigned char* p, int row, int col)
{
	unsigned char ch;
	printf("请输入迷宫图:\n");
	for (int i = 0; i < row * col; i++)
	{
		if ((ch = getchar()) != '\n')
			p[i] = ch;
		else
			--i;
	}

}
//打印迷宫图
void printMaze(unsigned char* p, int row, int col) {
	printf("\n迷宫图如下:\n");
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			printf("%c", p[i * col + j]);
		printf("\n");
	}

}
//走迷宫
//递归查询,这里由于递归是倒序输出路径,所以需要一个倒序操作
bool walkMaze(int row, int col, unsigned char* p, int x, int y)
{
	int pos = x * col + y;	//当前位置
	if (p[pos] == end)		//到达终点
		return true;
	if (isLegal(x - 1, y, row, col, p))	//上
	{
		//printMaze(p,row,col); //如果需要可以逐步输出迷宫图
		p[pos] = visited;	//设置访问标识,防止无限递归
		if (walkMaze(row, col, p, x - 1, y))	//该路径可行,输出操作符
		{
			inputPath(up);
			p[pos] = successPath;			//用于显示该路径
			return true;
		}
	}
	if (isLegal(x, y + 1, row, col, p))	//右
	{
		//printMaze(p,row,col);
		p[pos] = visited;
		if (walkMaze(row, col, p, x, y + 1))
		{
			inputPath(right);
			p[pos] = successPath;
			return  true;
		}
	}
	if (isLegal(x + 1, y, row, col, p))	//下
	{
		//printMaze(p,row,col);
		p[pos] = visited;
		if (walkMaze(row, col, p, x + 1, y))
		{
			inputPath(down);
			p[x * col + y] = successPath;
			return true;
		}
	}
	if (isLegal(x, y - 1, row, col, p))	//左
	{
		//printMaze(p,row,col);
		p[pos] = visited;
		if (walkMaze(row, col, p, x, y - 1))
		{
			inputPath(left);
			p[pos] = successPath;
			return  true;
		}
	}
	p[pos] = visited;
	return false;	//无路可走,该条路径不行
}

//自动寻找起点,可以自行选择是否调用
void findStart(unsigned char* p, int row, int col, int* x, int* y)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (p[i * col + j] == start)
			{
				*x = i;
				*y = j;
				return;
			}
		}
	}
}

int main()
{
	int row = 15, col = 15, x = 1, y = 1;	//行和列,起点坐标
	unsigned char* Maze = (unsigned char*)malloc(row * col);	//分配空间
	inputMaze(Maze, row, col);		//输入迷宫
	printMaze(Maze, row, col);		//打印迷宫
	walkMaze(row, col, Maze, x, y);		//走迷宫
	Maze[x * col + y] = start;		//矫正起点字符
	printMaze(Maze, row, col);		//打印迷宫
	printPath();					//打印路径
	free(Maze);						//释放空间
	system("pause");
	return 0;
}

或者手动走迷宫,得到最后的结果是 RRRDRRURRRRRRDDDDRDDD

32位小写md5加密即为flag

babypython

下载附件,是python字节码,有很多混淆的无用代码,尝试问chatgpt还原源码

下面是程序有效的代码思路

定义flag,并将flag的每个字符异或8

import timeit
flag = '************************************'
value = ''
output = ''
i = 0

while i < len(flag):
    temp = flag[i] ^ 8
    value += chr(ord(temp) ^ 8)
    i += 1

 将flag每个字符加3

for i in range(len(flag)):
    temp = flag[i]
    temp = chr(ord(temp) + 3)
    output += temp

将字符串进行base64加密,切片,即将加密后的base64密文反转倒序

import base64

output = base64.encode(output.encode())
obfuscated_output = output.decode()

obfuscated_output = obfuscated_output[:-1]

 将字符串中的g替换成1,H替换成3,W替换成9



obfuscated_output = obfuscated_output.replace('g', '1')
obfuscated_output = obfuscated_output.replace('H', '3')
obfuscated_output = obfuscated_output.replace('W', '9')
invalid_variable = len(obfuscated_output) * 5

# 第二个部分
print(obfuscated_output)

将txt文本末尾的加密变换后的字符串逆序,1替换为g,3替换为H,9替换为W,进行base64解密

得到解密后的字符串qglrv@onmlqpA>qmq>mBo3A?Bn<lppA@;lp4nx

写脚本解密,拿到flag:flag{5dcbafe63fbf3b7d8647c1aee650ae9c}

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
	int i;
	char str[]="qglrv@onmlqpA>qmq>mBo3A?Bn<lppA@;lp4nx";
	for(i=0;i<strlen(str);i++){
		str[i]-=3;
     	str[i]^=8;
	}
	printf("%s",str);
	return 0;
}

BadCoffee

下载附件,是js 文件,很多代码,好学长指导,知道是ob混淆

ob混淆:

开头定义了一个大数组,然后对这个大数组里的内容进行位移,再定义一个解密函数。后面大部分的值都调用了这个解密函数,以达到混淆的效果。

这种代码即为ob混淆,不仅变量名混淆了,运行逻辑等也高度混淆,难以理解

  1. 对象属性名称替换:混淆工具会将代码中的对象属性名称替换为无意义的名称。例如,将属性名从可读性高的名称(如 "name")替换为随机生成的字符串(如 "_0x1a2b3c")。这使得代码难以理解和分析。

  2. 属性访问转换:混淆工具可能会将直接的属性访问(例如 obj.property)转换为通过字符串进行间接访问的形式(例如 obj["property"])。这增加了代码的复杂性,使属性访问变得不直观。

  3. 属性重排序:混淆工具可能会对对象的属性进行重新排序,使属性的顺序变得混乱和不可预测。这增加了代码的困惑性,使属性的逻辑关系更加难以理解。

  4. 属性值加密:混淆工具可能会对对象的属性值进行加密或编码,以防止直接获取属性值。这可以使用各种加密算法或编码方案来实现。

  5. 对象引用混淆:混淆工具可能会修改对象的引用方式,使对象的引用变得复杂和不明显。例如,将对象的引用存储在数组、函数调用或其他对象中,增加代码的混乱性。

下面是一个示例代码:

var _0x1a2b = ['\x48\x65\x6C\x6C\x6F', '\x57\x6F\x72\x6C\x64', '\x63\x6F\x6E\x73\x6F\x6C\x65', '\x6C\x6F\x67'];//即大数组
//_0x1a2b 是一个包含随机字符串的数组,'\x48\x65\x6C\x6C\x6F' 对应替代属性名 'Hello'
var _0x3c4d = {};
_0x3c4d[_0x1a2b[0x0]] = 'Hello';//偏移
_0x3c4d[_0x1a2b[0x1]] = 'World';//:属性访问使用数组索引来间接访问属性,_0x3c4d[_0x1a2b[0x0]] 表示访问属性 'Hello
_0x3c4d[_0x1a2b[0x2]] = function (_0x24e2) {
    console[_0x1a2b[0x3]](_0x24e2);
};

_0x3c4d[_0x1a2b[0x2]](_0x3c4d[_0x1a2b[0x0]] + ' ' + _0x3c4d[_0x1a2b[0x1]]);//后面都调用解密函数

具体参考这篇文章:(124条消息) ob混淆解密在线工具_在线解ob混淆_滕青山ᅠ的博客-CSDN博客和这篇文章:(124条消息) 爬虫反混淆入门--JS混淆之ob混淆_阿J~的博客-CSDN博客

推荐一个在线工具解密ob混淆:解混淆测试版 (yuanrenxue.cn)   (这个在线工具使用火狐浏览器无法使用,可能是我的浏览器问题)

下面是优化后的代码:

function xxx(_0x53b7bb, _0x590286) {
  return _0x53b7bb ^ _0x590286;
}

function enc(_0x4bda4c) {
  var _0x8ff1dd = [],
      _0x6aca75 = [233, 129, 127, 238, 145, 144, 11, 43, 87, 134, 243, 158, 197, 216, 111, 136, 152, 29, 204, 31, 26, 228, 39, 148, 215, 220, 90, 76, 251, 57, 183, 184, 150, 157, 156, 176, 13, 41, 30, 86, 244, 8];

  for (let _0x7bc200 = 0; _0x7bc200 < 42; _0x7bc200++) {
    _0x8ff1dd[_0x7bc200] = xxx(_0x6aca75['at'](_0x7bc200), _0x4bda4c["charAt"](_0x7bc200)['charCodeAt']());
  }

  for (let _0x4f674a = 0; _0x4f674a < 42; _0x4f674a++) {
    _0x8ff1dd[_0x4f674a] = xxx(_0x8ff1dd['at'](_0x4f674a), _0x6aca75['at'](41 - _0x4f674a));
  }

  console["log"](_0x8ff1dd);
  return _0x8ff1dd;
}

function fff() {
  var _0xe4960c = "flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}",
      _0x55dae6 = enc(_0xe4960c),
      _0xbb5ecd = [135, 25, 72, 151, 195, 212, 228, 212, 250, 101, 39, 77, 163, 77, 70, 167, 119, 184, 7, 77, 144, 154, 93, 10, 185, 48, 179, 77, 71, 163, 67, 61, 113, 156, 196, 136, 239, 241, 128, 93, 84, 156];

  for (let _0x37df9d = 0; _0x37df9d < 42; _0x37df9d++) {
    if (_0x55dae6['at'](_0x37df9d) != _0xbb5ecd['at'](_0x37df9d)) {
      console["log"]("Error");
      return;
    }
  }

  console["log"]("YES");
  return;
}

fff();

也可以尝试自己修改变量名和函数名进一步优化 ,优化后稍微好看一点

function xor(a,b) {
  return a ^b;
}

function enc(flag) {
  var Str3 = [],
      Str2 = [233, 129, 127, 238, 145, 144, 11, 43, 87, 134, 243, 158, 197, 216, 111, 136, 152, 29, 204, 31, 26, 228, 39, 148, 215, 220, 90, 76, 251, 57, 183, 184, 150, 157, 156, 176, 13, 41, 30, 86, 244, 8];

  for (letj = 0;j < 42;j++) {
    Str3[_0x7bc200] = xor(Str2['at'](_0x7bc200), flag["charAt"](_0x7bc200)['charCodeAt']());
  }

  for (let k = 0; k < 42; k++) {
    Str3[k] = xor(Str3['at'](k), Str2['at'](41 - k));
  }

  console["log"](Str3);
  return Str3;
}

function fff() {
  varflag = "flag{xxxxxxxxxxxxxxxxxxxxxxxxxx}",
      result = enc(flag),
      Str = [135, 25, 72, 151, 195, 212, 228, 212, 250, 101, 39, 77, 163, 77, 70, 167, 119, 184, 7, 77, 144, 154, 93, 10, 185, 48, 179, 77, 71, 163, 67, 61, 113, 156, 196, 136, 239, 241, 128, 93, 84, 156];

  for (let i = 0; i < 42; i++) {
    if (result['at'](i) != Str['at'](i)) {
      console["log"]("Error");
      return;
    }
  }

  console["log"]("YES");
  return;
}

fff();

函数的大致思路是flag^str2^str2的反转字符串=str,写脚本解密:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
	
	char data[]={135, 25, 72, 151, 195, 212, 228, 212, 250, 101, 39, 77, 163, 77, 70, 167, 119, 184, 7, 77, 144, 154, 93, 10, 185, 48, 179, 77, 71, 163, 67, 61, 113, 156, 196, 136, 239, 241, 128, 93, 84, 156};
  char Buffer[]={233, 129, 127, 238, 145, 144, 11, 43, 87, 134, 243, 158, 197, 216, 111, 136, 152, 29, 204, 31, 26, 228, 39, 148, 215, 220, 90, 76, 251, 57, 183, 184, 150, 157, 156, 176, 13, 41, 30, 86, 244, 8};
   char flag[100];
int i;
for(i=0;i<42;i++){
	flag[i]=data[i]^Buffer[i]^Buffer[41-i];
	printf("%c",flag[i]);
}
	
	return 0;
}

未完待续...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/616563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Matter】Nordic Mattter(开发大纲)

nRF Connect SDK 支持Mattter Nordic提供的Matter用户指南 子页面&#xff1a; Matter概况开始使用Matter如何创建 Matter 最终产品 Matter网络拓扑结构 Thread&#xff1a;Thread是一种开放的低功耗无线通信协议&#xff0c;旨在为物联网设备提供安全、稳定、高效的IPv6连接。…

混合动力汽车耐久测试

一 背景 整车厂可通过发动机和电机驱动的结合为多款车型提供混合动力驱动技术。汽车集成电机驱动可大大减少二氧化碳的排放&#xff0c;不仅如此&#xff0c;全电动驱动或混合动力驱动的汽车还将使用户体验到更好的驾驶感受&#xff0c;且这种汽车可通过电动机来实现更快的加速…

机器学习 | 降维问题

目录 一、主成分分析 二、奇异值分解 2.1 奇异值分解原理 2.2 奇异值分解实践 三、特征值与特征向量 一、主成分分析 主成分有如下特征&#xff1a; 每个主成分是原变量的线性组合&#xff1b;各个主成分之间互不相关&#xff1b;主成分按照方差贡献率从大到小依次排列&…

【诗视野文学社】五一特刊|本期诗人:胭脂茉莉 李本 薛宏 文爱艺 唐根金 王宁 迪夫 东楠灵

【诗视野文学社】五一特刊 本期诗人&#xff1a;胭脂茉莉 李本 薛宏 文爱艺 唐根金 王宁 迪夫 东楠灵 脂茉莉简介&#xff1a;刘彦芹&#xff0c;女&#xff0c;作家、诗人&#xff0c;江苏人&#xff0c;年少习诗&#xff0c;评论及随笔见诸媒体及报刊&#xff0c;诗歌被选入海…

中国人民大学与加拿大女王大学金融硕士引领你走出职场困境,勇往直前!

走到一定职位时&#xff0c;想更进一步基本无望&#xff0c;到了自己事业的瓶颈期。从底层一路冲到中层靠的是能力&#xff0c;靠的是忠诚&#xff0c;靠的是勤奋&#xff0c;而再向上走&#xff0c;该凭借什么&#xff0c;完全找不到方向。而那些极个别的人却在自己看不到的地…

基于PySpark的10亿级数据集LAION-5B元数据快速处理实践(全文分享)

推荐语 多模态大模型训练如火如荼展开&#xff0c;但以LAION-5B为代表的大规模多模态数据集获取却成了一个令人头疼的问题。 OpenDataLab两位工程师在浦数 AI Talk做了非常实用的LAION-5B下载经验分享&#xff0c;我们整理了其演讲内容、Parquet文件、图片下载工具&#xff0…

Hive执行计划之一文读懂Hive执行计划

目录 文章目录 概述1.hive执行计划的查看2.学会查看Hive执行计划的基本信息3.执行计划步骤操作过程4.explain extended 概述 Hive的执行计划描述了一个hiveSQL语句的具体执行步骤&#xff0c;通过执行计划解读可以了解hiveSQL语句被解析器转换为相应程序语言的执行逻辑。通过…

软件测试人员迷茫之中如何找到职业发展的方向?

出现迷茫或焦虑的原因是什么&#xff1f; 也许每个人的原因不一样&#xff0c;但不外乎是下面这些原因叠加的结果。 1、敏捷和DevOps开发模式的推行&#xff0c;虽然20年的历史是否已经证明“敏捷已经失败了” 暂且不管&#xff0c;但敏捷/DevOps之风刮的还是很厉害&#xff0c…

每日一练 | 华为认证真题练习Day53

1、现在有以下10.24.0.0/24&#xff0c;10.24.1.0/24&#xff0c;10.24.2.0/24&#xff0c;10.24.3.0/24四个网段&#xff0c;这四个网段可以汇总为以下哪个网段&#xff1f;&#xff08;多选&#xff09; A. 10.24.0.0/23 B. 10.24.1.0/23 C. 10.24.0.0/22 D. 10.24.0.0/2…

Window环境rabbitmq安装教程

首先我们需要取官网下载对应的两个安装包 第一个是rabbitmq安装包路径在括号里&#xff08;Installing on Windows Manually — RabbitMQ&#xff09; 我们选择window下载即可。 下图是下载的样子&#xff0c;确认是这两个就没问题了 第二个是erlang&#xff08;http://erlang…

上海市计算机学会竞赛平台五月月赛题目汇总

我又来了&#xff01; 爆切了一大堆没用的水题后&#xff0c;我终于来发题解啦&#xff01;&#xff01;&#xff01; T1原题https://iai.sh.cn/problem/792 我们考虑通过计算最长上升连续自然数串&#xff08;是这么叫的吗&#xff09;来获取答案 可以开两个数组 和 来计…

从飞书妙记秒开率提升,看火山引擎A/B测试在研发场景的应用

作者&#xff1a;DataTester 用户体验是决定互联网产品能否长久生存的关键&#xff0c;每一个基于产品功能、使用和外观的微小体验&#xff0c;都将极大地影响用户留存和满意度。 对于企业协作平台飞书而言&#xff0c;用户体验旅程从打开产品页面的一瞬间就已开始&#xff0c;…

如何安装多个node版本(使用nvm)

1、卸载之前安装的所有node 2、下载nvm安装包&#xff0c;下载地址https://nvm.uihtm.com/ 3、安装nvm 4、打开cmd&#xff0c;运行命令 nvm install node版本号&#xff0c;安装对应版本的node 5、打开nvm的安装路径&#xff0c;可以看到安装的对应的node版本的文件夹 6、若有…

K8S之Deployment控制器管理应用(十一)

Deployment介绍 Deployment是最常用的K8s工作负载控制器&#xff08;Workload Controllers&#xff09;&#xff0c; 是K8s的一个抽象概念&#xff0c;用于更高级层次对象&#xff0c;部署和管理Pod。 Deployment的主要功能&#xff1a; • 管理Pod&#xff0c;即应用程序 •…

CS1237 数据实测

目录 硬件 测试数据 结论 性能 转换时间 硬件 外部电阻电位器 模拟 传感器信号 测试数据 一下记录数据为ADC原始数据未经过软件滤波 跳动幅度图片DEV_FREQUENCY_10DEV_PGA_1751DEV_FREQUENCY_40DEV_PGA_11562DEV_FREQUENCY_640DEV_PGA_18243DEV_FREQUENCY_640DEV_PGA_644…

Spring:什么是SpringBoot框架?①

前言&#xff1a; 我们说任何一个阶段的技术更迭都是在代码量&#xff0c;代码简洁度&#xff0c;封装后复杂关注度降低上下功夫&#xff0c;不断提升生产力。 Spring已经足够牛了&#xff0c;它的bean容器思想启迪和影响了众多的程序员&#xff0c;奠基引领了技术的发展。 在应…

人工智能直播的趋势分析报告

人工智能直播是指通过人工智能技术来模拟真人直播&#xff0c;通过机器学习和自然语言处理等技术实现。随着人工智能技术的不断发展&#xff0c;人工智能直播在近年来得到了广泛应用。 一、人工智能直播的优势 节省成本&#xff1a;相比传统直播&#xff0c;人工智能直播不需要…

校园垃圾回收处理APP

摘 要&#xff1a;本文开发的是校园垃圾分类回收APP。随着互联网的快速发展&#xff0c;现如今使用互联网对信息进行管理这一方法也被各行各业所使用&#xff0c;因为实现信息管理最好的方式就是建立良好的网络管理平台&#xff0c;并对其进行综合管理。与此同时&#xff0c;A…

C++模板类及其应用

C模板类及其应用 在本文中&#xff0c;我们将探讨C中的模板类及其应用。模板类是一种通用的编程技术&#xff0c;它允许您创建可重用的代码&#xff0c;同时保持类型安全和高性能。我们将通过以下几个方面来介绍模板类&#xff1a; 文章目录 C模板类及其应用什么是模板类&…

tomcat集群下的session共享和负载均衡(apache实现)

环境 操作系统&#xff1a;windows tomcat1&#xff1a;Apache Tomcat/7.0.52&#xff08;8085&#xff09; tomcat2&#xff1a;Apache Tomcat/7.0.52&#xff08;8086&#xff09; jdk&#xff1a;1.8.0_251 apache-http&#xff1a;httpd-2.2.17-win32-x86-no_ssl&#xff0…