偷懶打卡的新姿式

我不想我不想我不想遲到~

公司使用的是xxapp打卡。要想本身打卡, 那麼我抓包獲取接口和參數,本身組裝,本身訪問接口便可。 說幹就幹,我開始在登陸界面進行抓包:

https抓包.png

從圖上能夠發現:web

  • 在請求的時候,herades 裏面有一些參數,包括了custom-device-idcustom-versioncustom-oscustom-company-idx-json-web-token等,這些內容是自定義header加上去的,後期調用接口時可能會用到
  • 採用了https鏈接

既然XXX採用https方式,咱們沒有證書,就沒法攔截獲取信息,接口調用基本行不通了,那麼咱們採用AccessibilityService輔助功能的方式進行打卡如何呢?json

思路是:將一臺手機放到公司,鏈接網絡,另外一臺手機遠程QQ發送消息,公司這臺手機接收到消息,點亮屏幕,向上滑動解鎖,打開XXX,此時咱們的打開app是在運行的,而後經過AccessibilityService進行輔助點擊從而進行打卡。或者直接設置定時器,時間到以後自動觸發以上過程並打卡。但這種思路對進程保活有至關高的要求,不太好實現。數組


使用https以前的XXX,確定是http,那麼http接口今安在?bash

http訪問,試接口.png

竟然200,並且從返回的json來看,登陸接口對於服務器的邏輯來講是沒問題的,應該是在使用中,那麼下一步咱們只須要拿到入參就行。服務器


下一步,反編譯xxxx.apk,用到的工具是AndroidCrakTool網絡

反編譯XXX.png

這裏要提一下,反編譯後咱們能拿到資源文件們,資源文件對於定位頁面,控件,以及此控件接下來的邏輯是相當重要頗有幫助的。app

  • 反編譯後,將AndroidManifest.xmlres文件夾留下,其餘的刪除便可,由於咱們這次不對smali進行分析
  • 另外,反編譯後咱們發現XXX並無對代碼進行加殼,只是單純的混淆了。因此這就更加輕鬆簡單

接下來,咱們將XXX.apk後綴名改成zip,而後解壓,獲得以下內容:ide

解壓XXX.png

能夠看到,獲得了兩個dex文件,一個classes.dexclasses2.dex,這是由於他的方法數超過了65536,進行multidex的結果。如今咱們使用AndroidCrakTool對這兩個dex進行dex2jar,目的是將dex轉成jar包,方便咱們閱讀源碼。工具

dex2jar.png

獲得jar包以後,咱們用JD-GUI打開閱讀,也可使用AS或者IDEA進行源碼閱讀。這裏採用JD-GUI佈局


打開這兩個jar以下圖:

打開後.png

如今來理一理思路,咱們剛纔測試的是登陸接口,咱們目的是打卡,那麼咱們就須要登陸後,獲得token,而後帶上token和一大堆參數進行打卡接口的訪問,因此第一步,咱們須要獲得登陸接口的參數。


咱們經過使用TopActivity,在手機上找到登陸界面的Activity名字:

登陸界面截圖.png

從圖中左上角能夠知道這個界面的名字和包名,因此咱們在JD-GUI中找到對應的包名進入尋找登陸界面。因爲咱們有兩個jar,因此就先挨個找吧。但從順序來講,這個登陸界面通常會在dex1中,固然這也是猜想,不過通常按照代碼量和順序來看的話是這樣的。果不其然,以下圖:

登陸界面代碼截圖.png

從界面上看,咱們是點擊了button以後進行網絡請求的,因此咱們當作員變量,發現一個button,變量名i,而後緊接着下面有個b()方法,內部將i初始化了,findviewbyid()內部傳入的正是這個buttonidR文件中的靜態常量值。這裏插一句,若是有須要對界面和id進行分析的話,就須要從這些dex中找到R文件,而後將這個id的數值拿去尋找匹配,就能在R文件中反向獲得這個控件的id,而後將這個id拿到以前反編譯後的res文件夾中搜索匹配,從而獲得佈局文件,控件id等。固然也能經過ASDDMS進行佈局分析,從而獲得id,不過那個id是混淆後的,在jar中是沒法找到的,由於jar中使用的idint靜態常量。

接下來咱們將i變量的id2131362755用來進行搜索,獲得設置點擊事件的地方。這裏爲什麼不直接用變量i呢?由於i是混淆後的,搜出來可能會有不少,很差排除。

搜索button.png

從圖上能夠看到,咱們找到了onClick()回調,而且找到了點擊後的邏輯。圖中有個方法,叫executeOnExecutor(),看起來像是AsyncTask的線程池執行方法,咱們看看是否是,這時候點擊前面new b(),看看這個b對象是啥,以下圖:

AsyncTask.png

能夠看到果真是AsyncTask。那麼結果就顯而易見了,這次請求使用AsyncTask發起,因此咱們在AsynctTask內部就能找到網絡請求的相關內容了。先看第一個:

protected Void a(Void... paramVarArgs){
          this.b = b.w(this.d, this.e);
          return null;
    }
複製代碼

此方法一看就知道,他是doInBackground方法混淆後的,由於他的返回值是Void而不是void。在這個AsyncTask實現的時候,泛型定義以下:

private class b extends AsyncTask<Void, Void, Void>{}
複製代碼

三個Void,因此能夠判定第一個a()方法是doInBackground。那麼網絡請求就在這裏面了。再來看第二個a()方法。

protected void a(Void paramVoid){}
複製代碼

從返回值和參數來看,多是onCancelled()onPoseExcute(),可是從總體代碼和代碼量來看,能夠判定是onPoseExcute()

登陸接口發起請求.png


如今回過頭來分析doInBackground()

this.b = b.w(this.d, this.e);
複製代碼

咱們點擊w()進入看看:

登陸參數組裝.png

能夠看到,這個b對象的w()方法,就是組裝登陸接口所需參數的,登陸接口須要2個參數,最下面那個是接口地址,紅色部分是一串字符串。而經過大碼部分的字符串,咱們能夠知道第二個參數是密碼,那麼後面跟一串字符串是什麼呢?是否是加密?,咱們點擊e.a()中的a()方法去看看:

加密.png

從圖上能夠看到a()方法接收一個參數,聯繫剛纔組裝數據的地方,能夠知道,密碼是由明文加後面紅色部分字符串,再總體通過MD5加密以後的。至於爲什麼知道是明文密碼,咱們返回到LoginActivity,在AsyncTask實例化的時候傳入了兩個參數,後者就是密碼。這個密碼字符串的獲取方式是反推出來的,以下圖:

明文密碼.png

因此,如今咱們有了接口地址,參數,加密方式,咱們試試看可否訪問成功。

通過調試,登錄成功,server返回了一堆數據,其中包括了token,id等:

登錄成功.png

咱們如今至關於完成了50%

接下來的步驟要比以前簡單太多了。經過抓包,獲取到打卡接口的大概路徑,而後在剛纔組裝登陸接口參數的b類中,查詢匹配這個接口地址,因而獲得了打卡的完整接口地址。而且獲得了入參。剩下的就是慢慢組裝數據了。咱們須要打卡,那麼就須要經緯度。經過反編譯發現他是用的是高德地圖,因而咱們使用高德的地理位置反編碼,將咱們想打卡的位置的經緯度獲得,而後傳入參數體,從而實現登陸並打卡。


其實整個過程走下來,最主要的幾個點:

  • 在替換成https後,原http接口未關閉,多是爲了兼容老版本
  • apk未進行更深層的保護,僅僅只是混淆
  • 密碼加密的關鍵信息未進行有效保護,直接暴露了出來

最後,此次嘗試主要是利用了http接口未關閉的漏洞,其實說到底也就是一次抓包分析數據的過程。


  • 以上敏感信息均作馬賽克處理
  • app名字也替換成了XXX
  • 請勿用做商業用途和非法途徑,僅供學習參考
  • 若有侵權,聯繫我刪除
相關文章
相關標籤/搜索