# Android 動態系統進度
## 專案
**目前實驗室的gitlab是壞掉的,所以搬到github去**:
https://github.com/24135768b/androiddynamic-new_tauto
**以下是實驗室的gitlab**:
可以去開一條branch紀錄版本
wireguard
http://10.100.0.41/jimmy2559/mynewdivabeta
http://10.100.0.41/jerry30109/androiddynamic
Docker
http://10.100.0.41/jerry30109/androiddynamic_docker
openVPN (可是這個網址不能git clone跟git push 一定要用wireguard的VPN QAQ)把10.100.0.41改成192.168.50的網址就可以clone
http://192.168.50.77/jimmy2559/mynewdivabeta
http://192.168.50.77/jerry30109/androiddynamic
Docker
http://192.168.50.77/jerry30109/androiddynamic_docker
##
用openvpn連
Docker版本的動態系統(沒意外應該是可以跑)
http://192.168.50.53:8080
ubuntu 有個管理介面可以用:
http://192.168.50.53:9090
username: islab
password: 4296842968
可以vscode連,或是直接用這條指令連上去
ssh islab@192.168.50.53 -p 22
## Root與脫殼的邂逅
* 酷酷的黑科技
* GetVersion.py
```python=
from google_play_scraper import app
o = open("version.txt",'w',encoding='utf8')
dat
with open("applist.txt",'r') as f:
for line in f.readlines():
line = line[:-1]
try:
result = app(
line,
lang='tw',
country='tw'
)
except:
o.write("can't find " + line + '\n')
continue
try :
o.write(result['version'] + '\n')
except:
o.write("Error with: " + line + '\n')
```
## 單一入口
## Docker
http://192.168.50.77/jerry30109/androiddynamic_docker
* 這個gitlab裡面有docker的東東
* docker.patch中有說要包成docker要改那些東西
* 目前動態系統已經包好了(包括依庭做的更動),目前是放在我的電腦的虛擬機上面
* http://192.168.50.111:8080/upload
### How?
* docker-compose跟Dockerfile都已經寫好了
* 基本上不太需要去動他
* 感謝hallowworld大神(曾經的美好已經不在了QAQ)
* 基本上動態系統要上Docker會遇到的問題最主要是路徑
* 原本是使用相對路徑
* 但Docker本身的執行方式跟開發環境所使用的不一樣,Docker是從根目錄下去跑
* 開發環境則是在webapp.py的目錄
* python的open函數
* python所import的東西
*
* GitLab上面有docker.patch,基本上就是把動態系統從開發環境Docker化的方式
## 週報
https://docs.google.com/presentation/d/13y4i8pwtYKtlJW80mZ6GDlS_b_0O7F3bArLwfUMbft4/edit#slide=id.g18f414ccf99_0_18
## 檢測項目表格
https://docs.google.com/spreadsheets/d/166V5TKD7yCdHPjON55Ng3HjR2IRVo58P/edit#gid=1925924796
https://docs.google.com/spreadsheets/d/1Z5ymKW9BoWiD2JTKweyUQTE8Ovuqmpv5/edit?usp=sharing&ouid=103455109837616910330&rtpof=true&sd=true (new)
MSTG
https://github.com/OWASP/owasp-mastg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md
https://mas.owasp.org/MASTG/Android/0x05h-Testing-Platform-Interaction/
安卓系統對應工業局檢測(不要給別人看到:)
https://docs.google.com/spreadsheets/d/1mtVirScVWhc7F7x3ugpIl3Ro0p6H8bkI/edit#gid=1088740012
https://docs.google.com/spreadsheets/d/1ET40bkDQeY2v87J3RJ_8QEczVVreAAwG/edit?usp=sharing&ouid=103455109837616910330&rtpof=true&sd=true (new)
以上檢測向的名稱不夠清楚,要改成這個[表格](https://docs.google.com/spreadsheets/d/1W4-raUwT9LH7Sw5XP81M6KNA1_1VtSQe/edit?gid=188972761#gid=188972761)的名稱
## 遠端

192.168.50.198
islab/4296842968
https://192.168.50.82:8006 (網頁PVE)
root/4296842968
## 工業局的標準
* 工業局的APP檢測項目們(V3.2)
https://www.mas.org.tw/storage/files/3/original/39116225623d725978054.pdf
https://www.mas.org.tw/spaw2/uploads/images/AppV/20201201/AppV3.2.pdf
## Diva 進度整理
[survey] virtual app
學長已完成: 1 5 6 14 16 18 21 26 28 29
目前似乎已完成: 22 23 20 19 4 9 10 8 17 2
待做: 7(webview) 11(https) 12(crypto) 13(webview) 15(被拔掉了) 24(url)
**first of all 該如何下手**
在`DynamicDetectionRule.py`有寫好的要hook的function,所以寫diva的時候要用到這邊寫好的manager,也可以參考寫好的function們去實作功能,如果用到config.txt沒有寫好的function,就要記得回去加上去。
* (22 23) WriteReadClipboardActivity [完成待加強]
* 前端寫好了,會有一個copyfield跟pastefield
* 可以連結到android的clipboardManager (Landroid/content/ClipboardManager;)
* 情境:會複製資訊至剪貼簿中,並可以自由貼上
* 檢測:確認複製時不會複製到敏感資訊,貼上的剪貼簿中沒有儲存敏感資訊
* **學長建議:可以更加動態(?)**
* 在web 上可以顯示出警告訊息
* 補齊中文log
* `DynamicDetectionRule.py`
* `DyamicWriter.py`
* (20) SendSMSActivity [完成]
* 前端寫好了,能輸入手機號碼與簡訊內容
* 後端就是一個簡單的傳送簡訊功能(android.telephony.SmsManager)
* 情境:
* 有Call到sendTextMessage,sendDataMessage,sendMultipartTextMessage就視為危險行為。
* (19) TelecommunicationActivity [進行中]
* 好像`DynamicDetectionRule.py`中間的註解部分有點錯誤,我要直接改掉囉ouo
* 這個好多權限問題QQ
* 因為android 升級,在android 10以上的版本,這些module有受到影響:
* Build
* getSerial()
* TelephonyManager
* *getImei()*
* *getDeviceId()*
* *getSubscriberId()*
* getMeid()
* getSimSerialNumber()
* 所以有一些權限要特別去拿才有辦法QQ
* Third-party apps installed from the Google Play Store cannot declare privileged permissions
* 但我們不是透過google play安裝的軟體,應該是要拿得到權限?
* 他好麻煩真的是哭了
* (4)CheckKeyStoreNullPwdHardcorePwdActivity[已拔掉]
* (9,10) CheckBase64StringActivity[完成]
* 前後端功能寫好了,基本上就是一個簡單的Session產生器,使用Base64做Encode和Decode
* 動態系統:
* 可以透過Frida hook Base64的encodeToString Function但CmdServer和網站沒辦法hook,所以報表顯示不出來。
* 修改生code.js的那個python將function實例化就能hook到ㄌ
* 原本寫LogFile.txt的東東有點問題,後來查了一下是base64 encode完後會有多一個換行符號,DynamicWriter錯誤,目前暫時改了Inject Project裡面的code無視換行暫時解決(?)
* 不出意外的又有大麻煩ㄌ
* 問題已解決
* 8. GetAndroidIDWithSecureStringActivity[完成]
* 我把java的部分完成了
* 前端也好了
* 完成ouo/
* 17. FileDeleteActivity[完成]
* 7. WebviewAllowFileAccessActivity[進行中]
* 寫一個web使其能夠提取app內的資料(/data/data/com.example.mynewdivabeta)
* 2. runtime exec[完成]
* 12. CheckSecurityMethodAndCipherActivity
* cipher type
* key supported: 21
AES only supports key sizes of 16, 24 or 32 bytes...
* https://www.cnblogs.com/lsdb/p/9324372.html
* https://bigzuo.github.io/2019/03/27/java-cipher-tutorial/
*
* digest type
* https://dotblogs.com.tw/chhuang/2011/01/19/20883
* https://blog.csdn.net/ma1kong/article/details/2662997
* signature
* algo name https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature
* 另一種方法去做signature
https://gist.github.com/nakov/b01f9434df3350bc9b1cbf9b04ddb605
* https://gustavopeiretti.com/rsa-keys-java/
* mac type
* https://matthung0807.blogspot.com/2019/12/java-javaxcryptomac-hmacsha256-encrypt.html
* SSLCertificateInformation
* 原本的功能是把ssl的資訊印出來,但以mas的標準要去看加密法以及簽署ssl的人是否正常
* 基本上是利用SSLlab的API去做檢測,照這個方法會只能檢測有外網的Server,但基本上app都是使用外網,所以應該沒差?(大概)
* 利用python本身的檢測會比較難模擬出各種TLS版本或不同系統的連線模式
* 目前可以偵測憑證本身能不能被信任(簽發機構)、憑證是否過期、憑證本身的加密法是否安全(基本上工業局想看到的就這些)
## json格式問題
https://hackmd.io/@otiskan/BkcSdM-Jj
總共要做兩種格式
* 項目總表[完成]
* 學長已經有在`DynamicDetectionRule.py`已經有整理self.rule出來,所以這部分應該可以快一點
* 檢測到的報告[好惹]
* 目前的進度是把每個檢測項目的discription跟detail加上去了,json的部分可能要晚點
* 目前的問題:
* DynamicDetectionRule.py跟DynamicWriter.py太多無用的code
* 之後可能會需要大改
* 我們要改的部分,學長說我們可以依照自己喜歡的設計去寫
* 在DynamicDetectionRule裡面,有很多def function是檢測項目,當有call到這個檢測的function的時候再把東西寫進dict裡面,如果有重複的(已經存在的dict的key)可以skip或覆寫,然後再用dump把dict轉成json輸出
* 在webapp裡面有一個class叫Result,主要負責處理報表的部分,網頁上的呈現可能要從這邊改去連產pdf系統
* 可以把export_pdf註解掉,然後寫一個其他的function,在最下面routes那邊改endpoint就好了
* 因為是動靜態結合,所以可以去靜態系統拿資料(ex webapp的APKinfo)
* json[mast_report][data][discription]是描述問題
* json[mast_report][data][details]是描述hook到的function
* 最新標準依照網頁上面那個EXCEL進行
## TODO
* 檢測項目太老舊了,要更新
* [新檢測項可以從這邊下手](https://mas.owasp.org/MASTG/Android/0x05h-Testing-Platform-Interaction/)
* 動態系統的DB
* 應該跟靜態一樣使用mongo db就好
* 可以把已產出的報告寫進去db中
* 新增網頁路徑:可供使用者查詢歷史的報告
* 動態系統瘦身秀
* 現在裡面太多不必要的東西使Docker會相當的肥
## 遇到的問題
| 問題 | 解法 |
| --- | --- |
| show result沒辦法點 | 點了start之後就應該會把disabled關掉 |
|按start不會有其他反應: WebSocket is already in CLOSING or CLOSED state.| `pip install websockets` |
|Failed to spawn: unable to access zygote64 while preparing for app launch; try disabling Magisk Hide in case it is active 或者是pid 796被占用 也是同樣的問題| `adb shell "su -c magiskhide disable"` |
|Unable to load SELinux policy from the kernel: Failed to open file ?/sys/fs/selinux/policy?: Permission denied|`adb shell "su -c setenforce 0"`|
|Unable to save SELinux policy to the kernel|`su`|
|frida.NotSupportedError: need Gadget to attach on jailed Android;|adb shell上面跑的frida server跳掉了|
|docker status unhealthy | 沒關係 |
|Unable to start: Could not listen on address 127.0.0.1, port 27042: Error binding to address 127.0.0.1:27042: Address already in use| 一開始`adb forward --remove tcp:27042` 但失敗,後來`netstat -tunlp` 找到frida server的pid `kill -9 pid` 之後再重新執行frida server即可|
|Auto 功能客製化(針對特定Activity) | 通靈中 |
|Cookie好像有問題 | 通靈2.0 |
|MobSF: none |GlobalSetting.py 的UPLOAD_APK_DIR |
|Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.example.mynewdivabeta signatures do not match the previously installed version; ignoring!]|應該是裝置上面已經有一個有簽章版本的apk所以要解除安裝`adb uninstall com.example.mynewdivabeta.apk`|
|android ID hook 不到,不知道是不是config.txt的問題| 不是config的問題,是code.js在JavaScriptGenerator.py裡面有一個if要特別去看this跟this.$new() 然後才會可以hook到|
|{"type":"error","description":"Error: invalid address","stack":"Error: invalid address\n at Object.value [as patchCode] (frida/runtime/core.js:203:1)\n|SElinux把frida server擋掉了,所以打`setenforce 0`可以SElinux關掉|
|adbd cannot run as root in production builds|把magisk hide關掉 然後重新開機|
| base [adb] unable | 跑sudo ./probe.sh
## Server
* 預計要建立一個Server去讓app去通信(登入之類的功能)
* Server需要有SSL憑證(至少要TLS1.1以上)
* Server 預計建立在Debian11上面
* 目前使用的服務
* Apache2 httpd
* MySQL Community Server
* Mysql passwd: Iis4296842968.
* SSH Server(方便維護用)
* Cockpit
<!-- L1是比較基本的app
L2 是有涉及登入行為
L3是有金流交易行為 -->
## Trace Code
* 這邊我只把比較重要的寫出來(全部trace完我會往生)
* 你好厲害!!!!!
* 不不不,你懂得比較多的吧XD
#### `Tester.java`
:::info
這個東西是在TestLoader專案裡面,主要的用途是與CmdServer的溝通以及自動化(自動跑整個app)的實現
:::
Tester.java 啟動點是當 Code.js Hook 到 android.app.Activity.onCreate 時,會呼叫 Tester.java 當中的 StartActivity method。
在 StartActivity 當中會先判斷有沒有 Socket 連線,如果沒有表示第一次啟動,會建立 Socket 連線,接著會開一個新的 Thread (m_ControlThread)。
m_ControlThread
**負責接收來自 CmdServer.py 的指令。**
#### `Webapp.py` [未完成]
0. packages
* starlette:
* 是輕量化的ASGI框架,可以透過python架構出一個async web services
* ASGI (Asynchronous Server Gateway Interface),就是一個web的框架
* uvicorn
* 也是一個ASGI的web server,用來跑starlette
```
uvicorn.run(
Starlette(
routes=routes,
exception_handlers=exception_handlers
) ,
host='0.0.0.0', port=8080)
```
* jinja2
* 網頁模板引擎
1. Classes
* APKinfo:
* 網頁版系統針對APP靜態分析的主體
* 使用 MOBSF、Androguard、Androbug 去對APK進行靜態分析
* 初始化就直接對apk進行分析(\_init\_)
* 透過Do_static_analysis去建立各種靜態分析的Thread並執行
* get_source_code:把MOBSF拿到的source code拿出來
* 用python2
* 需要將docker 跑起來
* Loop Timer:
* 就是一個會轉圈圈的東東
* MOBSF以及Androbug在進行靜態分析時會跑的東西
* 不重要(大概)
* HomePage:
* 使用者連入Server後會初始化的Class
* 將使用者重新導向至/upload
* 本來好像需要login 但後來註解掉了
* ### Echo:
* **cmdserver**在這裏面
* 整個網頁系統的本體,大部分的操作都在這裡執行
* 點app上的btn會觸發onclick(),onclick()會傳action過去`webapp.py`,在這邊進行動作判斷
* 一開始要先點start,其他btn會是disabled
* 會送很多json的狀態,應該是寫json檔案的意思
* 還有關於websocket的一些api,像是on_connect,on_receive,on_disconnect等等
* Result:
* 使用者進入/result後會初始化的Class
* GET Req:
* 系統針對使用者的Cookie裡的apk_name進行分析結果的輸出
* 主要是基於/data/data(應用程式的暫存檔)中對應的Package Name中的LogFile去做輸出
* 輸出各項檢測的重要結果(各項風險等級內容,動態系統狀態.....etc)
* 簡單來說就是把LogFile pull出來,然後透過dynamic writer去get result這樣,最後把result 當成response回傳回去
* Upload:
* 使用者進入/upload後會初始化的Class
* GET Req:
* 進入upload介面讓使用者上傳APK
* POST Req:
* 使用者選完檔案後送出的Req
* 分析使用者上傳的是否為APK
* 初始化APKInfo(進行靜態分析)
* 確認MOBSF是否分析完成(一開始轉圈圈的東東)
* 在Cookie中儲存APK的名稱以利後續辨別
* Cookie有點問題,要處理他
* 應該是web socket在做的HTTP GET與HTTP POST(大概是)
* 目前網頁有的頁面:
* /upload: 上傳apk
* /result: App分析結果
* /static-result: 靜態分析結果
* TODO
* Merge學長的論文到系統上面
---
#### `DynamicWriter.py`
<font color = red> line 135 是不是要更新`logEntryList=reportEntryList`? </font>
<font color = blue> 到底mynewdiva 跟mynewdivabeta是一樣的東西嗎(?) 我們後來maybe都是用beta(?) 但其他寫死的資料好像還是mynewdiva(?)</font>
感覺就是mynewdiva的強化版XD
1. class
* LogEntry
* 主要是對log本身的各種操作,包括get跟put
* function、parameter、return、location
* LogDict
* insert = put
* logPrint
* 把log_entry寫到log.txt裡面
* analyze
* 主要是透過DynamicDetectionRule來做檢查,將結果用writer寫出去
* writer format [學長寫好的]
title: 'KeyStore null PWD or hard-coded PWD checking'
tag: '[Critical] [MASA 4.1.2.3.6, 4.1.2.3.8] [OWASP Mobile M5: Insufficient Cryptography]'
description: ['The password of KeyStore is hardcoded or null']
title_zhTW: 'KeyStore 無密碼 / 存在寫死的密碼'
tag_zhTW: '[嚴重] [工業局標準 4.1.2.3.6, 4.1.2.3.8] [OWASP Mobile M5: 無效的加密]'
description_zhTW: ['KeyStore 的密碼是寫死的或空白']
detail: detail
detail_zhTW: detail 中文
logEntryList: reportEntryList
2. method
* getMobSF
* 他把header跟data都寫死了,然後打post request到`http://192.168.50.252:8000/api/v1/scan`,把收到的回覆用json load出來回傳
* getAndrbugs
* 將mynewdiva的json打開來回傳
* with open("../static_analysis_result/com.example.mynewdiva.json", 'r') as f: 這行也是寫死的,但是似乎不會用到,所以沒差
* GetAllResult
* actFile = open('C:\\Users\\jerry\\Documents\\IIS\\Dy_system_dev\\fuckguo\\Frida\\androguard\\activites.txt','r') 這地方也是寫死的應該要改?
---
#### `writer.py`
<font color = blue>
有一個跟Dynamic writer一模一樣的LogEntry class,不知道為啥要這樣(?),但dynamic writer裡面應該用的就直接是自己定義的(就是用dynamic writer寫好的LogEntry class) 所以這邊的不知道要幹嘛??
同樣的我找到main.py.grid跟main.py.table裡面也有這種事情,不知道這兩個是不是自動產生的檔案們(?)</font>
---
#### `DynamicDetectionRule.py`
---
#### `CompileCode.py`
0. packages
* shutil:
* high level file management system
* 這邊用到的是rmtree跟copyfile
* rmtree 移除資料夾
* copyfile(src, dst)
*
2. main [是學長寫好的註解們]
* 清理原先編好的 InjectProject
* InjectCode(base, default, getsettings, strandhogg) 複製到 InjectProject
* 編譯 InjectProject, 拿到注入成功的 .apk File
* 拆包,換成 Smali Code
* smali code 中將原本的 Method 換成 HijackSelfMethod ,避免 Call Loop 問題
* Smali_inject1
* Smali_inject2
* 注入(InjectCode)+ 換HijackMethod 結束後,再回包成APK
---
#### `GenerateJavascript.py`
1. main [是學長寫好的註解們]
* 讀config.txt,並把內容parse去HijackSelfMethod_Config.txt
* 使用JavaScriptGenerator產生code.js
* 使用CastSmaliGenerator產生smali code: Caster.smali
---
#### `SetLoader.py`
1. method LoadDex
* 將apk複製一份變成zip檔,再把zip檔解壓縮,變成dex檔
2. 全域
* 將TestLoader跟InjectProject的debug-app.apk注入到手機的 `/data/local/tmp/`
---
#### `CmdServer.py` [太多了吧Q]
1. classes
* StateButtonEvent
* VIEWEVENTTYPE
* View
* ClickEvent
* StaticAutoModule
* OPCODETYPE
* MODETYPE
* ControlServer
* 透過GlobalSetting裡的東東獲取一些資訊(Port等)
* 會先檢查`CMDDEBUG`的狀態來判斷要不要開Thread使用者的輸入(auto,exit等指令)
* ControlThread
* main
* 主要是有一個ControlServer在做事
2. 現有的功能們
* 藉由ReadStdinThread去處理
* exit: 把 CmdServer kill 掉
* auto: 自動模式,for diva
* manual: 手動模式,單純只蒐集log(須自己點手機,程式會幫忙hook function)
* back: 返回event
* full: FulfillAllEditText
* next:
* showall: 查看 activity 和 View 的對應關係
* loadjson:
* loadcurr:
* save_record:
* goto:
* show:
* fuzz: 指定fuzz editext的id做fuzzing
* setpa:
* getCurr: 現在所在state(activity)
* sauto:
* shows:
* sets:
3. 各種狀態碼(OpCode)
* FINISHACTION : 0
* CHANGESTATE : 1
* GETLISTBUTTONEVENT : 2
* EXECBUTTONEVENT : 3
* CHANGEMODE : 4
* CLIENTERROR : 5
* MANUALSELECTINDEX : 6
* PAUSE : 7
* START : 8
* RESUMEACTIVITY : 9
* PRESSBACKBUTTON : 10
* SETSTATE : 11
* SETSTATE_FINISH : 12
* SETSTATENAME : 13
* EDITTEXT_GET : 14
* VIEWPERFORMCLICKEVENT : 15
4. CmdServer.py 啟動時 (def Start) 會開兩個 Thread。
- NewReadStdinThread
讀取我們的輸入,像是 auto = 啟動自動模式。
- NewControlThread
再開一個 RunFrida thread ,啟動 Frida 並讓 Frida 開啟 App。
等待 Socket 連線。
無限迴圈,接收 Tester.java 透過 Socket 的訊息,並執行對應操作。
---
#### Code.js
frida hook 的部分
---
#### MobSF
https://github.com/MobSF/Mobile-Security-Framework-MobSF
---
#### ws-scrcpy
https://github.com/NetrisTV/ws-scrcpy
是可以讓我們在網頁瀏覽器遠端控制安著手機的一個 npm project
透過npm install將requirements.txt內容都裝一裝之後可以跑npm start (但可能會少一點package 但我忘了我多裝了啥w 總之跑起來系統會跟你說: 是不是少了xxx呢~那時候再裝就好了)
---
#### fuzzing_handler
initialized in line 1049 function startFuzzing
---
投影片連結
https://docs.google.com/presentation/d/1oFmf8BjO_OTlRM6a2sSsI67y-TaXTlc_PUrqf5cXaCo/edit#slide=id.gb805562b93_0_139
https://docs.google.com/presentation/d/1LPUN6ftVpOSva37g1maXI3A7u9OXWJBfg4GZXaiSnAA/edit#slide=id.ge3e94be219_0_5
522