0x00 背景
因为公司的一个手机app的开发需求,要尝试链接手机开启的web服务。于是在Android Studio的Android模拟器上尝试连接,发现谷歌给模拟器做了网络限制,不能直接连接。当然这个限制似乎从很久以前就存在了。一直没有注意到。
0x01 Android 网络地址空间
模拟器的每个实例都在虚拟路由器或防火墙服务后面运行,这样便将其与开发机器网络接口和设置以及互联网隔离开来。所以
- 无法直接从PC访问到模拟器;
- 也无法从模拟器直接访问开发机器PC;
- 也无法直接从这个模拟器访问到另一个模拟器;
每个实例的虚拟路由器管理 10.0.2/24 网络地址空间。路由器管理的所有地址都采用 10.0.2.xx 形式,其中 xx 是一个数字。此空间内的地址由该模拟器或其路由器预先分配,具体说明如下:
网络地址 | 说明 |
---|---|
10.0.2.1 | 路由器或网关地址 |
10.0.2.2 | 主机环回接口的特殊别名(开发机器上的 127.0.0.1) |
10.0.2.3 | 第一个 DNS 服务器 |
10.0.2.4 / 10.0.2.5 / 10.0.2.6 | 可选的第二个、第三个和第四个 DNS 服务器 |
10.0.2.15 | 所模拟设备的网络或以太网接口 |
127.0.0.1 | 所模拟设备的环回接口 |
如果要实现从这个模拟器访问到另一个模拟器的场景,可以参考官网的说明–互连模拟器实例【传送门】。这里大概说明下原理:就是先让模拟器A和模拟器B都分别连到开发主机,用开发主机做中转。
这里有个重点:
在Android模拟器上访问10.0.2.2
地址就可以访问到开发主机的localhost了。
0x02 模拟器端口映射到本地(开发机)
端口映射有两种方法:
- 通过模拟器控制台设置重定向
- Android 调试桥 (adb) 工具
2.1 通过模拟器控制台设置重定向
第一步, 通过命令行连接到模拟器控制台,启动的第一个模拟器实例的控制台端口号为 5554。
第二步, 登录授权,输入 auth <auth_token>
命令。
<auth_token>
已经在上面命令的倒数第二行提供路径,我这里是:
/Users/用户名/.emulator_console_auth_token
打开文件可以看到一行token,复制过来,带入到命令中执行即可:
auth rsEGo86el0Kwomvp
成功授权后返回OK
第三步,端口映射
执行如下命令,将Android模拟器的6000端口映射到开发主机的5000端口,这样开发主机即可访问到模拟器开的6000端口服务了。
redir add tcp:5000:6000
使用 redir 命令来处理重定向。
如需添加重定向,请使用以下命令:
redir add <protocol>:<host-port>:<guest-port>
其中,<protocol>
是 tcp 或 udp,<host-port>
和 <guest-port>
用来设置自己的PC机器与Android 模拟器的系统之间的映射。
第四步,删除端口映射
redir del
: 删除一条转发规则,命令格式如下:
redir <protocol>:<hostport>
举例:
redir del tcp:5000
第五步,退出控制台,使用quit
或者exit
命令
2.2 通过 adb 设置重定向
Android 调试桥 (adb) 工具提供端口转发功能,这是设置网络重定向的另一种方法。官方说明【传送门】
可以使用 forward 命令设置任意端口转发,将特定主机端口上的请求转发到设备上的其他端口。以下示例设置了主机端口 6100 到Android 模拟器端口 7100 的转发:
adb forward tcp:6100 tcp:7100
以下示例设置了主机端口 6100 到 local:logd 的转发:
adb forward tcp:6100 local:logd
请注意,除了停止 adb 服务器,adb 目前不提供移除重定向的方法。
上面这句话是官网抄来的,半天没有理解说的是什么。懂了似乎又没懂。懂了的可以跳过本段。这里翻译下:端口映射的规则一旦使用,没办法像删除路由那样删除映射规则。唯一的办法就是关掉adb服务。
停止 adb 服务器
如需停止 adb 服务器,请使用 adb kill-server
命令。然后,您可以通过发出其他任何 adb 命令来重启服务器。
0x03 模拟器访问本地(开发机)
如开篇所讲,本地PC的地址会被映射成10.0.2.2
,用localhost或者127.0.0.1是访问不到的。在模拟器的浏览器访问试试。
0x04 tips
- 想要进一步了解Andrioid 控制台操作命令的同学可以移步到官网【传送门】;
10.0.2.2
这个本地ip映射的机制至少在Android emulator2.0版本就存在了,大约是2009年,可能在1.0版本就在了。没错,很早就这样了。10.0.2.2
曾经有一个从浏览器就能开起反弹shell的漏洞(CVE-2010-1807),有趣的是这本来是苹果safari的任意代码执行漏洞,在安卓也能用,配合这个ip:10.0.2.2
就能从开发主机访问到模拟器的shell了。【传送门】
0x05 参考文献
https://developer.android.com/studio/run/emulator-networking?hl=zh-cn
https://m.imooc.com/wiki/androidstudio-emulatorconsole
https://developer.aliyun.com/article/270580
https://blog.csdn.net/learner_lps/article/details/52451464