代碼中被植入了惡意刪除操作,太狠了!
背景
在交接的代碼中做手腳進(jìn)行刪庫等操作,之前只是網(wǎng)上聽說的段子,沒想到上周還真遇到了,并且親自參與幫忙解決。
事情是這樣的,一老板接手了一套系統(tǒng),可能因?yàn)殡p方在交接時出現(xiàn)了什么不愉快的事情,對方不提供源代碼,只是把生產(chǎn)環(huán)境的服務(wù)器打了一個鏡像給到對方。
對方拿到鏡像恢復(fù)之后,系統(tǒng)起來怎么也無法正常處理業(yè)務(wù),于是就找到我?guī)兔词鞘裁丛?。?jīng)過排查,原來交接的人在鏡像中做了多處手腳,多處刪除核心數(shù)據(jù)及jar包操作。下面來給大家細(xì)細(xì)分析排查過程。
排查過程
由于只提供了鏡像文件,導(dǎo)致到底啟動哪些服務(wù)都是問題。好在是Linux操作系統(tǒng),鏡像恢復(fù)之后,通過history命令可以查看曾經(jīng)執(zhí)行了哪些命令,能夠找到都需要啟動哪些服務(wù)。但服務(wù)啟動之后,業(yè)務(wù)無法正常處理,很多業(yè)務(wù)都處于中間態(tài)。
原本系統(tǒng)是可以正常跑業(yè)務(wù)的,打個鏡像之后再恢復(fù)就不可以了?這就奇怪了。于是對項(xiàng)目(jar包或war)文件進(jìn)行排查,查看它們的修改時間。
在文件的修改時間上還真找到了一些問題,發(fā)現(xiàn)在打鏡像的兩個小時前,項(xiàng)目中一個多個項(xiàng)目底層依賴的jar包被修改過,另外還有兩個class文件被修改過。
于是,就對它們進(jìn)行了重點(diǎn)排查。首先反編譯了那兩個被修改過的class文件,在代碼中找到了可疑的地方。
可疑代碼
在兩個被修改的類中都有上述代碼。最開始沒太留意這段代碼,但直覺告訴我不太對,一個查詢業(yè)務(wù)里面怎么可能出現(xiàn)刪除操作呢?這太不符合常理了。
于是仔細(xì)閱讀上述代碼,發(fā)現(xiàn)上述紅框中的代碼無論何時執(zhí)行最終的結(jié)果都是id=1。你是否看出來了?問題就出在三目表達(dá)式上,無論id是否為null,id被賦的值都是1??吹竭@里,也感慨對方是用心了。為了隱藏這個目的,前面寫了那么多無用的代碼。
但只有這個還不是什么問題,畢竟如果只是刪除id為1的值,也只是刪除了一條記錄,影響范圍應(yīng)該有限。
緊接著反編譯了被修改的jar包,依次去找上述刪除方法的底層實(shí)現(xiàn),看到如下代碼:
刪除操作
原來前面?zhèn)鬟f的id=1?是為了配合where?條件語句啊,當(dāng)id=1?被傳遞進(jìn)來之后,就形成了where 1=1?的條件語句。這個大家在mybatis中拼接多條件語句時經(jīng)常用到。結(jié)果就是一旦執(zhí)行了上述業(yè)務(wù)邏輯,就會觸發(fā)刪除T_QUART_DATA全表數(shù)據(jù)的操作。
而T_QUART_DATA表中是用于存儲觸發(fā)定時任務(wù)的表達(dá)式,到這里也就明白了,為啥前面的業(yè)務(wù)跑不起來,全部是中間態(tài)了。因?yàn)橐坏┰跇I(yè)務(wù)邏輯中觸發(fā)開關(guān),把定時任務(wù)的cron表達(dá)式全部刪除,十多個定時任務(wù)全部歇菜,業(yè)務(wù)也就跑步起來了。
找到了問題的根源,解決起來就不是啥事了,由于沒有源代碼,稍微費(fèi)勁的是只能把原項(xiàng)目整個反編譯出來,然后將改修改地方進(jìn)行了修改。
又起波折
本以為到此問題已經(jīng)解決完畢了,沒想到第二天又出現(xiàn)問題了,項(xiàng)目又跑不起來了。經(jīng)過多方排查和定位,感覺還有定時任務(wù)再進(jìn)行暗箱操作。
于是通過Linux的crontab命令查看是否有定時任務(wù)在執(zhí)行,執(zhí)行crontab -e或crontab -l,還真看到有三個定時任務(wù)在執(zhí)行。跟蹤到定時任務(wù)執(zhí)行的腳本中,而且明目張膽的起名deleteXXX:
刪除腳本
而在具體的腳本中,有如下執(zhí)行操作:
刪除核心依賴包
這下找到為什么項(xiàng)目中第二天為啥跑不起來了,原來Linux的定時任務(wù)將核心依賴包刪除了,并且還會去重啟服務(wù)。
為了搞破壞,真是煞費(fèi)苦心啊。還好的是這個jar包在前一天已經(jīng)反編譯出來了,也算有了備份。
小結(jié)
原本以為程序員在代碼中進(jìn)行刪庫操作或做一些其他小手腳只是網(wǎng)絡(luò)上的段子,大多數(shù)人出于職業(yè)操守或個人品質(zhì)是不會做的。沒想到這還真遇到了,而且對方為了隱藏刪除操作,還做了一些小偽裝,真的是煞費(fèi)苦心啊。如果有這樣的能力和心思,用在寫出更優(yōu)秀的代碼或系統(tǒng)上或許更好。
當(dāng)然,不知道他們在交接的過程中到底發(fā)生了什么,竟然用這樣的方式對待昔日合作的伙伴。之所以寫這篇文章,是想讓大家學(xué)習(xí)如何排查代碼問題的過程,畢竟用到了不少知識點(diǎn)和技能,但這并不是教大家如何去做手腳。無論怎樣,最起碼的職業(yè)操守還是要有的,這點(diǎn)不接受反駁。