阅读“CTF比赛总是输?你还差点Tricks!”记录

偶然间从网上搜罗到一些网络安全的资料,有些日子没有看这方面内容了(大三狗课太多了😩)。因此做此纪录
注:所有内容仅为个人记录,如有错误,欢迎指出(本人还是个菜鸡T_T),附上文件链接:CTF比赛总是输?你还差点Tricks!

一、WEB狗出题套路

个人觉得对学习路线有一定帮助,先mark一波🥴

  1. 爆破(md5,爆破随机数,验证码识别等)
  2. 绕WAF(花式绕mysql,文件读取关键词检测的拦截)
  3. PHP特性(弱类型,反序列化,\0截断,iconv截断)
  4. 密码题(包括hash长度扩展、异或、移位加密各种变形、32位随机数过小、随机数种子可预测等)
  5. 找源码技巧(各种源码泄露)
  6. 文件上传(花式文件名,文件内容检测,各种解析漏洞)
  7. mysql类型差异(包括和PHP弱类型类似的特性,0x、0b、0e之类,varchar和integer相互转换,非strict模式截断等)
  8. open_basedir、disable_functions花式绕过技巧
  9. 条件竞争
  10. 社工
  11. windows特性(包括短文件名、IIS解析漏洞、NTFS文件系统通配符、::$DATA,冒号截断)
  12. SSRF
  13. XSS
  14. XXE
  15. 各种协议

二、WEB弱类型相关题型

2.1 strcmp字符串比较

示例代码

<?php
define('FLAG', 'pwnhub{THIS_IS_FLAG}');
if (strcmp($_GET['flag'], FLAG) == 0) {
    echo "success, flag:" . FLAG;
}

解题思路

  • 根据strcmp函数的解释,用于比较两个字符串,如果str1<str2则返回<0,反之返回>0;相等则返回0
  • 如果strcmp函数出错,则会返回NULL,而NULL==0,成功绕过。strcmp无法对数组进行操作,操作数组将会返回NULL,如下:
<?php
var_dump(strcmp([1, 2, 3], [2, 3, 4]));

运行结果:

2.2 字符串比较升级版

示例代码

<?php
define('FLAG', 'pwnhub{THIS_IS_FLAG}');
if (
    $_GET['s1'] != $_GET['s2']
    && md5($_GET['s1']) == md5($_GET['s2'])
) {
    echo "success, flag:" . FLAG;
}

解决方案1:

  • 通过科学计数法我们可以得知,0e1234560e567890
  • 对应的有些字符串的md5值是0exxxxxxxxxxx的形式。只要找到两个符合要求的字符串即可。例如下面的代码
<?php
var_dump(md5('QNKCDZO') == md5('240610708'));

运行结果:

解决方案2:

  • 与上一题类似,使用NULL==NULL的原理,只要让函数返回NULL即可
  • md5()同样的无法处理数组,如下:
<?php
var_dump(md5([1,2,3]));

结果如下:

  • 但存在一个问题就是,我们用户该如何的向后台提交数组呢,直接提交形如[1,2,3]这样的内容,会被视为字符串保存,要提交数组,只要按F12,找到要提交的表单,修改name属性为属性名[]再提交即可。比如代码如下:
<form action="" method="post">
    <input type="text" name="arr">
    <input type="submit" value="submit">
</form>
<?php
if (isset($_POST['arr']))
    var_dump($_POST['arr']);

修改内容

修改后上传数据,显示结果如下

2.3 登录逻辑常见考点

示例代码

<?php
$name = addslashes($_POST['name']);
$r = $db->get_row("SELECT `pass` FROM `user` WHERE `name`='{$name}'");
if ($r['pass'] === md5($_POST['pass'])) {
 //...login success
}

解题思路

  • 本题中使用了===,无法使用弱类型比较,SQL注入也不存在。需要通过构造NULL来实现绕过登录
  • 再sql查询中,如果查询不到相关用户,对应的pass的值将会是NULL,同理,使用NULL===NULL,我们只需要将md5()返回值为NULL即可,因此该题的关键就是提交一个不存在的用户名,使得返回的$r['pass']NULL。而密码我们提交一个数组,使得md5函数运行出错,返回NULL,这样即可登录成功!
posted @ 2020-10-18 14:20  Lionely  阅读(207)  评论(0编辑  收藏  举报