利用PythonInfiniti爆破路由器密码, 限定错误次数? 对Python无用!

图片 1

落到实处登入时密码错误次数节制作用,就是在登陆分界面中当顾客提交了不当的密码时在数据库中记录下那几个张冠李戴次数,直到错误次数到达钦点次数时,锁定顾客账户,那个时候纵然输入正确的密码,也不能够登陆。

image

亟待达成如下工作:

在庭院里面看见了二个没人用的路由器(ws860s卡塔尔,看起来像个黑科学技术的玩意儿,就想着进去看看,到底有何有意思的。见到前边的标签上有web分界面包车型大巴地址,然后登录进去看看,开采存密码,然后本人想,路由器的密码应该都以能够reset的,然后笔者就用笔戳那多少个reset键,神迹未有发生,原本那些reset键坏了。

(1)纠正客户表users的组织,扩展有关字段。

图片 2

(2)自定义落成UserDetailsService,用于加载额外的数目字段。

image

(3)自定义完成AuthenticationProvider,用于捕获登入成功和挫败的事件。

图片 3

(3)改过spring-security.xml文件,配置上述(2)和(3)的音讯。

image

(4)改过登陆战败页面,呈现具体登入错误消息。

浅析进度

 

抓包

1.1.1. 改过顾客表结构

对users表的表结构做如下更正,

充实七个字段:

账户是不是过期: expired

账户是或不是锁定:locked

密码是还是不是过期:passwordexpired

签到失利次数:failtimes

Spring Security在UserDetails接口以至User类中均定义了前3个字段对应的品质,不过在查询数据库时,私下认可未有询问那多少个字段,在创设User实例时均以true举办组织。在自定义UserDetailsService时将效仿JdbcDaoImpl对loadUsersByUsername()方法开展纠正。

 

 

实际SQL操作如下:

 

mysql> alter table users add column expired boolean not null;

Query OK, 0 rows affected (0.28 sec)

Records: 0  Duplicates: 0  Warnings: 0



mysql> alter table users add column locked boolean not null;

Query OK, 0 rows affected (0.06 sec)

Records: 0  Duplicates: 0  Warnings: 0



mysql> alter table users add column passwordexpired boolean not null;

Query OK, 0 rows affected (0.08 sec)

Records: 0  Duplicates: 0  Warnings: 0



mysql> alter table users add column failtimes int not null default 0;

Query OK, 0 rows affected (0.34 sec)

Records: 0  Duplicates: 0  Warnings: 0



mysql> desc users;

+-----------------+-------------+------+-----+---------+-------+

| Field           | Type        | Null | Key | Default | Extra |

+-----------------+-------------+------+-----+---------+-------+

| username        | varchar(64) | NO   | PRI | NULL    |       |

| password        | varchar(64) | NO   |     | NULL    |       |

| enabled         | tinyint(1)  | NO   |     | NULL    |       |

| expired         | tinyint(1)  | NO   |     | NULL    |       |

| locked          | tinyint(1)  | NO   |     | NULL    |       |

| passwordexpired | tinyint(1)  | NO   |     | NULL    |       |

| failtimes       | int(11)     | NO   |     | 0       |       |

+-----------------+-------------+------+-----+---------+-------+

7 rows in set (0.00 sec)



mysql> select * from users;

+----------+------------------------------------------+---------+---------+--------



+-----------------+-----------+

| username | password                                 | enabled | expired | locked |



passwordexpired | failtimes |

+----------+------------------------------------------+---------+---------+--------



+-----------------+-----------+

| lisi     | 40bd001563085fc35165329ea1ff5c5ecbdbbeef |       1 |       0 |      0 |



              0 |         0 |

| wangwu   | 40bd001563085fc35165329ea1ff5c5ecbdbbeef |       1 |       0 |      0 |



              0 |         0 |

| zhangsan | 40bd001563085fc35165329ea1ff5c5ecbdbbeef |       1 |       0 |      0 |



              0 |         0 |

+----------+------------------------------------------+---------+---------+--------



+-----------------+-----------+

3 rows in set (0.00 sec)

 

 

1、打开路由的web页面:192.168.3.1,路由器再次来到

1.1.2. 落到实处自定义的UserDetailsService

 

(1)先定义二个UserDetailsUpdater接口。

此接口类型将用作CustomAuthenticationProvider的登陆帮忙消息爱护对象CustomUserDetailsService的接口类型。

 

/**

* @ClassName: UserDetailsUpdater

* @Description: 用于维护用户登录辅助信息

* @author http://www.cnblogs.com/coe2coe/

*  

*/

public interface UserDetailsUpdater {



/**

 * 在登录密码错误和登录成功时维护登录辅助信息。

 * @param username  用户名

 * @param success   登录是否成功

 * @throws Exception

 */

void updateUser(String username, boolean success) throws Exception;


}

 

 

 

(2)定义自定义的CustomUserDetailsService类。

从Spring Security的JdbcDaoImpl类继承,同一时间达成了UserDetailsUpdater接口。

 

/**

* @ClassName: CustomUserDetailsService

* @Description: (1)从数据库中加载安全相关的用户信息,添加了SpringSecurity默认不包含的3个字段。

*               (2)实现UserDetailsUpdater,维护登录辅助信息。

* @author http://www.cnblogs.com/coe2coe/

*  

*/

public class CustomUserDetailsService extends JdbcDaoImpl implements UserDetailsUpdater {



/**

 * 从数据库查询用户信息。

 */

@Override

protected List<UserDetails> loadUsersByUsername(String username) {

return getJdbcTemplate().query(this.getUsersByUsernameQuery(),

new String[] { username }, new RowMapper<UserDetails>() {

@Override

public UserDetails mapRow(ResultSet rs, int rowNum)

throws SQLException {

String username = rs.getString("username");

String password = rs.getString("password");

boolean enabled = rs.getBoolean("enabled");

boolean locked = rs.getBoolean("locked");

boolean expired = rs.getBoolean("expired");

boolean passwordExpired = rs.getBoolean("passwordexpired");

return new User(username, password, enabled,

!expired,!passwordExpired,!locked,

AuthorityUtils.NO_AUTHORITIES);

}



});

}



/**

 * 主要作用是使SpringSecurity最终使用的UserDetails不必要与从数据库查询出的UserDetails完全相同。

 * 提供了一个间接的中间层。

 */

@Override

protected UserDetails createUserDetails(String username, UserDetails userFromUserQuery,

List<GrantedAuthority> combinedAuthorities) {

String returnUsername = userFromUserQuery.getUsername();



if (!this.isUsernameBasedPrimaryKey()) {

returnUsername = username;

}

return new User(returnUsername,

userFromUserQuery.getPassword(),

userFromUserQuery.isEnabled(),

userFromUserQuery.isAccountNonExpired(),

userFromUserQuery.isCredentialsNonExpired(),

userFromUserQuery.isAccountNonLocked(),

combinedAuthorities);

}





@Override

public void updateUser(String username, boolean success) throws Exception {

if(success){

this.getJdbcTemplate().update(sqlUnlockUser, username);

}

else{

this.getJdbcTemplate().update(sqlIncreaseFailTimes,username);

if(this.getJdbcTemplate().queryForObject(sqlQueryFailTimes, Integer.class,username) >= maxFailTimesBeforeLock)

{

this.getJdbcTemplate().update(sqlLockUser,username);

}

}

}



//最大的失败次数

private int     maxFailTimesBeforeLock = 5;



//解锁账户

private String  sqlUnlockUser = "update users set locked = false,failtimes=0 where username=?";



//锁定账户

private String  sqlLockUser = "update users set locked = true where username=? and locked = false";

//增加失败次数

private String  sqlIncreaseFailTimes = "update users set failtimes = failtimes + 1 where username=?";



//查询失败次数。

private String  sqlQueryFailTimes = "select failtimes from users where username=?";





public String getSqlUnlockUser() {

return sqlUnlockUser;

}

public void setSqlUnlockUser(String sqlUnlockUser) {

this.sqlUnlockUser = sqlUnlockUser;

}

public String getSqlLockUser() {

return sqlLockUser;

}

public void setSqlLockUser(String sqlLockUser) {

this.sqlLockUser = sqlLockUser;

}

public String getSqlIncreaseFailTimes() {

return sqlIncreaseFailTimes;

}

public void setSqlIncreaseFailTimes(String sqlIncreaseFailTimes) {

this.sqlIncreaseFailTimes = sqlIncreaseFailTimes;

}

}

 

 

 

 

 

自定义CustomAuthenticationProvider类

 

重大效用是在客户登陆时现身密码错误时甚至登入成功时开展自定义的处理。

 

/**

* @ClassName: CustomAuthenticationProvider

* @Description: 自定义的一个用户认证提供者。

* @author http://www.cnblogs.com/coe2coe/

*  

*/

public class CustomAuthenticationProvider extends DaoAuthenticationProvider {



@Override

public Authentication authenticate(Authentication auth) throws AuthenticationException {

System.out.println("authenticate begin------");

Authentication  authResult = null;

try{

authResult =  super.authenticate(auth);



try{//验证成功,重置密码错误次数。

this.userDetailsUpdater.updateUser(auth.getName(), true);

}

catch(Exception exp){

exp.printStackTrace();

}

}

catch(BadCredentialsException ex){//密码错误,增加密码错误次数,达到最大次数时锁定账户。

    System.out.println("BadCredentialsException:" + auth.getName());

  try{

this.userDetailsUpdater.updateUser(auth.getName(), false);

}

catch(Exception exp){

exp.printStackTrace();

}

throw ex;

}

catch(AuthenticationException ex){

System.out.println("AuthenticationException:" + auth.getName());

System.out.println(auth.getDetails());

System.out.println(auth.getPrincipal());

   throw ex;

}

System.out.println("authenticate end--------");

return authResult;

}



private UserDetailsUpdater  userDetailsUpdater;



public UserDetailsUpdater getUserDetailsUpdater() {

return userDetailsUpdater;

}



public void setUserDetailsUpdater(UserDetailsUpdater userDetailsUpdater) {

this.userDetailsUpdater = userDetailsUpdater;

}

}

 

 

图片 4

1.1.3. 修改spring-security.xml文件

重视指标是将上述的自定义CustomUserDetailsService和CustomAuthenticationProvider类举办铺排,并布置到AuthenticationManager中。

 

 

<!-- 用户和角色的对应关系 -->

 <sec:authentication-manager>

 <!-- 指定AuthenticationProvider为自定义的CustomAuthenticationProvider -->

   <sec:authentication-provider ref="authenticationProvider"  />

 </sec:authentication-manager>





<!-- 自定义的CustomUserDetailsService -->

<beans:bean  id="userDetailsService"  class="com.test.security.CustomUserDetailsService" >

  <beans:property name="dataSource" ref="dataSource"></beans:property>

  <beans:property name="usersByUsernameQuery"

   value="select * from users where username=?"

   ></beans:property>

</beans:bean>



<!-- 自定义的CustomAuthenticationProvider

     将UserDtailsService和UserDetailsUpdater注入其中。

 -->

<beans:bean id="authenticationProvider" class="com.test.security.CustomAuthenticationProvider">

 <beans:property name="userDetailsService" ref="userDetailsService"></beans:property>

 <beans:property name="passwordEncoder" ref="passwordEncoder"></beans:property>

 <beans:property name="userDetailsUpdater" ref="userDetailsService"></beans:property>

</beans:bean>



<!-- 仍然是使用SHA摘要算法处理密码 -->

 <beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"></beans:bean>

 

 

 

image

1.1.4. 改正登陆战败页面

 

指标是目的在于在签到战败时展现具体登入错误消息。

Spring Security将登陆失利时的充足对象存放在requst对象的质量中。

在login_failed.jsp中扩展如下代码:

 

<p>${SPRING_SECURITY_LAST_EXCEPTION.message}</p>

  

 

签到密码错误时显示密码错误:

 图片 5

 

 

当累加5次密码错误之后,再度登陆时显得账户已锁定:

 图片 6

 

 

图片 7

1.1.5. 总结

有多少个须要注意的地点:

  (a)使用的密码摘要算法的类名可以在Spring Security的源代码中找到。

  (b)原始的Spring Security加载客商表users中的音讯时,未有加载登陆扶持消息,所以举行了自定义,编写了新的加载进度。

  (c)CustomAuthenticationProvider的bean定义中,属性userDetailsService是Spring Security的DaoAuthenticationProvider所须求的;属性userDetailsUpdater是自行加多的。二者都将本着同一个bean对象userDetailsService,该bean对象直接调用JdbcTemplate的办法垄断(monopoly卡塔尔数据库。

 

image

会获取csrf和cookie和所须要的值,那几个值都要保留下来,后边会用。

2、输入客户名密码后:

图片 8

image

图片 9

image

图片 10

image

图片 11

image

3、路由器再次来到数据

图片 12

image

密码的变通方法

从上面抓包的结果来看,Password字段是经过加密的,所以豆蔻梢头旦我们要Python暴力破解,须要把这几个password的变型算法找寻来。

开垦web登陆页面,查看源代码,找找算法

图片 13

image

图片 14

image

图片 15

image

图片 16

image

图片 17

image

在linux上改良ip地址,很简短一条命令就能够化解:

图片 18

image

[password:bbbbbbbb];{“errorCategory”:”user_pass_err”,”csrf_param”:”FcnG919l8J7XhQsOYQEMS3WhsC2liSX”,”count”:2,”csrf_token”:”IQ/LfSZSx7gTp6VflYnZelobNSpoMy2″}

ip地址被节制,需求等待1分钟的提示:

[password:aaaaaaaa];{“errorCategory”:”Three_time_err”,”csrf_param”:”VKGTylVILQA9SFsTyYdpkHv8qfJPIIw”,”count”:3,”csrf_token”:”MTQLBcWQN+1DJjAP+A6xC4AUSXciBod”}

报到成功的提醒:

****[password:xxxxxxxx];{“csrf_param”:”H/DyWxogz7+2y4UfzhqddowkjH1uL04″,”csrf_token”:”MorgBb0+PNpoE8KhwBwq4OoioD2NcCs”,”errorCategory”:”ok”,”level”:2,”IsWizard”:true,”IsFirst”:true}

流程

图片 19

image

具有的数目都考虑好了,下一步,正是发端利用Python写程序了。

核心Python代码:

图片 20

image

图片 21

image

图片 22

image

图片 23

image

图片 24

image

图片 25

image

图片 26

image

图片 27

image

图片 28

image

图片 29

image

图片 30

image

图片 31

image

图片 32

image

图片 33

image

图片 34

image

怎么防守暴力破解?

图片 35

image

图片 36

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图