过完年的首发,就来个小洞吧!
审计过程
找回密码步骤1:根据验证码与用户名查询是否存在邮箱与手机号
com.seeyon.v3x.personalaffair.controller.PersonalBindController#getBindTypeByLoginName
public void getBindTypeByLoginName(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, String> content = new HashMap();
HttpSession session = request.getSession(false);
if (session == null && !SystemEnvironment.isSuitDeployMode()) {
session = request.getSession(true);
}
session.removeAttribute("loginName");
String memberIsExist = "false";
String loginName = request.getParameter("loginName");
String bindemailEnable = "false";
String email = "";
String bindphonenumberEnable = "false";
String telNumber = "";
String pwd_strong_require = this.systemConfig.get("pwd_strong_require");
String pwd_strength_validation_enable = this.systemConfig.get("pwd_strength_validation_enable");
boolean imgCodeEquals = false;
if (SystemEnvironment.isSuitDeployMode()) { //检查验证码
String page_code = request.getParameter("img_verifyCode");
content.put("img_verifyCode", page_code);
VerifyCodeUtil.checkAndrefreshVerifyCode();
String img_verifyCodeObj = (String)session.getAttribute("login.VerifyCode");
if (!Strings.isEmpty(page_code) && !Strings.isEmpty(img_verifyCodeObj)) {
imgCodeEquals = Strings.equals(page_code, img_verifyCodeObj);
session.removeAttribute("login.VerifyCode");
}
} else {
imgCodeEquals = true;
}
if (imgCodeEquals) {
if (AppContext.hasPlugin("ldap")) {
loginName = this.ldapBindingMgr.getLoginName(loginName);
}
V3xOrgMember member = this.orgManager.getMemberByLoginName(loginName);
if (member != null) { //查询手机号邮箱
memberIsExist = "true";
Long memberId = member.getId();
boolean smsSetEnable = this.cloudMobileManager.isAccountOfCanUseSMS(member.getOrgAccountId());
String bind_phonenumber = this.customizeManager.getCustomizeValue(memberId, "bind_phonenumber");
bindphonenumberEnable = bind_phonenumber == null ? "" : bind_phonenumber;
bindphonenumberEnable = Strings.equals(bindphonenumberEnable, "true") ? String.valueOf(smsSetEnable) : "false";
telNumber = member.getTelNumber();
boolean emailSetEnable = this.cloudMailManager.isCanUseMail();
String bind_email = this.customizeManager.getCustomizeValue(memberId, "bind_email");
bindemailEnable = bind_email == null ? "" : bind_email;
bindemailEnable = Strings.equals(bindemailEnable, "true") ? String.valueOf(emailSetEnable) : "false";
email = member.getEmailAddress();
}
}
session.setAttribute("seeyon_find_pwd_count", imgCodeEquals ? 1 : 0); //验证码验证成功之后会在session中设置找回密码步骤1
content.put("memberIsExist", memberIsExist);
content.put("bindphonenumberEnable", bindphonenumberEnable);
content.put("telNumber", this.formartNum(telNumber));
content.put("bindemailEnable", bindemailEnable);
content.put("email", this.formartEmail(email));
content.put("pwd_strong_require", pwd_strong_require);
content.put("pwd_strength_validation_enable", pwd_strength_validation_enable);
content.put("imgCodeEquals", String.valueOf(imgCodeEquals));
session.setAttribute("loginName", Strings.toHTML(loginName)); //设置用户名
super.rendText(response, JSONUtil.toJSONString(content));
}
此时:
session.setAttribute("seeyon_find_pwd_count", 1);
session.setAttribute("loginName", "admin");
找回验证码第二步:
com.seeyon.v3x.personalaffair.controller.PersonalBindController#sendVerificationCodeToBindNum
public void sendVerificationCodeToBindNum(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession(false);
if (!isPass(session, 1)) { //判断session中seeyon_find_pwd_count是否有值
this.logger.error("非法操作!");
super.rendText(response, JSONUtil.toJSONString(false));
} else {
session.removeAttribute("validateTimes");
session.removeAttribute("verificationCode");
Map<String, String> content = new HashMap();
content.put("verifyImageCodeEquals", "true");
session.setAttribute("seeyon_find_pwd_count", 2); //设置此时找回验证码进度为2
this.validateSendTimes(session);
String type = request.getParameter("type");
String verificationCode;
String sendcontent;
if ("bind".equals(type)) {
verificationCode = request.getParameter("verifyImageCode");
VerifyCodeUtil.checkAndrefreshVerifyCode();
sendcontent = (String)AppContext.getSessionContext("login.VerifyCode");
if (!Strings.equals(verificationCode, sendcontent)) {
content.put("verifyImageCodeEquals", "false");
session.setAttribute("seeyon_find_pwd_count", 1);
super.rendText(response, JSONUtil.toJSONString(content));
AppContext.removeSessionArrribute("login.VerifyCode");
return;
}
AppContext.removeSessionArrribute("login.VerifyCode");
}
verificationCode = this.getVerificationCode(6);
sendcontent = verificationCode;
String accountName = "";
if ("true".equals(SystemProperties.getInstance().getProperty("org.isGroupVer"))) {
accountName = this.orgManager.getUnitById(OrgConstants.GROUPID).getShortName();
} else {
accountName = this.orgManager.getUnitById(OrgConstants.ACCOUNTID).getShortName();
}
String telNumber = "";
String loginName = "";
V3xOrgMember member = null;
PhoneLoginHelper template = PhoneLoginHelper.PCUPDATE;
if ("bind".equals(type)) {
member = this.orgManager.getMemberById(AppContext.currentUserId());
if (null != member) {
telNumber = member.getTelNumber();
}
telNumber = request.getParameter("telNumber");
if (SystemEnvironment.isSuitDeployMode()) {
sendcontent = "[" + accountName + "]" + ResourceUtil.getString("common.person.bind.sms.content", verificationCode);
}
} else if ("validate".equals(type)) { //如果设置type=validate
loginName = (String)session.getAttribute("loginName"); //从session中取出loginName
member = this.orgManager.getMemberByLoginName(loginName);
if (null != member) {
telNumber = member.getTelNumber();
}
if (SystemEnvironment.isSuitDeployMode()) {
sendcontent = "[" + accountName + "]" + ResourceUtil.getString("common.person.retrieve.content", verificationCode);
}
String origin = request.getParameter("origin");
if (Strings.isNotBlank(origin) && "zx".equals(origin)) { //如果origin=zx 会设置session中canModify为true
AppContext.putSessionContext("canModify", "true");
template = PhoneLoginHelper.UCUPDATE;
}
}
if ("validate".equals(type)) {
try {
Result result = this.loginSmsManager.sendSMSLoginCode(telNumber, template.getText());
if (result.isSuccess()) {
content.put("verifyImageCodeEquals", "true");
AppContext.putSessionContext("findPasswordForNew", telNumber);
} else {
content.put("verifyImageCodeEquals", "false");
if (result != null && 6028 == result.getCode()) {
content.put("messageCode", String.valueOf(result.getCode()));
}
}
} catch (Exception var16) {
content.put("verifyImageCodeEquals", "false");
}
super.rendText(response, JSONUtil.toJSONString(content));
} else {
try {
Long senderId = OrgConstants.SYSTEM_ADMIN_ID;
if (member != null) {
this.cloudMobileManager.sendMessage(sendcontent, senderId, new Date(), telNumber, member.getId());
AppContext.putSessionContext("bindTelNumber", telNumber);
}
AppContext.putSessionContext("verificationCode", verificationCode);
String startDate = String.valueOf((new Date()).getTime());
AppContext.putSessionContext("startDate", startDate);
AppContext.putSessionContext("validateTimes", 0);
} catch (Exception var15) {
this.logger.error("", var15);
}
super.rendText(response, JSONUtil.toJSONString(content));
}
}
}
此时
session.setAttribute("seeyon_find_pwd_count", 2);
AppContext.putSessionContext("canModify", "true");
修改密码第三步:
com.seeyon.v3x.personalaffair.controller.IndividualManagerController#resetPassword
public void resetPassword(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession(false);
Object loginName = session.getAttribute("loginName"); //已在第一步设置
Object canModify = session.getAttribute("canModify"); //已在第二步设置
if (null != loginName && "true".equals(canModify) && PersonalBindController.isPass(session, 3)) { //isPass并未验证是否等于3,而是仅仅验证能否取出seeyon_find_pwd_count,并返回true
session.removeAttribute("seeyon_find_pwd_count");
PrincipalManager principalManager = (PrincipalManager)AppContext.getBean("principalManager");
String password = request.getParameter("nowpwd"); //新密码
try {
V3xOrgMember member = this.orgManager.getMemberByLoginName((String)loginName);
if (member == null) {
logger.error("Member not exist!");
super.rendText(response, JSONUtil.toJSONString(false));
return;
}
//下面是更新操作
V3xOrgMember memberBeforeUpdate = new V3xOrgMember();
V3xOrgMember newMember = new V3xOrgMember();
BeanUtils.copyProperties(memberBeforeUpdate, member);
V3xOrgPrincipal newOrgPrincipal = new V3xOrgPrincipal(member.getId(), member.getLoginName(), password);
member.setV3xOrgPrincipal(newOrgPrincipal);
BeanUtils.copyProperties(newMember, member);
OrganizationMessage om = principalManager.update(newOrgPrincipal);
if (Strings.isNotEmpty(om.getErrorMsgs())) {
OrgHelper.throwBusinessExceptionTools(om);
}
if (LdapUtils.isLdapEnabled() && LdapUtils.isBind(member.getId())) {
LDAPConfig config = LDAPConfig.getInstance();
String type = config.getSys().getProperty("ldap.ad.enabled");
if ("ad".equals(type) && config.getIsEnableSSL() || "ldap".equals(type)) {
OrganizationLdapEvent event = (OrganizationLdapEvent)AppContext.getBean("organizationLdapEvent");
event.changePassword(memberBeforeUpdate, newMember);
}
}
ChangePwdEvent event = new ChangePwdEvent(this);
event.setMember(member);
EventDispatcher.fireEvent(event);
session.removeAttribute("loginName");
session.removeAttribute("canModify");
} catch (Exception var16) {
logger.error("", var16);
super.rendText(response, JSONUtil.toJSONString(false));
return;
}
super.rendText(response, JSONUtil.toJSONString(true));
} else {
logger.error("非法操作!");
super.rendText(response, JSONUtil.toJSONString(false));
}
}
//isPass 代码
public static boolean isPass(HttpSession session, int expectValue) {
Object val = session.getAttribute("seeyon_find_pwd_count");
return true;
}
仅供安全研究与学习之用,如用于其他用途,由使用者承担全部法律及连带责任,与本公众号无关。
具体利用过程会在知识星球
原文始发于微信公众号(摸鱼Sec):致xOA任意用户密码重置(非公开)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论