简单逆向18

news/2024/10/17 18:25:16/

诺莫18

原题:在这里插入图片描述

开始:

放入IDA:

int __usercall wmain@<eax>(int a1@<ebx>)
{FILE *v1; // eaxFILE *v2; // eaxchar v4; // [esp+3h] [ebp-405h]char v5; // [esp+4h] [ebp-404h]char v6; // [esp+5h] [ebp-403h]char v7; // [esp+104h] [ebp-304h]char v8; // [esp+105h] [ebp-303h]char v9; // [esp+204h] [ebp-204h]char v10; // [esp+205h] [ebp-203h]char v11; // [esp+304h] [ebp-104h]char v12; // [esp+305h] [ebp-103h]printf("Come one! Crack Me~~~\n");v11 = 0;memset(&v12, 0, 0xFFu);v9 = 0;memset(&v10, 0, 0xFFu);while ( 1 ){do{do{printf("user(6-16 letters or numbers):");scanf("%s", &v11);v1 = (FILE *)sub_4024BE();fflush(v1);}while ( !sub_401000(&v11) );printf("password(6-16 letters or numbers):");scanf("%s", &v9);v2 = (FILE *)sub_4024BE();fflush(v2);}while ( !sub_401000(&v9) );sub_401090(&v11);v7 = 0;memset(&v8, 0, 0xFFu);v5 = 0;memset(&v6, 0, 0xFFu);v4 = ((int (__cdecl *)(char *, char *))loc_4011A0)(&v7, &v5);if ( sub_401830(a1, (int)&v11, &v9) ){if ( v4 )break;}printf(&v5);}printf(&v7);return 0;
}

sub_401000()判断输入字符长度为6-16,并且为字母或者字符

sub_401090(&v11)没有对v11进行操作,不影响密码和流程,跳过

v4 = ((int (__cdecl *)(char *, char *))loc_4011A0)(&v7, &v5);

看后面printf(&v5);
v5的数据没有,使用动态调试:
在这里插入图片描述
在这里插入图片描述
一个跳出这个循环就对了,那就要
sub_401830(a1, (int)&v11, &v9)
v4均满足if,v4是由两个已知量输入的,所以我们不用管

sub_401830(a1, (int)&v11, &v9):

bool __usercall sub_401830@<al>(int ebx0@<ebx>, int user, const char *pow)
{int v4; // [esp+18h] [ebp-22Ch]signed int v5; // [esp+1Ch] [ebp-228h]signed int v6; // [esp+28h] [ebp-21Ch]unsigned int v7; // [esp+30h] [ebp-214h]char v8; // [esp+36h] [ebp-20Eh]char v9; // [esp+37h] [ebp-20Dh]char v10; // [esp+38h] [ebp-20Ch]unsigned __int8 v11; // [esp+39h] [ebp-20Bh]unsigned __int8 v12; // [esp+3Ah] [ebp-20Ah]char v13; // [esp+3Bh] [ebp-209h]int v14; // [esp+3Ch] [ebp-208h]char v15; // [esp+40h] [ebp-204h]char v16; // [esp+41h] [ebp-203h]char v17; // [esp+140h] [ebp-104h]char v18; // [esp+141h] [ebp-103h]v5 = 0;v6 = 0;v12 = 0;v11 = 0;v17 = 0;memset(&v18, 0, 0xFFu);v15 = 0;memset(&v16, 0, 0xFFu);v10 = 0;v7 = 0;v4 = 0;while ( v7 < strlen(pow) ){if ( isdigit(pow[v7]) ){v9 = pow[v7] - 48;}else if ( isxdigit(pow[v7]) ){if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )pow[v7] = 34;v9 = (pow[v7] | 0x20) - 87;}else{v9 = ((pow[v7] | 0x20) - 97) % 6 + 10;    // 将a,b,c...转换为16进制对应的10进制数值}v10 = v9 + 16 * v10;if ( !((signed int)(v7 + 1) % 2) ){*(&v15 + v4++) = v10;ebx0 = v4;v10 = 0;}++v7;}while ( v6 < 8 ){v11 += byte_416050[++v12];v13 = byte_416050[v12];v8 = byte_416050[v11];byte_416050[v11] = v13;byte_416050[v12] = v8;if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 )v13 = v11 + v12;*(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF ){v11 = -83;v12 = 43;}sub_401710((int)&v17, (const char *)user, v6++);v5 = v6;if ( v6 >= (unsigned int)(&v15 + strlen(&v15) + 1 - &v16) )v5 = 0;}v14 = 0;sub_401470(ebx0, &v17, &v14);return v14 == 43924;
}

分析:

将输入字符串进行操作后与byte_416050[(unsigned __int8)(v8 + v13)]数据亦或再放入sub_401470(ebx0, &v17, &v14);。这是关键流程,倒着看,要让v14 == 43924,进入sub_401470(ebx0, &v17, &v14):

_DWORD *__usercall sub_401470@<eax>(int a1@<ebx>, _BYTE *a2, _DWORD *a3)
{int v3; // ST28_4int v4; // ecx_DWORD *_EAX; // eaxint v6; // edxint v8; // ST20_4int v9; // eaxint v10; // ediint v11; // ST1C_4int v12; // edxchar v13; // diint v14; // ST18_4int v15; // eaxint v16; // ST14_4int v17; // edxchar v18; // alint v19; // ST10_4int v20; // ecxchar _AL; // alint v23; // ST0C_4int v24; // eax_DWORD *result; // eaxint v26; // edxif ( *a2 == 'd' ){*a3 |= 4u;v4 = *a3;}else{*a3 ^= 3u;}v3 = *a3;if ( a2[1] == 'b' ){_EAX = a3;*a3 |= 0x14u;v6 = *a3;}else{*a3 &= 0x61u;_EAX = (_DWORD *)*a3;}__asm { aam }if ( a2[2] == 'a' ){*a3 |= 0x84u;v9 = *a3;}else{*a3 &= 0xAu;}v8 = *a3;v10 = ~(a1 >> -91);if ( a2[3] == 'p' ){*a3 |= 0x114u;v12 = *a3;}else{*a3 >>= 7;}v11 = *a3;v13 = v10 - 1;if ( a2[4] == 'p' ){*a3 |= 0x380u;v15 = *a3;}else{*a3 *= 2;}v14 = *a3;if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 ){if ( a2[5] == 102 ){*a3 |= 0x2DCu;v17 = *a3;}else{*a3 |= 0x21u;}v16 = *a3;}if ( a2[5] == 's' ){*a3 |= 0xA04u;v18 = (char)a3;v20 = *a3;}else{v18 = (char)a3;*a3 ^= 0x1ADu;}v19 = *a3;_AL = v18 - v13;__asm { daa }if ( a2[6] == 'e' ){*a3 |= 0x2310u;v24 = *a3;}else{*a3 |= 0x4Au;}v23 = *a3;if ( a2[7] == 'c' ){result = a3;*a3 |= 0x8A10u;v26 = *a3;}else{*a3 &= 0x3A3u;result = (_DWORD *)*a3;}return result;
}

加入每一个if都成立,验证a3的值是不是43924

a3 = 0
a3 |= 0x4
a3 |= 0x14
a3 |= 0x84
a3 |= 0x114
a3 |= 0x380
#a3 |= 0x2DCu  反调试的不要
a3 |= 0xA04
a3 |= 0x2310
a3 |= 0x8A10print(a3) #43924 #dbappsec

输出结果就是43924
所以v17的值是’dbappsec’
现在研究前面的算法:

while ( v7 < strlen(pow) ){if ( isdigit(pow[v7]) ){v9 = pow[v7] - 48;}else if ( isxdigit(pow[v7]) ){if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )pow[v7] = 34;v9 = (pow[v7] | 0x20) - 87;}else{v9 = ((pow[v7] | 0x20) - 97) % 6 + 10;    // 将a,b,c...转换为16进制对应的10进制数值}v10 = v9 + 16 * v10;if ( !((signed int)(v7 + 1) % 2) ){*(&v15 + v4++) = v10;ebx0 = v4;v10 = 0;}++v7;}

如果是字符是数字,就转成相应的值,如果是字母,就转成相应的16进制,如:a转成10,b转成11(第二个if不需要管,单个字符字符不肯能识别为16进制)

然后两个两个组合看成16进制,转化为10进制寸到v15。

简而言之就是把一个字符串两个两个看成一个16进制,转换为10进制存到数组中

byte_416050我们也需要动态调试(再IDA找到偏移地址):
在这里插入图片描述
查找ecx值,8次
[0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd]

逆向:

import hashlib
a3 = 0
a3 |= 0x4
a3 |= 0x14
a3 |= 0x84
a3 |= 0x114
a3 |= 0x380
#a3 |= 0x2DCu  反调试的不要
a3 |= 0xA04
a3 |= 0x2310
a3 |= 0x8A10print(a3) #43924 #dbappsecx = [0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd]
y = ['d','b','a','p','p','s','e','c']
m = ""for i in range(len(y)):m += hex(ord(y[i])^x[i])m = m.replace("0x","")n = hashlib.md5()
n.update(m.encode("utf-8"))print(n.hexdigest())

根据题目要求,要进行md5加密

套上flag
flag{d2be2981b84f2a905669995873d6a36c}


http://www.ppmy.cn/news/285040.html

相关文章

汇编语言-课程设计2

;OVERVIEW DOG.exe 中 装载了程序 installer1, installer2, installer3, booter, newint, mainsub, set_ui, wait_choice, f1, f2, f3, f4, f5, show_str; mainsub 拥有五个功能函数 f1~f5, 两个子函数 set_ui & wait_choice, 一个通用的 show_str; installer1 将 boote…

【学习笔记】Flutter重要知识点

学习资料 4月28日-5月11日 按照这个视频边学习边敲代码 视频学习 争取两个星期把flutter和dart搞定&#xff01;&#xff01;&#xff01;&#xff01; 5月12日半夜更新学习日志 基本内容学的超不多了&#xff0c;感觉声明式编程真的好爱~~Android原生好久没搞了。接下来练几…

细说SSRF

目录 什么是SSRF形成原因容易出现SSRF的地方SSRF的危害脑图函数file_get_contents()fsockopen()curl_exec() 协议 漏洞检测常用绕过方式限制为http://www.xxx.com 域名时&#xff08;利用&#xff09;限制请求IP不为内网地址限制请求只为http协议利用[::]利用句号利用特殊地址利…

面试准备知识

信息收集 假如给你一个网站你怎么去渗透 步骤 首先看是什么类型的网站&#xff0c;大型网站可以去天眼查等查询法人股份等信息&#xff0c;小型网站可以查询使用了哪类建站系统。 whois信息查询 获取注册者邮箱姓名电话等 查询服务器旁站及子域名站点&#xff0c;因为主站一…

细说——SSRF

目录 什么是SSRF形成原因容易出现SSRF的地方SSRF的危害脑图SSRF相关函数和协议函数file_get_contents()fsockopen()curl_exec() 协议 漏洞检测常用绕过方式限制为http://www.xxx.com 域名时&#xff08;利用&#xff09;限制请求IP不为内网地址限制请求只为http协议利用[::]利用…

变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计

1.概述 本次建设内容包括&#xff1a;危险废物处理中心、有机废弃物处理中心、配套建设园区污水处理厂和园区管理中心等&#xff0c;该建设内容包括了安庆市静脉产业园项目红线范围内得所有固体废弃物处理子项目&#xff0c;以及园区红线范围内、外为园区配套的市政设施。全厂共…

变电站综合自动化系统如何提高综合性自动化功能?

安科瑞变电站综合自动化系统在安庆市静脉产业园应用 安科瑞 崔远航摘 要 变电站综合自动化系统是将变电站内的二次设备经过功能的组合和优化设计&#xff0c;利用计算机技术、通信技术、信号处理技术&#xff0c;实现对全变电站的主要设备和输、配电线路的自动监视、测量、控…

安科瑞变电站综合自动化系统 在安庆市静脉产业园应用

1.概述 静脉产业&#xff0c;这一概念最早由日本学者提出&#xff0c;专家们形象地将废弃物转换为再生资源的行业称为“静脉产业”——因其变废为宝&#xff0c;循环利用&#xff0c;如同将含有较多二氧化碳的血液送回心脏的静脉。安庆市静脉产业园是为创建安庆市经济健康持续 …