Cheate MAC address
Table of Contents
背景
由于一些原因,很多软件会绑定网卡MAC地址,这样就导致换了网卡之后,软件就无法使用了。
一般的解决方案是通过命令修改MAC地址,但是这样不够优雅,并且还有导致mac地址重复的风险。
使用命令修改IP地址
ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
使用HOOK来完成mac地址欺骗
找出受害者获取MAC地址的方法
受害人信息 1
OS | Ubuntu 16.04 xenial |
网卡 | a8:83:3b:53:eb:35 |
找出受害人获取mac地址的方法
用strace抓一下log
strace ./lmhostid
execve("./lmhostid", ["./lmhostid"], [/* 30 vars */]) = 0
brk(NULL) = 0x828000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=138880, ...}) = 0
mmap(NULL, 138880, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f75775c6000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000b\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=144976, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f75775
# 省略......
close(3) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
openat(AT_FDCWD, "/proc/net/dev", O_RDONLY) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(4, "Inter-| Receive "..., 1024) = 718
read(4, "", 1024) = 0
close(4) = 0
stat("/sys/devices/virtual/net/eno1", 0x7ffd14cf1d40) = -1 ENOENT (No such file or directory)
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
ioctl(4, SIOCGIFHWADDR, {ifr_name="eno1", ifr_hwaddr=a8:83:3b:53:eb:35}) = 0
close(4) = 0
stat("/sys/devices/virtual/net/virbr0", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/sys/devices/virtual/net/lo", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
ioctl(3, SIOCGIFHWADDR, {ifr_name="eno1", ifr_hwaddr=a8:83:3b:53:eb:35}) = 0
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4
ioctl(4, SIOCGIFHWADDR, {ifr_name="eno1", ifr_hwaddr=a8:83:3b:53:eb:35}) = 0
close(4) = 0
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond0"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond1"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond2"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond3"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond4"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond5"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond6"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond7"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond8"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="bond9"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic0"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic1"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic2"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic3"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic4"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic5"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic6"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic7"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic8"}) = -1 ENODEV (No such device)
ioctl(3, SIOCGIFHWADDR, {ifr_name="vmnic9"}) = -1 ENODEV (No such device)
close(3) = 0
write(1, "The FlexNet host ID of this mach"..., 54The FlexNet host ID of this machine is "a8833b53eb35"
) = 54
exit_group(0) = ?
+++ exited with 0 +++
从上面的log可以很容易的看出,应用使用SIOCGIFHWADDR的ioctl来获取MAC地址,所以只要hook这个函数就可以完成我们想要的功能。
使用LD_PRELOAD来完成hook
- 代码
/*
* ifhwaddr hook - a hook SIOCGIFHWADDR ioctl to give a fake MAC address for apps
* LD_PRELOAD="hook.so" command
*
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#ifndef RTLD_NEXT
#define RTLD_NEXT ((void *) -1l)
#endif
#define REAL_LIBC RTLD_NEXT
int ioctl (int __fd, unsigned long int __request, ...) {
static int (*func_ioctl) (int, unsigned long int, void *) = NULL;
va_list args;
void *argp;
int retval;
if (! func_ioctl) {
func_ioctl = (int (*) (int, unsigned long int, void *)) dlsym (REAL_LIBC, "ioctl");
}
va_start (args, __request);
argp = va_arg (args, void *);
va_end (args);
struct ifreq *ifr = argp;
retval = func_ioctl (__fd, __request, argp);
if (SIOCGIFHWADDR == __request && retval == 0) {
unsigned char* mac=(unsigned char*)ifr->ifr_hwaddr.sa_data;
// set to b3:26:83:2c:73:ec
mac[0] = 0xb3;
mac[1] = 0x26;
mac[2] = 0x83;
mac[3] = 0x2c;
mac[4] = 0x73;
mac[5] = 0xec;
}
return retval;
}
编译:
gcc -shared -o hook.so hook.c
测试:
hook前:
./lmhostid
lmhostid - Copyright (c) 1989-2017 Flexera Software LLC. All Rights Reserved.
The FlexNet host ID of this machine is "a8833b53eb35"
hook后
LD_PRELOAD=./hook.so ./lmhostid
lmhostid - Copyright (c) 1989-2017 Flexera Software LLC. All Rights Reserved.
The FlexNet host ID of this machine is "b326832c73ec"
Footnotes:
1
本文中的MAC address都是随机数