短信接口被刷爆:我用Nginx臨時(shí)止血
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
最近,朋友公司遇到了一件讓他們“寢食難安”的事:他們的短信驗(yàn)證碼接口被人盯上了,充進(jìn)去的錢沒多久就被刷得一分不剩。不充錢,業(yè)務(wù)直接受影響;但充錢吧,就像往無底洞里灌水。他們聯(lián)系短信服務(wù)商,對方反饋說可能是“被惡意盜刷”。由于他們沒自己的IT團(tuán)隊(duì),App是找外包做的,現(xiàn)在處于無人維護(hù)狀態(tài)。老板希望在不改代碼的前提下想個(gè)辦法幫忙止血。 斷癥:不是Bug,而是接口在裸奔這個(gè)App已經(jīng)穩(wěn)定運(yùn)行了兩年左右,程序 bug 的可能性比較小。我們懷疑是短信平臺信息泄露,或者接口被惡意程序利用。我上服務(wù)器看了下,他們部署非常簡單:前端用 Nginx 直接代理后端 Java 服務(wù)。打開 Nginx 日志發(fā)現(xiàn)有人以每秒3-6次的頻率請求獲取短信驗(yàn)證碼的URL。并且接口調(diào)用未做二次驗(yàn)證,這就等于把“發(fā)驗(yàn)證碼”的權(quán)限完全開放了。哎!機(jī)會(huì)就這樣留給了別有用心的人。 亡羊補(bǔ)牢這種情況,不改代碼確實(shí)有點(diǎn)難搞。從Nginx日志上可以看到,攻擊者使用了大量代理IP,每次請求的IP和參數(shù)都在變化,所以沒辦法通過IP黑名單的方式解決問題。我們只能寄希望于App在請求接口的時(shí)攜帶了攻擊者不具備的標(biāo)識。由于Nginx無法直接打印完整請求頭,所以考慮用OpenResty通過Lua腳步把所有的請求頭內(nèi)容輸出到日志里(這個(gè)接口是Get請求)。又只能在夜深人靜的時(shí)候加班學(xué)習(xí),好在以前了解過一點(diǎn)OpenResty的知識。 分析請求頭先折騰了一個(gè)簡單腳本來分析請求頭,要是這一關(guān)過不了,那基本可以放棄這個(gè)思路了。
經(jīng)過一番分析,發(fā)現(xiàn)App在每個(gè)請求上都帶上了一個(gè)版本號信息(雖然還在1.0.0),好在正好可以用來區(qū)分是否為惡意請求。 基于請求頭做驗(yàn)證接下來,就是利用 Nginx 的 map 指令判斷請求頭中是否包含指定版本號字段。命中放行,沒命中就攔下。
部署上去后看了下 Java 的日志,接口盜刷的請求直接被干掉,效果顯著。 以假亂真雖然攔截成功,但返回403會(huì)暴露我們的防御策略,容易引起對手的注意,分分鐘就能突破這道薄弱的屏障。于是做了個(gè)升級:在nginx攔截到請求后,直接返回請求成功的響應(yīng)結(jié)果,從此以后雙方都可以保持“成功”的假象。 改動(dòng)如下:
經(jīng)測試,妥妥的,在不看日志的情況下,根本看不出到底有沒有真的請求到 Java 服務(wù)。 總結(jié)一直不太能理解,這種攻擊到底圖個(gè)啥。既沒帶來直接利益,還要花成本搞代理搞腳本,這不是典型的損人不利己嗎。在之后的幾天里,一切又恢復(fù)到了往日的寧靜。雖然事情已經(jīng)告一段落,但臨時(shí)止血不是長久之計(jì),解決這類問題還是需加強(qiáng)程序安全驗(yàn)證,提升攻擊難度。 最后關(guān)于OpenResty,可以翻閱我的OpenResty學(xué)習(xí)筆記,歡迎點(diǎn)贊支持。 本文來自博客園,作者:ASER_1989,轉(zhuǎn)載請注明原文鏈接:https://www.cnblogs.com/aser1989/p/18817862 ? 該文章在 2025/4/10 11:51:13 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |