【发布时间】:2021-11-23 07:43:03
【问题描述】:
我一直在寻找一种方法来处理我的MAC 地址并对其进行修改,我偶然发现了以下可用的 ANSI-C 代码 sn-p,但我不确定如何操作。在sn-p里面,我为我想问的问题加了分。
/*
* Spoof a MAC address with LD_PRELOAD
*
* If environment variable $MAC_ADDRESS is set in the form "01:02:03:04:05:06"
* then use that value, otherwise use the hardcoded 'mac_address' in this file.
*
* Bugs: This currently spoofs MAC addresses for *all* interfaces.
* It would be better to watch calls to socket() for the interfaces
* you want and then only spoof ioctl calls to that file descriptor.
*/
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#define SIOCGIFHWADDR 0x8927
static unsigned char mac_address[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
int
ioctl(int d, int request, unsigned char *argp)
{
static void *handle = NULL;
static int (*orig_ioctl)(int, int, char*);
int ret;
char *p;
// If this var isn't set, use the hardcoded address above
p=getenv("MAC_ADDRESS");
if (handle == NULL) {
char *error;
handle = dlopen("/lib/libc.so.6", RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(EXIT_FAILURE);
}
orig_ioctl = dlsym(handle, "ioctl");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
}
ret = orig_ioctl(d, request, argp);
if (request == SIOCGIFHWADDR) {
unsigned char *ptr = argp + 18; // [1] what is the +18 purpose?
int i;
for (i=0; i < 6; i++) {
if (!p) {
ptr[i] = mac_address[i];
continue;
}
int val = 0;
if (p[0]>='0' && p[0]<='9') val |= (p[0]-'0')<<4;
else if (p[0]>='a' && p[0]<='f') val |= (p[0]-'a'+10)<<4;
else if (p[0]>='A' && p[0]<='F') val |= (p[0]-'A'+10)<<4;
else break;
if (p[1]>='0' && p[1]<='9') val |= p[1]-'0';
else if (p[1]>='a' && p[1]<='f') val |= p[1]-'a'+10;
else if (p[1]>='A' && p[1]<='F') val |= p[1]-'A'+10;
else break;
if (p[2]!=':' && p[2]!='\0') break;
ptr[i] = val;
p+=3;
}
}
return ret;
}
那么,我的第一个问题[1]:
在声明unsigned char *ptr = argp + 18; 中,“添加”的目的是什么?我们如何得出这个数字?例如,在查看strace ifconfig 之后,我可以看到使用以下参数调用 ioctl:
ioctl(5, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr={sa_family=ARPHRD_ETHER, sa_data=00:15:5d:2f:7f:86}}) = 0
其中5 是文件描述符,SIOCGIFHWADDR 是对应于获取/设置硬件地址的标志,其余的是argp。但是,我们如何准确地迭代这个struct 的数据?
在获取.so 文件并执行以下操作后,可以测试代码的功能,例如:
export LD_PRELOAD="./hostid-spoof.so" # the compiled lib
export MAC_ADDRESS="11:22:33:44:55:66"
ifconfig
那么网络接口的mac地址确实改变了。但这具体是如何生效的呢?
【问题讨论】:
-
什么是hostID?
-
@ZsigmondLőrinczy 其硬件地址 (MAC)。