程序員要從0下表開始,這篇是介紹這個系列的背景的,沒有興趣的人可以直接跳過。
為什么要開發ActiveX控件
由於工作需要,我們開發了一個網站,使用了一款身份證識別儀的網頁ActiveX(OCX)插件。但是我發現現在市面上各種識別儀的ActiveX插件都有一個共同的問題,都是可以被仿冒偽造,好多廠家為了適應性,采用了同一個ClassID,實現同樣的接口來讀取信息。
我們的網站是要給到下線使用的,他們有些就會安裝一些身份證讀取軟件,來通過實現一個同樣接口同樣ClassID的ActiveX,達到身份證讀取欺詐的目的。例如clsid:10946843-7507-44FE-ACE8-2B3483D179B7
<form id="form1" runat="server"> <OBJECT classid="clsid:10946843-7507-44FE-ACE8-2B3483D179B7" id="CVR_IDCard" name="CVR_IDCard" width="0" height="0" > </OBJECT> <script language="javascript" type ="text/javascript"> function Button1_onclick() { var CVR_IDCard = document.getElementById("CVR_IDCard"); var strReadResult = CVR_IDCard.ReadCard(); if(strReadResult == "0") { ClearForm(); document.all['Name'].value = CVR_IDCard.Name; document.all['Sex'].value = CVR_IDCard.Sex; document.all['Nation'].value = CVR_IDCard.Nation;
既然欺詐的ActiveX這么猖獗,而身份證識別儀必須采用ActiveX控件的方式讀取外設,所以我們需要開發自己的安全的ActiveX控件。
PS:一開始我們也覺得從技術上是無法完全防范的,從業務規范上的防范會更有效,甚至說安裝個攝像頭防止下面亂來都會有效。不過既然這里是技術博客,我們還是從技術層面做點探討
為什么要從ActiveX調用另一個ActiveX
既然身份證廠家提供了ActiveX(也就是OCX形式的控件),有的甚至會賣大包提供SDK包,也就是下面DLL的調用說明
華視電子識別儀驅動目錄↓
南京藝數識別儀驅動目錄↓
如果我的ActiveX調用他們的DLL,當然技術上是簡單,但是因為識別儀廠家的驅動是不同的,而且DLL的接口也不盡相同,有的甚至不會提供接口文檔,就會造成通用性很差。
如果我的ActiveX調用他們的ActiveX,因為大家提供給網頁端都有同樣的接口,所以通過ActiveX調用ActiveX會更加簡單和通用。為了增加安全性,我們的ActiveX不會通過網頁進行中轉,而是在內存中直接調用識別儀廠家的ActiveX。
var CVR_IDCard = document.getElementById("CVR_IDCard");
var strReadResult = CVR_IDCard.ReadCard();
if(strReadResult == "0")
{
document.all['Name'].value = CVR_IDCard.Name;
document.all['Sex'].value = CVR_IDCard.Sex;
document.all['Nation'].value = CVR_IDCard.Nation;
識別儀廠家的ActiveX控件有什么問題?
問題多了去了!!!我簡單分析了BS加載識別儀數據的過程,有多個漏洞點可以想辦法繞過。
1:可以通過通信截取的,例如用Fiddler等工具攔截通信,修改讀取的信息
2:直接在瀏覽器通信前用js腳本修改數據
3:修改注冊表,將ActiveX控件的指向自己寫的一個偽造控件,服務器就分不清是真控件讀取的還是偽造控件讀取的
4:大部分識別儀廠家的ActiveX控件都是基於公安部發布的幾個動態鏈接庫,如termb.dll、sdtapi.dll等,這些dll的接口都是無校驗的。寫一個偽造的termb.dll替換官方的dll,就可以范圍偽造的信息。
5:從dll讀取usb端口應該還有文章可做,只是過於底層沒有深入研究
還沒算系統鈎子、反編譯破解等高級方法,當然我也不是安全方面的專家,至少將1、2、3等門檻較低的問題修復也就差不多了,為了達到這個目的,我們的做法是開發一個ActiveX來調用識別儀廠家的ActiveX控件,並作安全處理(至於中間的安全做法和防護方法,不在本系列討論內容)。