# 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)的名稱 ## 遠端 ![](https://i.imgur.com/h7hDO5z.png) 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