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