1. 程式人生 > 其它 >WEB安全新玩法 [11] 防範批量註冊

WEB安全新玩法 [11] 防範批量註冊

「業務安全動態加固平臺 · 實踐系列」

網站的攻擊者通過批量註冊使用者,能夠實施大規模非法操作,如搶優惠券、惡意刷單等。這給服務商造成了直接的經濟損失,而大量的垃圾使用者也會佔用系統資源,增加系統執行壓力。防範批量註冊需要針對系統特點,多管齊下綜合應對,iFlow 業務安全加固平臺可以提供各種防範批量註冊的技術實現方式。


以某電商網站為例,其使用者註冊功能存在被攻擊者利用的可能。在此將模擬攻擊者批量註冊的行為,並利用 iFlow 使用多種手段來防範攻擊。

攻擊示例

攻擊者編寫 RegistTest.py 指令碼進行攻擊,指令碼使用 WebDriver 驅動瀏覽器模擬正常使用者的註冊操作。

攻擊者事先準備好待註冊的使用者/口令檔案。指令碼執行時迴圈進行如下操作:逐行讀取使用者/口令檔案中的資訊→訪問註冊頁面→使用第三方軟體識別驗證碼→將使用者資訊註冊提交。

指令碼執行完畢後,可以看到大量使用者被註冊,均來自於攻擊者準備的使用者檔案。

手段一 頻度限制

使用 iFlow 可以簡便地實現在規定時間內限制同一訪問主體 (IP 或裝置) 的使用者註冊次數,也可以在規定時間內限制網站整體的使用者註冊次數。

程式碼實現以下條件:

  • 同一裝置在 30 分鐘內使用者註冊超過 3 次,則阻止此裝置訪問 10 分鐘;
  • 同一 IP 在 60 分鐘內使用者註冊超過 10 次,則阻止此 IP 訪問 20 分鐘;
  • 網站整體在 120 分鐘內使用者註冊超過 100 次,則暫停整個系統註冊操作 30 分鐘。
{
	"if": [
		"REQUEST_FILENAME == '/shop/index.php'",
		"@ARGS.s == '/index/user/reg.html'"
	],
	"then": [
        "DEVICE.reg_num@1800=DEVICE.reg_num+1",
		"REAL_IP.reg_num@3600=REAL_IP.reg_num+1",
        "GLOBAL.reg_num@7200=GLOBAL.reg_num+1",
        {
        	"if": "DEVICE.reg_num>3",
            "then": [
                "DEVICE.reg_num=null",
                "block('DEVICE',10*60,'deny')"
            ]
        },
        {
        	"if": "REAL_IP.reg_num>10",
            "then": [
                "REAL_IP.reg_num=null",
            	"block('REAL_IP',20*60,'deny')"   
            ]
        },
        {
        	"if": "GLOBAL.reg_num>100",
        	"then": [
        		"GLOBAL.reg_num=null",
        		"GLOBAL.reg_blocking@1800=true"
        	]
        },
		{
            "if": "GLOBAL.reg_blocking",
            "then": "verdict('deny')"
        }
	]
}

手段二 頁面關聯

正常使用者填寫註冊資訊是需要花費一段時間的,而自動化攻擊獲取註冊頁面和提交註冊資訊的時間往往很短。使用 iFlow 可以有效判斷這種差異,進而區分正常使用者和自動化指令碼。

程式碼實現以下條件:

  • 提交註冊 (reg.html) 之前 120 秒內必須訪問過註冊頁面 (reginfo.html)
  • 訪問註冊頁面 (reginfo.html) 後,必須超過 5 秒才能提交註冊 (reg.html)
[
	{
		"if": [
			"REQUEST_FILENAME == '/shop/index.php'",
			"@ARGS.s == '/index/user/reginfo.html'"
		],
		"then": [
			"SESSION.had_access_reginfo_page_flag@120=1",
			"SESSION.time_between_reginfo_and_reg@5=1"
		]
    },
	{
		"if": [
			"REQUEST_FILENAME == '/shop/index.php'",
			"@ARGS.s == '/index/user/reg.html'"
		],
		"then": {
			"if": "!SESSION.had_access_reginfo_page_flag",
			"then": {
				"action": "deny",
                "log": "reginfo.html must access firstly!"
			},
			"else": {
				"if": "!SESSION.time_between_reginfo_and_reg",
				"then": "SESSION.had_access_reginfo_page_flag=null",
				"else": {
					"action": "deny",
                    "log": "The time between reginfo.html and reg.html is too short!"
				}
			}
		}
	}
]

手段三 客戶端識別

正常使用者使用瀏覽器訪問網站,攻擊者則使用工具模擬瀏覽器或驅動瀏覽器引擎來訪問網站。我們使用 iFlow 在響應中主動插入和執行前端程式碼來獲取客戶端的特徵。

程式碼實現以下條件:

  • 訪問註冊頁面 (reginfo.html) 時,iFlow 在響應報文中加入 js 程式碼段,這段程式碼判斷客戶端是否為 WebDriver,並將結果傳送到 iFlow 檢查點 (checker.dummy)
  • 訪問 iFlow 檢查點 (checker.dummy) 時,iFlow 獲得判斷結果,如果是 WebDriver 則阻止該 IP 的訪問 10 小時。
[
	{
		"if": [
			"REQUEST_FILENAME == '/shop/index.php'",
			"@ARGS.s == '/index/user/reginfo.html'"
		],
		"then": {
			"directive": "alterResponseBody",
			"op": "string",
			"target": "var __user_id__ = 0;",
			"substitute": "var __user_id__ = 0; var httpRequest = new XMLHttpRequest(); httpRequest.open('GET', '/iflow/checker.dummy?ret='+window.navigator.webdriver); httpRequest.send(); "
		}
    },
    {
        "if": [
            "REQUEST_FILENAME == '/iflow/checker.dummy'",
            "@ARGS.ret != 'false'"
        ],
        "then": [
            "verdict('deny', 'Client is webdriver!')",
            "block('REAL_IP', 3600*10, 'deny', REAL_IP.__id..' in blocking')"
        ]
    }
]

手段四 一次性令牌

利用 iFlow 可以給流程加入一次性限時令牌。具體到本例中,訪問註冊頁面時使用者獲得一個一次性令牌,提交註冊時這個令牌被消費掉,缺少令牌則不能進行提交註冊。這一手段可以防範重放攻擊。

程式碼實現以下條件:

  • 訪問註冊頁面 (reginfo.html) 時,iFlow 在響應報文中加入 js 程式碼段,在引數中加入一次性令牌;
  • 提交註冊 (reg.html) 時,iFlow 檢查一次性令牌的真實性並予以銷燬,即令牌不能被重複使用。
[
	{
		"if": [
			"REQUEST_FILENAME == '/shop/index.php'",
			"@ARGS.s == '/index/user/reginfo.html'"
		],
		"then": [
			"TX.tmp_ulh=md5(random())",
			"SESSION.reginfo_ulh@300=SESSION.reginfo_ulh..','.. TX.tmp_ulh",
			{
				"directive": "alterResponseBody",
				"op": "string",
				"target": "/index/user/reg.html", 
				"substitute": "/index/user/reg.html&ulh=${TX.tmp_ulh}"
			}
		]
	},
	{
		"if": [
			"REQUEST_METHOD == 'POST'",
			"REQUEST_FILENAME == '/shopxo-1.6.0/index.php'",
			"@ARGS.s == '/index/user/reg.html'"
		],
		"then": {
			"if": "notNull(SESSION.reginfo_ulh)",
			"then": [
                "SESSION.reginfo_ulh = null",
                {
					"if": "!contain(SESSION.reginfo_ulh, @ARGS.ulh)",
					"then": {
						"action": "deny",
						"log": "${SESSION.reginfo_ulh} not contain ${@ARGS.ulh}!"
					},
					"else": {
						"directive": "alterArgGet",
						"op": "unset",
						"name": "ulh"
					}
				}
            ],
			"else": {
				"action": "deny",
				"log": "${SESSION.reginfo_ulh} is not exist!"
            }
		}
    }
]

總結

針對目標電商網站的批量註冊漏洞,我們使用了頻度限制、頁面關聯、客戶端識別、一次性令牌這四種手段進行防護。事實上,使用 iFlow 還可以寫出其他防護手段,如引數聚合、動態混淆等。通過上述手段,使用者能夠很大程度緩解攻擊者的批量註冊行為。

我們在上述例子中看到:在 Web 伺服器前部署 iFlow 業務安全加固平臺,它有能力攔截、計算和修改雙向 HTTP 報文並具備儲存能力,可以成為 Web 應用的虛擬補丁。(張戈 | 天存資訊)