代碼中被植入了惡意刪除操作,太狠了!

背景
在交接的代碼中做手腳進行刪庫等操作,之前只是網上聽說的段子,沒想到上周還真遇到了,并且親自參與幫忙解決。
事情是這樣的,一老板接手了一套系統,可能因為雙方在交接時出現了什么不愉快的事情,對方不提供源代碼,只是把生產環境的服務器打了一個鏡像給到對方。
對方拿到鏡像恢復之后,系統起來怎么也無法正常處理業務,于是就找到我幫忙看是什么原因。經過排查,原來交接的人在鏡像中做了多處手腳,多處刪除核心數據及jar包操作。下面來給大家細細分析排查過程。
排查過程
由于只提供了鏡像文件,導致到底啟動哪些服務都是問題。好在是Linux操作系統,鏡像恢復之后,通過history命令可以查看曾經執行了哪些命令,能夠找到都需要啟動哪些服務。但服務啟動之后,業務無法正常處理,很多業務都處于中間態。
原本系統是可以正常跑業務的,打個鏡像之后再恢復就不可以了?這就奇怪了。于是對項目(jar包或war)文件進行排查,查看它們的修改時間。
在文件的修改時間上還真找到了一些問題,發現在打鏡像的兩個小時前,項目中一個多個項目底層依賴的jar包被修改過,另外還有兩個class文件被修改過。
于是,就對它們進行了重點排查。首先反編譯了那兩個被修改過的class文件,在代碼中找到了可疑的地方。

可疑代碼
在兩個被修改的類中都有上述代碼。最開始沒太留意這段代碼,但直覺告訴我不太對,一個查詢業務里面怎么可能出現刪除操作呢?這太不符合常理了。
于是仔細閱讀上述代碼,發現上述紅框中的代碼無論何時執行最終的結果都是id=1。你是否看出來了?問題就出在三目表達式上,無論id是否為null,id被賦的值都是1。看到這里,也感慨對方是用心了。為了隱藏這個目的,前面寫了那么多無用的代碼。
但只有這個還不是什么問題,畢竟如果只是刪除id為1的值,也只是刪除了一條記錄,影響范圍應該有限。
緊接著反編譯了被修改的jar包,依次去找上述刪除方法的底層實現,看到如下代碼:

刪除操作
原來前面傳遞的id=1?是為了配合where?條件語句啊,當id=1?被傳遞進來之后,就形成了where 1=1?的條件語句。這個大家在mybatis中拼接多條件語句時經常用到。結果就是一旦執行了上述業務邏輯,就會觸發刪除T_QUART_DATA全表數據的操作。
而T_QUART_DATA表中是用于存儲觸發定時任務的表達式,到這里也就明白了,為啥前面的業務跑不起來,全部是中間態了。因為一旦在業務邏輯中觸發開關,把定時任務的cron表達式全部刪除,十多個定時任務全部歇菜,業務也就跑步起來了。
找到了問題的根源,解決起來就不是啥事了,由于沒有源代碼,稍微費勁的是只能把原項目整個反編譯出來,然后將改修改地方進行了修改。
又起波折
本以為到此問題已經解決完畢了,沒想到第二天又出現問題了,項目又跑不起來了。經過多方排查和定位,感覺還有定時任務再進行暗箱操作。
于是通過Linux的crontab命令查看是否有定時任務在執行,執行crontab -e或crontab -l,還真看到有三個定時任務在執行。跟蹤到定時任務執行的腳本中,而且明目張膽的起名deleteXXX:

刪除腳本
而在具體的腳本中,有如下執行操作:

刪除核心依賴包
這下找到為什么項目中第二天為啥跑不起來了,原來Linux的定時任務將核心依賴包刪除了,并且還會去重啟服務。
為了搞破壞,真是煞費苦心啊。還好的是這個jar包在前一天已經反編譯出來了,也算有了備份。
小結
原本以為程序員在代碼中進行刪庫操作或做一些其他小手腳只是網絡上的段子,大多數人出于職業操守或個人品質是不會做的。沒想到這還真遇到了,而且對方為了隱藏刪除操作,還做了一些小偽裝,真的是煞費苦心啊。如果有這樣的能力和心思,用在寫出更優秀的代碼或系統上或許更好。
當然,不知道他們在交接的過程中到底發生了什么,竟然用這樣的方式對待昔日合作的伙伴。之所以寫這篇文章,是想讓大家學習如何排查代碼問題的過程,畢竟用到了不少知識點和技能,但這并不是教大家如何去做手腳。無論怎樣,最起碼的職業操守還是要有的,這點不接受反駁。






















