👁‍🗨EgressIpQuery - 主机出口IP查询工具

可在攻击前或配置全局代理后使用该工具检测出口IP,避免在攻击中因代理未生效而被溯源的问题。

Github:https://github.com/sma11new/EgressIpQuery

🔨工具介绍

🍜工具特点

  • 图形化方便操作和展示
  • 支持自定义查询接口、代理
  • 同时查询出口IP归属
  • 没有第三方依赖

🍝java版本

项目使用jdk8编写

🍻使用说明

直接查询,使用的工具自带接口

image

也可以自定义查询接口,当主动修改接口后,会在同目录下生成EIQconfig.list接口配置文件,恢复默认接口后,会自动删除该配置文件。

⭕遗留问题

配置代理后,再次点开配置界面,代理类型会重置为socks,如果是http则需要再次选择。

🐎代码分析

工具实现非常简单,我甚至能想到用Python怎样在不到100行写出一个又健壮又好用的同样功能的工具,不过这是第一个较为完整的Java工具项目,功能简单,主要用于熟悉Java项目流程,收获不小。

🏭项目结构

开始使用maven管理项目,但是配置和打包重复出现问题,而且功能较简单,索性不用了,下个项目再好好研究

image_2022-05-18_00-18-00

弃用maven后结构如下:

  • query包下放功能逻辑相关代码
  • ui包下放界面展示相关代码
  • utils包下放工具类

image-20220518000356290

关键查询类Query如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package query;

import utils.HttpUtil;
import utils.RegUtil;

public class Query {
/**
* 查询出口IP
*
* @param interUrl 查询接口地址
* @return ip
*/
public static String doQueryIp(String interUrl) {
String egressIp = null;
String reqResult = HttpUtil.doGet(interUrl, Proxy.getProxy.schame(), Proxy.getProxy.ip(), Proxy.getProxy.port());
if (reqResult != null) {
egressIp = RegUtil.findIp(reqResult);
}
return egressIp;
}

/**
* 查询归属
*
* @param ip 待查询ip
* @return addr
*/
public static String doQueryAddr(String ip) {
String addr = null;
String url = "http://whois.pconline.com.cn/ipJson.jsp?ip=" + ip + "&json=true";
String reqResult = HttpUtil.doGet(url, null, null, 0);
if (reqResult != null) {
addr = RegUtil.findAddr(reqResult);
}
return addr;
}
}

doQueryIp方法调用HttpUtil工具类中的doGet方法发起get请求,再对结果做正则匹配,获取出口IP

doQueryAddr方法同样调用HttpUtil工具类中的doGet方法发起get请求,对结果匹配归属地址,获取归属

💫自定义接口Dialog

巧妙地设计

起初打算整个工具是不带任何配置文件和生成文件的,但是发现使用中要想自定义接口就必须生成配置文件,因此用了这个巧妙的设计:

初始工具不带配置文件,自定义接口后,如果接口与默认接口不相同,则创建一个配置文件写入修改后的接口,当接口与默认接口相同时又会删除配置文件,而且窗口加入了恢复默认按钮,方便。因此查询逻辑是系统调用查询接口时会先优先判断是否存在配置文件,存在表示配置文件已经修改,则读取文件中的接口,不存在就是系统默认接口。

纯纯的《花里胡哨》

相关代码:

使用静态代码块初始化,来实现初始化接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 初始化接口列表
static {
try {
File interFile = new File(interConFile);
// 存在自定义接口配置文件,表示用户修改并自定义接口,则加载dialog时读取文件中的接口
// 否则读取默认接口
if (interFile.exists()) {
interList = FileUtil.readFile(interConFile);
} else {
interList = defaultInter;
}
} catch (Exception e) {
e.printStackTrace();
}
}

query.Inter#setInterList set时判断是否相同,并执行下一步操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* set接口,并判断是否与默认接口相同,相同删除配置文件,不同写入配置文件
* 接收String
*
* @param interList 接口List
*/
public static void setInterList(String interList) {
Inter.interList = TypeTransUtil.stringToList(interList);

if (!Inter.interList.equals(Inter.defaultInter)) {
FileUtil.writeFile(interList, interConFile);
} else {
FileUtil.deleteFile(interConFile);
}
}

合法输入校验

正则校验输入的接口是否是合法url,同样在配置代理中也校验IP端口是否合法。

image-20220518001338519

去重

对接口去重处理。