| 一、前言 看個圖,了解下投票的過程。 提交投票信息 投票頁 ――――――――>投票信息處理頁 反饋投票結果 (請求頁)<―――――――(響應頁) 一般情況下,填寫投票信息,然后點提交按鈕發送到響應頁,這樣來完成一個投票。這過程繁瑣,還不能多次投票。有時,手工投票達不到所期待的效果。 曾幫朋友弄過幾次投票,壇里有朋友也PM說要看看源代碼。投票器應該說沒有一個固定的框架,一些處理方法上需要視響應頁做針對性的改動。 自己寫的源代碼太雜亂,放出來怕丟人。10.1放假窩在家里寫了點心得,與大家分享一下。看過之后,你也可以寫。不當之處請指正。 制作投票器,最關鍵的二樣東西是獲得投票信息和找到響應頁。也就是說通過請求頁訪問(提交)響應頁時,提交了什么信息,并且這個響應頁是什么。找到了這兩樣,投票器完成了一大半。 二、編寫投票器所需要的一些HTTP知識 1、 最好是寫過一些網頁。看某網頁的源文件,可以很快找到哪些是form表單、BUTTON提交按鈕、INPUT文件框等內容。 惡補網站: http://www.lib.tsinghua.edu.cn/chinese/INTERNET/HTML/Normal/html_design.html http://www.w3.org/TR/REC-html40/index/elements.html http://www.w3.org/TR/REC-html32.html 2、了解一個HTTP的消息頭由哪些內容組成。如下是一個表單提交后,向網站發送的消息頭內容: POST /redsky/temp/whu_tp/vote.asp HTTP/1.1 //定義HTTP是一個POST動作 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */* //響應頁可以使用的媒體類型 Referer: http://pmc.whu.edu.cn/redsky/temp/whu_tp/whu_tp.asp //請求頁的網址 Accept-Language: zh-cn //指定的字符集類型 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts; mxie; .NET CLR 1.1.4322) Host: pmc.whu.edu.cn Content-Length: 46 //提交數據的長度 Connection: Keep-Alive Cache-Control: no-cache Cookie: ASPSESSIONIDQSCDRSCC=NHNDPPNDPJJFBBJMLBAOMHOD //提交時所傳送的Cookie值。 voted=25&voted=30&voted=35&Submit=%CD%B6%C6%B1 //提交時,所傳送的數據 惡補網站: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 小結: WIN form 、WEB FORM兩樣都得精通,這是師傅2002年說的。 三、輔助軟件 查看HTTP消息頭的軟件,專門的軟件有HTTP Watch( http://www.hanzify.org/index.php?Go=Show::List&ID=4384)或IEWatch, 也可以用 CommView (這些天www.ttdown.com上的軟件沒法下載:-()之類抓包的軟件。 四、手工分析投票過程 先說說手工操作時一個正常的投票過程(以武漢大學的這個投票為例) http://pmc.whu.edu.cn/redsky/temp/whu_tp/whu_tp.asp 選擇被投票人石云霞(在姓名前面打勾),然后點“投票”,響應頁接收被投票人的姓名并記錄投票數記錄投票人的IP,然后返回投票成功或重復投票的信息。 這一過程很簡單,但我們不知道點投票后,瀏覽器向網頁發送了什么信息。在這里,先別急著用軟件來看,嘗試手工分析,這有助于一些復雜情況的解決。 回到投票的網頁,查看源文件(前面所提到的http基本知識派上用場了), a)首先找響應頁是什么,也就是接收處理投票信息的網頁。在記事本中按Ctrl+f,查找’<form’字符串。通過搜索,找到這么一行: <form name="form1" method="post" action="vote.asp"> Form表單的名稱name=form1,方法method=post,動作action=vote.asp 。vote.asp是我們所關心的,這個就是響應頁的地址。 整理地址得到:http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp b)查找被投票人的信息。被投票人的選擇是通過一個多選框來完成,那么在源文件里查找’<input’字樣。通過搜索,找到了以下內容。 <input type="checkbox" name="voted" value="25"> <a href="whu_tp_more.asp?id=25" class="index" target="_blank"> 石云霞</a> <b><font color="#FFFF00" size="2"> </font></b> <input type="checkbox" name="voted" value="26"> <a href="whu_tp_more.asp?id=26" class="index" target="_blank"> 李義天</a> <b><font color="#FFFF00" size="2"> </font></b> …………………………. 從這一大串內容中可以看出,石云霞的編號為25,李義天的編號為26 ,input元素的名稱為voted。 整理一下voted=25這是被投票人的信息。 查找input的時候需要注意,看是否有hidden類型的input元素。隱藏一定數量的input元素,可以起到一定的防范作用。 在源文件里一直看下去,只到</form>為止。在</form>前還有兩個按鈕, <input type="submit" name="Submit" value="投票"> <input type="reset" name="Submit2" value="重置"> 組合一下 submit=投票 submit2=重置(這個內容可以忽略)。 c) 最后整理一下,得到一個完整的網址 http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票 在瀏覽器中訪問一下這個地址,看有什么提示??,提示“投票成功“。再次訪問提示“你的IP已經投過一次了^_^”。這說明這個網址就是真正的投票網址。只要不斷地訪問這個網址,就可以達到投票的目的。 小結:沒寫過網頁也沒關系,通過輔助軟件也可以分析出這一網址。 五、軟件分析投票過程 安裝HTTPWATCH后,重啟機器,可以在IE標準按鈕欄中找到它的圖標(沒有的話,從菜單‘查看’->‘瀏覽器欄’中選擇),單點圖標后如圖,IE窗口下半部分顯示出HTTPWATCH的工作窗口。 http://bbs.et8.net/bbs/attachment.php?attachmentid=339392&stc=1 圖中顯示的內容是選擇點擊‘投票’按鈕后,IE與網站之間的數據流。上半部分記錄了IE訪問了哪幾個網頁,下半部分是訪問某個網頁時,具體的數據流。 (HTTPWATCH的使用方法在這里不細講了。) 我們在正常瀏覽網頁時,IE一般的動作都是GET。而投票過程中,IE需要將你的選擇(被投票人的姓名)提交給投票的網址,訪問這個網址時,IE將產生一個POST動作。查看HTTPWATCH的記錄,URL=http: //pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp時,IE的動作是POST。那么http: //pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp就是投票的響應頁。這和前面手工分析時找到的響應頁是一致的。 找到了響應頁,接下來找投票的信息,也就是IE提交了什么數據。這里看HTTPWATCH窗口的下半部分。 下半部分是一個TAB PANEL,看重要的幾個標簽。 HEADERS:提交到響應頁的HTTP HEADER的內容。 Cookies:提交時,Cookies的內容。 POST DATA:提交時,IE向響應頁發送的數據。 STREAM:提交時,本地機器與網站之間的傳輸的數據流。 http://bbs.et8.net/bbs/attachment.php?attachmentid=339393&stc=1 顯而易見,POST DATA是我們要找的內容。看到這個標簽,左邊是兩個參數名voted 和submit ,右邊是兩個參數的值,‘25’和‘投票’。整理一下得到: Voted=25 submit=投票 將這兩個參數值與前面找到的網址整理一下,得到 http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票 六、編寫投票器 找到了真正的投票URL,用C#做投票器就簡單了,無非是做到:如何循環地訪問這個網頁。 看下面的這個過程。 ……… using System.Net; ……… public int GotoURL( out string message,string url,int timeout,string proxyurl,string keyword,out int rate,bool proxyed) /* Message:返回的信息 Url:需要訪問的地址 Timeout:超時時間 Proxyurl:代理的地址 Keyword:判斷投票成功的標志 Rate:訪問url所花費的時間 Proxyed:是否使用代理 */ { byte[] gbyte=new byte[1024]; string strInput; int iret=3; int i,len=0; DateTime dtBegin=DateTime.Now; message="正在訪問中。。。"; try { url=@"http://pmc.whu.edu.cn/redsky/temp/whu_tp/vote.asp?voted=25& submit=投票"; WebRequest myWebRequest=WebRequest.Create(url); myWebRequest.Timeout=timeout;//設置超時時間=15000毫秒 if (proxyed)//是否使用代理功能 { WebProxy myProxy=new WebProxy();//實例化一個WebProxy類,這個類設置WebRequest的Proxy屬性,這樣可以通過代理來訪問url。 myProxy=(WebProxy)myWebRequest.Proxy; string proxyAddress= proxyurl; Uri newUri=new Uri(proxyAddress); myProxy.Address=newUri; myWebRequest.Proxy=myProxy; } WebResponse myWebResponse=myWebRequest.GetResponse();//實例化一個WebResponse類,用于接收WebRequest的響應內容,依據內容來判斷投票是否成功。 Stream streamResponse=myWebResponse.GetResponseStream();// 實例化一個Stream類,從WebResponse接收數據流。 i=streamResponse.Read(gbyte,len,1024); len+=i; while(i!=0) { i=streamResponse.Read(gbyte,len,1024); len+=i; } strInput=System.Text.Encoding.GetEncoding("gb2312").GetString(gbyte); i=strInput.IndexOf("成功"); Console.WriteLine(i); if (i==-1) message="訪問成功"; else message="訪問失敗";// 將數據流轉換成字符串,并從中判斷投票是否成功。 iret=0; streamResponse.Close(); } catch (System.Net.WebException we) { message="NetError"+we.Message; } catch (System.IO.IOException ie) { message="IOError"+ie.Message; } catch (System.Exception ex) { message=ex.Message; } TimeSpan ts=DateTime.Now-dtBegin; rate=(int)ts.TotalMilliseconds; //獲取訪問的時間。 return iret; } 過程很簡單,就是使用System.Net中的兩個類來訪問網頁。 創建實例:WebRequest myWebRequest=WebRequest.Create(url); 訪問網頁:WebResponse myWebResponse=myWebRequest.GetResponse(); 流StreamResponse視響應頁的處理方法,可能沒有任何返回內容。 Stream streamResponse=myWebResponse.GetResponseStream(); 考慮到一個IP只能投票一次的限制,過程加了使用代理的功能 WebProxy myProxy=new WebProxy(); 這樣即可以當投票器來使用,也可以用于檢測代理的有效性。 接下來的事,就容易多了。找代理,循環調用這個過程。循環速度感覺慢的話,可以用多個線程一起來跑。 小結:直接訪問響應頁就能投票,這是最常見的投票方式。網頁設計人員沒有在響應頁做防范處理,從而為投票器創造了的條件。 防范措施通常有以下幾種: 1、 對HTTP HREADERS里的REFERER做判斷,為空表示沒有訪問過投票頁(提交頁)。這樣繞開請求頁,直接訪問響應頁是無效的。 2、 訪問投票頁時,在headers里的cookies里設置某種標志,提交時,響應頁對這個標志做判斷。沒有這個標志,直接訪問響應頁是無效的。 3、 訪問投票頁時,隨機生成N位數字驗證碼,響應頁對驗證碼做判斷。 4、 生成圖形驗證碼。響應頁對驗證碼做判斷。 第1、2種方法容易處理,研究出規律,設置WebRequest的headers屬性。 第3種方法需要多加個過程,首先訪問投票頁得到驗證碼,然后與其他data組合一同post給響應頁。 第4種無解,和和。不過,還沒發現哪種投票會用上圖形驗證碼這措施。手工投票不僅麻煩,同時也關閉了自己、他人的方便之門。 結言: 不管投票方式如何,投票所需填寫的內容有多復雜,最終它還是要提交給響應頁做處理。多看看http watch。 不會編程也沒關系,找代理軟件,利用代理檢測的功能,投票。 |