· 为什么要伪造IP? · 伪造IP能干吗? · 如何伪造?
上面这三个问题希望能帮你在这篇文章中找到答案。先来说如何伪造。
伪造IP的思路是通过修改 Header 来实现增加 XFF 字段
XFF字段在我之前的推送中有介绍过具体是什么含义跟作用, 那些伪造IP的软件都是什么原理 但是在那篇推送中没有公开源码,其实也是出于安全考虑。说到这里就要来回答伪造IP能干嘛的问题了。
伪造IP的作用只局限于想象力,简单的,能刷刷投票, 复杂的话,包括黑服务器,绕过IP限制抓取后端数据,或者模拟测试看服务端承压能力如何,都是可以的。 至于商业作用?伪造IP也能做到大部分人想到的歪心思。 伪造IP在Android移动端上分两种情况,下面分别介绍。
如果你想修改自己的app的IP地址的话方法很简单, 结合上面说过的 XFF 字段,你只需要在每个 HTTP 请求头上加上 X-Forwarded-For 字段就行。
如果你想修改的是其他app的IP地址…请往下看。
下面说的方法是用来修改那些我们动不了的HTTP请求逻辑的。 有人说只要是JAVA代码,就算被封装起来也可以用反射来Hook呀!
是的没错,但是如果要修改的是任意一个装在你手机上的app的IP地址, 比如把某个视频app的IP改到境外,看一些在境内看不到的视频内容,嗯哼。
在正式开始侵入之前你需要了解 Xposed 框架。如果没了解过的话可以看我这个推送 教你三分钟写个Xposed模块
我们的原理也是把HTTP请求加上XFF字段,方法就是把目标app的所有HTTP请求都截下来,然后动手脚。
HttpUrlConnection->connect() HttpUrlConnection->getInputStream()
上面这两个方法是所有HTTP请求的必经之路,但是有个问题需要注意,就是必须要在 connect() 发生之前去修改 Header,在 connect() 之后是修改不了的。所以要实现的方法是 beforeHookedMethod() 方法。 下面是hook connect()方法的代码,
XposedHelpers.findAndHookMethod("com.android.okhttp.internal.huc.HttpURLConnectionImpl", lpparam.classLoader, "connect", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
HttpURLConnection urlConn = (HttpURLConnection) param.thisObject;
XposedBridge.log("[beforeHookedMethod] connect url: " + urlConn.getURL());
if (urlConn != null) {
try {
urlConn.addRequestProperty("X-Forwarded-For", info.getIp());
} catch (IllegalStateException exp) {
XposedBridge.log("[beforeHookedMethod] handleHttpHook, exp: " + exp.getMessage());
}
}
super.beforeHookedMethod(param);
}
});
可以看到这里注入的对象是 HttpURLConnectionImpl,方法是 connect()。这里有个细节问题,各个厂商的FW可能有不同,在适配不同厂商的时候这里 hook的对象可能不太一样,需要看实际情况修改。 hook完 conect(),下面要hook getInputStream(),基本套路一样
XposedHelpers.findAndHookMethod("com.android.okhttp.internal.huc.HttpURLConnectionImpl", lpparam.classLoader, "getInputStream", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
HttpURLConnection urlConn = (HttpURLConnection) param.thisObject;
XposedBridge.log("[beforeHookedMethod] getInputStream url: " + urlConn.getURL());
if (urlConn != null) {
try {
urlConn.setRequestProperty("X-Forwarded-For", info.getIp());
} catch (IllegalStateException exp) {
XposedBridge.log("[afterHookedMethod] getInputStream, exp: " + exp.getMessage());
}
}
super.beforeHookedMethod(param);
}
});
如果成功的注入上这两段代码而且在运行时没有崩溃的话,那么恭喜你,你可以用Fiddler或者Charles之列的工具抓包看Header是否已经带上这个字段。
感谢看到这里的朋友,关于 Xposed 的完整代码附在下面,在注入上面两个方法之前还需要判断一下目标 app 是不是你想要的,否则 Xposed会 hook 掉所有的请求,这会导致一些不可控的问题。
public class MainHook implements IXposedHookLoadPackage{
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
XposedBridge.log("[handleLoadPackage] " + lpparam.packageName);
if(!lpparam.packageName.equals("Your Package Name")) {
return;
}
XposedBridge.log("[packageHoooked] " + lpparam.packageName);
handleHttpConnectHook(lpparam, info);
handleInputStreamHook(lpparam, info);
}
private void handleHttpConnectHook(XC_LoadPackage.LoadPackageParam lpparam, final DeviceInfo info) {
XposedBridge.log("[methodhook] handleHttpHook()");
XposedHelpers.findAndHookMethod("com.android.okhttp.internal.huc.HttpURLConnectionImpl", lpparam.classLoader, "connect", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
HttpURLConnection urlConn = (HttpURLConnection) param.thisObject;
XposedBridge.log("[beforeHookedMethod] connect url: " + urlConn.getURL());
if (urlConn != null) {
try {
urlConn.addRequestProperty("X-Forwarded-For", info.getIp());
urlConn.setRequestProperty("User-Agent", Const.HEADER_UA);
} catch (IllegalStateException exp) {
XposedBridge.log("[beforeHookedMethod] handleHttpHook, exp: " + exp.getMessage());
}
}
super.beforeHookedMethod(param);
}
});
}
private void handleInputStreamHook(XC_LoadPackage.LoadPackageParam lpparam, final DeviceInfo info) {
XposedHelpers.findAndHookMethod("com.android.okhttp.internal.huc.HttpURLConnectionImpl", lpparam.classLoader, "getInputStream", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
HttpURLConnection urlConn = (HttpURLConnection) param.thisObject;
XposedBridge.log("[beforeHookedMethod] getInputStream url: " + urlConn.getURL());
if (urlConn != null) {
try {
urlConn.setRequestProperty("X-Forwarded-For", info.getIp());
} catch (IllegalStateException exp) {
XposedBridge.log("[afterHookedMethod] getInputStream, exp: " + exp.getMessage());
}
}
super.beforeHookedMethod(param);
}
});
}
}