· 为什么要伪造IP?· 伪造IP能干吗?· 如何伪造?
上面这三个问题希望能帮你在这篇文章中找到答案。先来说如何伪造。
伪造IP的思路是通过修改 Header 来实现增加 XFF 字段
XFF字段在我之前的推送中有介绍过具体是什么含义跟作用,那些伪造IP的软件都是什么原理但是在那篇推送中没有公开源码,其实也是出于安全考虑。说到这里就要来回答伪造IP能干嘛的问题了。
伪造IP的作用只局限于想象力,简单的,能刷刷投票,复杂的话,包括黑服务器,绕过IP限制抓取后端数据,或者模拟测试看服务端承压能力如何,都是可以的。至于商业作用?伪造IP也能做到大部分人想到的歪心思。伪造IP在Android移动端上分两种情况,下面分别介绍。
修改自己的app IP的地址
如果你想修改自己的app的IP地址的话方法很简单,结合上面说过的 XFF 字段,你只需要在每个 HTTP 请求头上加上 X-Forwarded-For 字段就行。
如果你想修改的是其他app的IP地址…请往下看。
修改第三方 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); } }); }}
欢迎入群讨论技术问题