1. 前言

好久没写文章了,工作比较忙,不过我还是对技术比较热爱,即使它不能给我带来利益,保持初心。

工作期间遇到一个问题,连接vpn的软件是校验机器硬件码,不是公司电脑不让使用vpn软件,上下班已经让我搞得筋疲力尽了,我不想每天背个电脑回家,这还怎么让我在家愉快的加班?

2. 分析

首先,我能想到硬件码当然是mac地址,为了验证我自己的想法,我需要将mac地址设置成与公司电脑mac地址相同的地址。

这里windows 上有简单的修改mac地址的方法,通过修改注册表,简单来说就是给注册表增加选项,让网络地址可以配置。

正常无线网卡是没有 “网络地址” 这个配置项的,是通过注册表增加实现的这个配置项。

不过这里有限制,就是mac 地址的第二位必须为固定的一些值,这是受到系统的限制,看网上说xp系统是没有限制的,不过我不可能去换xp系统的。

无奈,我需要快速验证到底是不是根据mac地址生成的硬件码,因为如果不是 mac地址生成的硬件码,我后续的工作无法进行下去。

这里采用简单粗暴的方法,直接使用虚拟机

然后装上对应的vpn 软件,功夫不负有心人,果然是mac地址生成的硬件码。

3. 大胆猜测

知道了修改mac地址就可以实现伪装硬件码后,后面的思路就是如何 让软件读取到假的mac地址,我猜测 vpn 软件是通过windows 的api 来读取 mac 地址的,简单的百度一下发现 GetAdaptersInfo这个函数,其在 Iphlpapi.dll

简单用frida 验证一下 vpn 软件是否调度到了 GetAdaptersInfo 这个函数:

frida-trace -i "GetAdaptersInfo" "软件完整地址"

输出:

GetAdaptersInfo: Loaded handler at "C:\\Users\\pc\\Desktop\\__handlers__\\IPHLPAPI.DLL\\GetAdaptersInfo.js"
Started tracing 1 function. Press Ctrl+C to stop.
/* TID 0x3cf8 */
2948 ms 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0f4ee254 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee264 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee274 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee284 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee294 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2a4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2b4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2c4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2e4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee2f4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee304 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee314 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee324 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee334 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0f4ee344 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2948 ms GetAdaptersInfo()

可以看到软件确实调用到了 GetAdaptersInfo 这个函数。

这里要注意一个问题,启动cmd时要用 管理员权限 启动,否者hook不到。

4. 分析GetAdaptersInfo函数

DWOED GetAdaptersInfo(

PIP_ADAPTER_INFO pAdapterInfo;

PULONG pOutBufLen;

);

函数有俩个参数,第一个参数是 PIP_ADAPTER_INFO 类型的指针,最终结果也存储在 第一个参数里面。

第二个参数是一个长度,是一个整数型指针。

返回值也是一个整数表示是否获取成功。

简单一个程序,获取mac及网络地址的代码:

#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
// 初始化winsock
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen);
DWORD dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
// 第一次调用GetAdapterInfo获取ulOutBufLen大小
if (dwRetVal == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
}
if (dwRetVal == NO_ERROR)
{
pAdapter = pAdapterInfo;
while (pAdapter)
{
printf("Adapter Name: \t%s\n", pAdapter->AdapterName);
printf("Adapter Desc: \t%s\n", pAdapter->Description);
printf("MAC Addr: \t%02x-%02x-%02x-%02x-%02x-%02x\n",
pAdapter->Address[0],
pAdapter->Address[1],
pAdapter->Address[2],
pAdapter->Address[3],
pAdapter->Address[4],
pAdapter->Address[5]);
printf("IP Address: \t%s\n", pAdapter->IpAddressList.IpAddress.String);
printf("IP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
printf("Gateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
pAdapter = pAdapter->Next;
}// end while
}
else
{
printf("Call to GetAdaptersInfo failed.\n");
}
if (pAdapterInfo != NULL)
{
free(pAdapterInfo); //释放资源
}
return 0;
} //end main

简单调试一下这个程序:

可以看到 第一个参数 是一个结构体,有点像 链表的数据结构,每次使用 Next 来调度到下一块内存,存储的也是下一块网卡信息(包括虚拟网卡)。而我们需要的Mac 地址就存放在 Address 这个字段中。

因为 frida 脚本我还不知道如果调度结构体,所以这里通过偏移值来修改的(如果有方法,还请评论区大佬教我)。

这里需要注意调试时是x86来调试,因为vpn软件是32位的。

算一下mac(Address) 地址针对 pAdapterInfo 偏移值:

>>> 0x0087f19c-0x0087f008
404
>>>

next 针对 pAdapterInfo 偏移值:

>>> 0x0087f288-0x0087f008
640
>>>

5. 编写 frida 脚本

这里有一个难点,如何在函数结束的时候 改变其内存值,hook脚本 onLeave中的参数是返回值,而不是函数的参数,这里可以在 onEnter 对第一个参数this绑定,这样 onLeave 时就可以调到这个指针了

var writeFile = Module.getExportByName(null, "GetAdaptersInfo");

Interceptor.attach(writeFile, {
onEnter: function(args)
{
this.data = args[0] //动态绑定第一个参数到 this,为了在函数返回是修改
},
onLeave:function(ret){
// 1280
// 640
console.log(Memory.readByteArray(ptr(this.data.add(404)), 6)) //输出第一块网卡mac地址
console.log(Memory.readByteArray(ptr(this.data.add(1044)), 6)) // +640结构体偏移,获得下一块网卡mac地址
Memory.writeByteArray(ptr(this.data.add(1684)),[0x01,0x02,0x03,0x04,0x05,0x06]) // 写入第三块网卡mac地址
}
});

启动命令(cmd管理员权限):

frida "软件路径" -l C:\Users\pc\Desktop\hooking.js --no-pause

6. 后记

通过这个案例解决了我实际的问题,这个东西前前后后弄了一周 (工作时间除外),从刚开始有这个想法,到一步一步分析验证。东西做出来后也有很大的成就感。针对逆向这方面我是个小白,很多东西都是现查的。

有一些感想:保持清晰思路,大胆猜想,小心验证,保证你逻辑每一步都正确,最后的结果肯定是符合预期的,这就叫合理吧。

记一次hook mac地址实现伪装硬件码的更多相关文章

  1. 网络基本概念备忘:MAC地址,端口,HTTP状态码

    MAC地址 英文MAC Address 英文全称: Media Access Control Address 别称:硬件位址 用途:定义网络设备位置 表示:十六进制数,6 Byte 特点:产品出产后M ...

  2. 突破路由mac地址过滤思路

    一.获取合法的mac地址 在拿到无线网络的密码时,主要思路就是,用类似airodump-ng这类监听软件(WildPackets OmniPeek,Kismet),获得合法客户端的mac地址,然后再更 ...

  3. MAC 地址为什么不需要全球唯一

    MAC 地址(Media access control address)是分配给网络接口控制器(Network interface controller, NIC)的唯一标识符,它会在网络段中充当网络 ...

  4. 伪装MAC地址

    一.界面操作法 打开"网上邻居",右键属性"本地连接",点击配置 选择"高级",再选"网路卡位址"(不同系统名字略不同) ...

  5. 利用tcp三次握手,使用awl伪装MAC地址进行多线程SYN洪水攻击

    SYN洪水攻击概述:SYN洪水攻击主要源于: tcp协议的三次握手机制tcp协议面向链接的协议SYN洪水攻击的过程:在服务端返回一个确认的SYN-ACK包的时候有个潜在的弊端,如果发起的客户是一个不存 ...

  6. [记]WIndow/Linux 获取本机(全部)IPv4、IPv6、MAC地址方法 (C/C++)

    Linux 获取本机IP.MAC地址用法大全 //#include <sys/types.h> #include <ifaddrs.h> #include <sys/io ...

  7. Windows Mac地址伪装步骤

    本文介绍Windows上Mac地址修改方法,适用于网络环境绑定了Mac地址需要修改上网的情况. 工具/原料 PC电脑一台 Windows系统 方法/步骤 点击右下角图标. 点击打开网络和共享中心. 点 ...

  8. 记一次排查局网内的ARP包 “不存在的” MAC 地址及 “不存在的”IP 所发的ARP包

    xu言: 最近生了一场病,虽然不是给自己找理由不写.不过果不其然还是没有坚持每天发一篇啊.不过,有时间我还是会把一些有意思的事情记录下来.以作备忘吧.这人老了记性就不好了.哈哈哈,当然,也侧面说明了. ...

  9. 记MAC地址、磁盘序列号的获取

    import java.io.*; import java.net.Inet4Address; import java.net.InetAddress; import java.net.Network ...

  10. 手机电脑Mac地址修改方法

    1.什么是Mac地址? MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址.硬件地址,用来定义网络设备的位置.在O ...

随机推荐

  1. [Python]-opencv-python模块(cv2)-图片读取和格式转换

    python常常用opencv模块来处理图像. import cv2 as cv 读取图片:imread() 默认按照彩色三通道读取: img = cv2.imread(path) 读取灰度图: im ...

  2. 四、frp内网穿透服务端frps.ini各配置参数详解

    [必须]标识头[common]是不可或缺的部分 [必须]服务器IPbind_addr = 0.0.0.00.0.0.0为服务器全局所有IP可用,假如你的服务器有多个IP则可以这样做,或者填写为指定其中 ...

  3. 在 K8S 上部署以 mysql 数据库作为后端存储的单机版 nacos

    Nacos 被用于: 服务发现 微服务配置信息管理 部署 nacos 时,需要用到如下两个镜像,这两个镜像均来自于 nacos 官方发布到 docker hub 的镜像, nacos/nacos-se ...

  4. 编码中的Adapter,不仅是一种设计模式,更是一种架构理念与解决方案

    大家好,又见面了. 不知道下面这玩意大家有没有见过或者使用过?这是一个插座转换器.我们都知道日常使用的是220v的交流电,而国外不同国家使用的电流电压是不一样的(比如日本使用的是110v).且插座的接 ...

  5. 前端三件套 HTML+CSS+JS基础知识内容笔记

    HTML基础 目录 HTML基础 HTML5标签 doctype 标签 html标签 head标签 meta标签 title标签 body标签 文本和超链接标签 标题标签 段落标签 换行标签 水平标签 ...

  6. Docker容器获取宿主机信息

    最近在做产品授权的东西,开始宿主机为Window,程序获取机器硬件信息相对简单些,后来部署时发现各种各样的的环境问题,所有后来改用dokcer部署,docker方式获取宿主机信息时花了些时间,特此记录 ...

  7. CentOS 7.9 安装 MySQL 5.7.35

    CentOS 7.9 安装 MySQL 5.7.35 1 下载地址:https://downloads.mysql.com/archives/community/ 2 mysql5.7.35 安装包上 ...

  8. vue2双向绑定原理:深入响应式原理defineProperty、watcher、get、set

    响应式是什么?Vue 最独特的特性之一- 就是我们在页面开发时,修改data值的时候,数据.视图页面需要变化的地方变化. 主要使用到哪些方法? 用 Object.defineProperty给watc ...

  9. 常用cmd及bat脚本命令

    1.内部命令和外部命令 cmd 命令 :内部命令和外部命令 内部命令 系统自带命令 dir copy 外部命令 调用应用程序,可自由拓展 mstsc.exe(mstsc)远程连接 ping (ping ...

  10. 使用idea操作git(ssh协议)

    问题 我们发现,使用IDEA上的git功能,当使用ssh协议出现了可以commit但无法push和pull的问题,经过测试发现原因是Could not read from remsitory.直接翻译 ...