1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > android arp 检测工具 android检测arp攻击

android arp 检测工具 android检测arp攻击

时间:2019-09-22 13:20:16

相关推荐

android arp 检测工具 android检测arp攻击

前段时间突然和别人讨论到arp检测这块的实现,心血来潮,将腾讯的wifi管家给反编译了一下,看了它如何实现arp检测,下面是分析的结果。

下面是wifi管家检测arp攻击的类,进入的时候会发送一个message,然后执行handleMessage函数

public void handleMessage(Message arg8) {

int v6 = 10001;

boolean v0 = true;

super.handleMessage(arg8);

switch(arg8.what) {

case 10001: {

goto label_7;

}

case 10002: {

goto label_42;

}

}

return;

label_7:

if((bth.a(this.eES)) && (bth.b(this.eES).refresh()) && (bap.a(bth.b(this.eES)))) {

bth.c(this.eES);

if(bth.d(this.eES) == 3) {

bth.e(this.eES);

bth.a(this.eES, 0);

}

bth.b(this.eES).Fu();

try {

v0 = bth.b(this.eES, 10001);

}

catch(Exception v1) {

}

}

if(bth.f(this.eES) == null) {

return;

}

if(!v0) {

return;

}

this.sendEmptyMessageDelayed(v6, bth.g(this.eES));

return;

label_42:

bth.a(this.eES, false);

bth.c(this.eES, 0);

int v2 = 0;

boolean v1_1 = true;

while(v2 != 2) {

try {

if((bth.b(this.eES).refresh()) && (bap.a(bth.b(this.eES)))) {

if(v2 == 0) {

bth.h(this.eES);

}

else {

bth.e(this.eES);

}

bth.b(this.eES).Fu();

v1_1 = bth.b(this.eES, 10002);

if(bth.i(this.eES) != 0) {

break;

}

SystemClock.sleep(700);

}

}

catch(Throwable v2_1) {

break;

}

++v2;

}

if(bth.f(this.eES) != null && (v1_1)) {

this.sendEmptyMessageDelayed(v6, bth.g(this.eES));

}

bth.a(this.eES, true);

}

刚开始执行的时候,runnable的run函数调用handler发送10002,所以label_42是检测的入口函数,bth.h是调用this.Fo函数,首先看一下this.Fo函数:

private void Fo() {

int v1 = this.eGX.Ft();

if(v1 != 0) {

int v0;

for(v0 = 0; v0 != 256; ++v0) {

String v2 = bao.kR(v1);

if(!v2.equals(this.eGX.eHl) && !v2.equals(this.eGX.eHj)) {

ban.io(v2);

}

v1 = bao.kS(v1);

}

}

}

public int Ft() {

int v0;

DhcpInfo v1 = this.eHC.getDhcpInfo();

if(v1 == null) {

v0 = 0;

}

else {

v0 = 16777215;

if(mask != 0) {

v0 = mask;

}

v0 &= v1.gateway;

}

return v0;

}

public static String kR(int arg2) {

return (arg2 & 255) + "." + (arg2 >> 8 & 255) + "." + (arg2 >> 16 & 255) + "." + (arg2 >> 24 & 255);

}

static {

ban.eHh = new byte[]{-126, 40, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 32, 67, 75, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 33, 0, 1};

}

public static void io(String arg6) {

try {

DatagramSocket v0_1 = new DatagramSocket();

DatagramPacket v1 = new DatagramPacket(ban.eHh, ban.eHh.length, InetAddress.getByName(arg6), 137);

v0_1.setSoTimeout(100);

v0_1.send(v1);

v0_1.close();

}

catch(Exception v0) {

}

}

public static int kS(int arg2) {

int v0 = (arg2 >> 24 & 255) + 1;

return v0 <= 255 ? v0 << 24 | 16777215 & arg2 : -1;

}

可以看到这个函数的作用是针对这个局域网的子网下除了当前连接wifi的网关以外的所有ip发送udp请求,以此来让arp文件里记录局域网子网下所有的ip和mac地址,bth.e也是发送udp,不过它只向网关ip发送

arp文件初始化之后,紧接着调用Fu()函数,如下:

public ArrayList Fu() {

BufferedReader v0_2;

BufferedReader v1 = null;

this.eHy.clear();

try {

v0_2 = new BufferedReader(new FileReader("/proc/net/arp"));

}

catch(Throwable v0) {

goto label_50;

}

catch(Exception v0_1) {

v0_2 = v1;

goto label_40;

}

try {

v0_2.readLine();

while(true) {

String v1_3 = v0_2.readLine();

if(v1_3 == null) {

break;

}

String[] v1_4 = v1_3.split("[ ]+");

if(v1_4.length < 6) {

continue;

}

String v2 = v1_4[0];

v1_3 = v1_4[3];

if(v2.equals(this.eHj)) {

this.eHk = v1_3;

}

if(v1_3.equals("00:00:00:00:00:00")) {

continue;

}

this.eHy.add(new String[]{v2, v1_3, ""});

}

}

catch(Exception v1_1) {

goto label_40;

}

catch(Throwable v1_2) {

goto label_58;

}

if(v0_2 == null) {

goto label_42;

}

try {

v0_2.close();

}

catch(IOException v0_3) {

}

...这段代码对this.eGX.eHy变量重新赋值,这个变量就是用来存放arp文件内容的,下面会用到这个变量,它的内容其实就是”/proc/net/arp”文件的内容

变量初始化完之后,这时候arp内容就可以进行分析了,然后执行bth.b函数,它调用了dY函数,如下:

private boolean dY(int arg11) {

Object v1_1;

Object v2;

boolean v8 = false;

if(!TextUtils.equals(this.eHc, this.eGX.BSSID)) {

this.Fn();

}

else {

int v7 = 0;

boolean v1 = true;

while(v7 != this.eGX.eHy.size()) {

CharSequence v4 = this.eGX.eHy.get(v7)[0];

Object v3 = this.eGX.eHy.get(v7)[1];

if(!TextUtils.equals(v4, this.eGX.eHj)) {

this.eGZ.put(v3, v4);

}

else {

Object v0 = this.eGY.get(v4);

if(TextUtils.isEmpty(((CharSequence)v0))) {

this.eGY.put(v4, v3);

}

else {

if(v3 != null && (TextUtils.equals(((CharSequence)v0), ((CharSequence)v3)))) {

goto label_29;

}

if(TextUtils.equals(((CharSequence)v3), this.eGX.eHk)) {

v2 = this.eGY.get(v4);

}

else {

String v2_1 = ((String)v3);

}

v0 = this.eGZ.get(v3);

if(v0 == null || (((String)v0).equals(v4))) {

this.nx();

String v1_2 = this.ah(((String)v2), ((String)v4));

}

else {

v1_1 = v0;

}

this.kP(arg11);

if(this.eHb != null) {

this.eHb.a(((String)v1_1), ((String)v2), this.im(((String)v1_1)), arg11, this.eGU, this.c(this.eGX.eHj, this.eGX.eHk, ((String)v1_1), ((String)v2)));

}

this.reset();

v1 = false;

}

}

label_29:

++v7;

}

v8 = v1;

}

return v8;

}

上面的v7是this.eGX.eHy的元素下标,目的是为了遍历this.eGX.eHy,所以这边是对arp文件内容进行分析的函数,首先对this.eGX.eHy进行解释,这个变量是一个ArrayList,上面提到的Fu()函数初始化了这个变量,它将arp文件里的每行记录变成this.eGX.eHy的一条记录,下面是执行查看arp的结果,可以看到每行的数据包含六个元素,第一个是Ip,第四个是mac address

然后再解释一下this.eGX.BSSID和this.eGX.eHj怎么来的,下面是它的初始化函数

public boolean refresh() {

int v7 = 34;

boolean v0 = false;

try {

WifiInfo v2 = this.eHC.getConnectionInfo();

DhcpInfo v3 = this.eHC.getDhcpInfo();

if(!this.eHC.isWifiEnabled()) {

return v0;

}

if(!this.Fs()) {

return v0;

}

if(v2 != null && v3 != null && v2.getSupplicantState() == PLETED) {

this.SSID = v2.getSSID();

int v4 = v2.getIpAddress();

if(this.SSID.charAt(0) == v7 && this.SSID.charAt(this.SSID.length() - 1) == v7) {

this.SSID = this.SSID.substring(1, this.SSID.length() - 1);

}

if(!this.Fs()) {

return v0;

}

if(TextUtils.isEmpty(this.SSID)) {

return v0;

}

if("".equalsIgnoreCase(this.SSID)) {

return v0;

}

if(v4 == 0) {

return v0;

}

this.BSSID = v2.getBSSID();

this.eHj = bao.kR(v3.gateway);

...通过上面可以看到this.eGX.BSSID其实就是当前连接的wifi的bssid,this.eGX.eHj其实就是网关ip

最后来看一下怎样检测arp攻击,this.eGZ是一个HashMap,key是mac地址,value是ip,下面是找出现在的arp文件里网关Ip对应的mac是否和之前的不一样的arp记录

if(!TextUtils.equals(v4, this.eGX.eHj)) {

this.eGZ.put(v3, v4);

}

else {

Object v0 = this.eGY.get(v4);

if(TextUtils.isEmpty(((CharSequence)v0))) {

this.eGY.put(v4, v3);

}

this.eGY也是一个HashMap,key是ip,value是mac,下面的代码是找出网关ip对应的多个mac地址情况,如果发现网关ip对应的mac和之前的不一样,那么说明遇到arp攻击,就需要发送攻击者相关信息给服务器,注意的是this.eGY在开始检测前会先将arp里面的网关ip和mac地址放进去,然后刷新arp,所以才会出现同一个网关ip对应多个Mac情况

else {

if(v3 != null && (TextUtils.equals(((CharSequence)v0), ((CharSequence)v3)))) {

goto label_29;

}

if(TextUtils.equals(((CharSequence)v3), this.eGX.eHk)) {

v2 = this.eGY.get(v4);

}

else {

String v2_1 = ((String)v3);

}

v0 = this.eGZ.get(v3);

if(v0 == null || (((String)v0).equals(v4))) {

this.nx();

String v1_2 = this.ah(((String)v2), ((String)v4));

}

else {

v1_1 = v0;

}

this.kP(arg11);

if(this.eHb != null) {

this.eHb.a(((String)v1_1), ((String)v2), this.im(((String)v1_1)), arg11, this.eGU, this.c(this.eGX.eHj, this.eGX.eHk, ((String)v1_1), ((String)v2)));

}

this.reset();

v1 = false;

}private String ah(String arg6, String arg7) {

int v1;

for(v1 = 0; v1 != this.eGX.eHy.size(); ++v1) {

String v3 = this.eGX.eHy.get(v1)[0];

if((this.eGX.eHy.get(v1)[1].equals(arg6)) && !v3.equals(arg7)) {

String v0 = v3;

return v0;

}

}

return "0.0.0.0";

}

现在真相大白了,主要检测方法:

1. arp攻击就是发送arp广播让局域网内的所有设备将网关ip对应的mac地址改成攻击者的mac地址,这样的话被攻击者的网关ip是对的,但是mac地址变了,因此只要找出来当前网络的网关mac地址对应的所有Ip,里面肯定包括了真正的网关ip和攻击者的网关ip,另外根据上面的代码还会出现同一个网关ip对应多个Mac的情况,这种事因为检测开始前先将arp里面的网关ip和mac地址放进去,然后检测开始时会刷新arp文件,如果受到攻击,此刻的网关ip对应的mac可能会和之前的不一样

2. 扫描局域网内子网下的所有ip,然后获取arp文件内容,生成一个三维数组,第一个元素是ip,第二个是mac地址,最后一个不用管

3. 将上面获取到的三维数组进行遍历,找出网关ip对应是否多个mac地址

4. 如果发现网关ip对应至少两个mac地址,那么不等于网关Ip的那个mac地址就是攻击者的mac地址,然后再找出这个mac对应的不等于网关ip的那个ip就是攻击者的真实ip

5. 可能大家也会遇到一个疑惑,上面的检测是基于刷新后的arp里面的网关对应的mac是正确的基础上的,那如何保证网关mac此刻是正确的呢,抓包看了一下,wfi管家并没有加快wifi网关mac的更新,测了一下,我的手机上是30秒左右更新一次网关mac,所以初步怀疑只有在刚好更新mac的这段时间内wifi管家才能检测出问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。