{"id":16571509,"url":"https://github.com/hrbrmstr/rdaradar","last_synced_at":"2025-03-16T20:31:12.762Z","repository":{"id":237523429,"uuid":"794632937","full_name":"hrbrmstr/rdaradar","owner":"hrbrmstr","description":"☢️ Safety Radar for RDA Files","archived":false,"fork":false,"pushed_at":"2024-05-03T09:46:17.000Z","size":19,"stargazers_count":46,"open_issues_count":4,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-16T05:31:41.237Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hrbrmstr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-01T16:21:07.000Z","updated_at":"2025-02-28T19:06:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"dc644c77-db6b-4100-8079-3e2d584a22c3","html_url":"https://github.com/hrbrmstr/rdaradar","commit_stats":null,"previous_names":["hrbrmstr/rdaradar"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Frdaradar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Frdaradar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Frdaradar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hrbrmstr%2Frdaradar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hrbrmstr","download_url":"https://codeload.github.com/hrbrmstr/rdaradar/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243928314,"owners_count":20370268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T21:24:13.648Z","updated_at":"2025-03-16T20:31:12.472Z","avatar_url":"https://github.com/hrbrmstr.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n# rdaradar (RDA Radar)\n\nSanity check R data files before use.\n\n## Why?\n\n“Researchers” from HiddenLayer took advantage of the hype cycle before\nRSAC 2024 to [broadcast a non-vulnerability in\nR](https://hiddenlayer.com/research/r-bitrary-code-execution/).\n\nThey (IMO) inappropriately received a CVE assignment (CVE-2024-27322)\nfor, what is, expected behavior in the deserialization of R objects via\nstandard mechanisms. I am not shocked as I am also of the opinion\nthat the current state of “CVE” in general is “busted”.\n\nThere is no mention of this CVE in the release of R 4.4.0 which *did*\nmodify the behavior of deserializing certain objects within R data\nfiles. I am going to make an assumption the change was made because of\nthis CVE.\n\nHowever, the “weakness” is by no means closed.\n\n[Konrad Rudolph](https://mastodon.social/@klmr#.) and [Iakov\nDavydov](https://mstdn.science/@idavydov) did some ace cyber sleuthing\nand [figured out other ways R data file deserialization can be\nabused](https://mastodon.social/@klmr/112360501388055184). Please take a\nmoment and drop a note on Mastodon to them saying “thank you”. This is\nexcellent work. We need more folks like them in this ecosystem.\n\n\u003e Please note that *this is all expected behavior*. R has many\n\u003e “defaults” that can get one into trouble. Seven years ago I [made this\n\u003e example repo/package](https://github.com/hrbrmstr/rpwnd/) to\n\u003e demonstrate some of the more overt “gotchas” that can lead to\n\u003e potential unwanted behavior. Back in 2019, the fine folks at rOpenSci\n\u003e [also let us poke at making R a bit\n\u003e safer](https://ropensci.org/blog/2019/04/09/commcall-may2019/#resources).\n\nI’m including one of their sample “calc” exploit payloads since hiding\nit really doesn’t do much to determined attackers.\n\nWhen you `load()` an R data file directly into your R session into the\nglobal environment, the object will, well, *load there*. So, if it has\nan object named `print` that’s going to be in your global environment\nand get called when `print()` gets called. Lather/rinse/repeat for any\nother object name. It should be pretty obvious how this could be abused.\n\nA tad more insidious is what happens when you quit R. By default, on\n`quit()`, unless you specify otherwise, that function invocation will\nalso call `.Last()` if it exists in the environment. This functionality\nexists in the event things need to be cleaned up. One “nice” aspect of\n`.`-prefixed R objects is that they’re hidden by default from the\nenvironment. So, you may not even notice if an R data file you’ve loaded\nhas that defined. (You likely do not check what’s loaded anyway.)\n\nIt’s also possible to create custom R objects that have their own\n“finalizers” (ref `reg.finalizer`), which will also get called by\ndefault when the objects are being destroyed on quit.\n\nThere are also likely other ways to trigger unwanted behavior.\n\nIf you want to see how this works, start R from RStudio, the command\nline, or R GUI. Then, load `exploit.rda`. Then, quit R/RStudio/R GUI\n(this will be less dramatic on linux, but the demo should still be\neffective).\n\nThe main takeaway from this is DO NOT LOAD ANY R DATA FILES YOU DID NOT\nCREATE OR TRUST THE PROVENANCE OF.\n\nIf you *must* take in untrusted R data files, keep reading.\n\n## What (Does This Do)?\n\nYou can either run the `check.R` script directly or via the Docker\ncontainer version of it. It will load the specified R data file into a\n“quarantined” environment, then list out the objects in the environment,\ncompare them to known, potentially dangerous ones, and also print out\nthe contents of any functions defined.\n\nIt will exit with a status code of `1` if anything dangerous is found.\n\nIt’s a work-in-progress (I’m really short on time this week), and filing\nissues with suggestions for improvement (then, PRs) would be most\nwelcome.\n\n## Usage: Bare Script (POTENTIALLY DANGEROUS)\n\n``` bash\n$ Rscript check.R /path/to/RDATAFILE\n```\n\nExample output for the `exploit.rda` file:\n\n    -----------------------------------------------\n    Loading R data file in quarantined environment…\n    -----------------------------------------------\n\n    Loading objects:\n      .Last\n      quit\n\n    -----------------------------------------\n    Enumerating objects in loaded R data file\n    -----------------------------------------\n\n    .Last : function (...)  \n     - attr(*, \"srcref\")= 'srcref' int [1:8] 1 13 6 1 13 1 1 6\n      ..- attr(*, \"srcfile\")=Classes 'srcfilecopy', 'srcfile' \u003cenvironment: 0x12cb25f48\u003e \n    quit : function (...)  \n     - attr(*, \"srcref\")= 'srcref' int [1:8] 1 13 6 1 13 1 1 6\n      ..- attr(*, \"srcfile\")=Classes 'srcfilecopy', 'srcfile' \u003cenvironment: 0x12cb25f48\u003e \n\n    ------------------------------------\n    Functions found: enumerating sources\n    ------------------------------------\n\n    Checking `.Last`…\n\n    !! `.Last` may execute arbitrary code on your system under certain conditions !!\n\n    `.Last` source:\n    {\n        cmd = if (.Platform$OS.type == \"windows\") \n            \"calc.exe\"\n        else if (grepl(\"^darwin\", version$os)) \n            \"open -a Calculator.app\"\n        else \"echo pwned\\\\!\"\n        system(cmd)\n    }\n\n\n    Checking `quit`…\n\n    !! `quit` may execute arbitrary code on your system under certain conditions !!\n\n    `quit` source:\n    {\n        cmd = if (.Platform$OS.type == \"windows\") \n            \"calc.exe\"\n        else if (grepl(\"^darwin\", version$os)) \n            \"open -a Calculator.app\"\n        else \"echo pwned\\\\!\"\n        system(cmd)\n    }\n\nWhile this should theoretically be “safe”, it is much safer to run this\nin a Docker container.\n\n## Usage: Docker\n\nBuild:\n\n``` bash\n$ docker build -t rdaradar:0.1.0 -t rdaradar:latest .  \n```\n\nRun:\n\n``` bash\n$ docker run --rm -v \"$(pwd)/exploit.rda:/unsafe.rda\" rdaradar \n```\n\nExample output for the `exploit.rda` file:\n\n    -----------------------------------------------\n    Loading R data file in quarantined environment…\n    -----------------------------------------------\n\n    Loading objects:\n      .Last\n      quit\n\n    -----------------------------------------\n    Enumerating objects in loaded R data file\n    -----------------------------------------\n\n    .Last : function (...)  \n     - attr(*, \"srcref\")= 'srcref' int [1:8] 1 13 6 1 13 1 1 6\n      ..- attr(*, \"srcfile\")=Classes 'srcfilecopy', 'srcfile' \u003cenvironment: 0xaaaac3a30568\u003e \n    quit : function (...)  \n     - attr(*, \"srcref\")= 'srcref' int [1:8] 1 13 6 1 13 1 1 6\n      ..- attr(*, \"srcfile\")=Classes 'srcfilecopy', 'srcfile' \u003cenvironment: 0xaaaac3a30568\u003e \n\n    ------------------------------------\n    Functions found: enumerating sources\n    ------------------------------------\n\n    Checking `.Last`…\n\n    !! `.Last` may execute arbitrary code on your system under certain conditions !!\n\n    `.Last` source:\n    {\n        cmd = if (.Platform$OS.type == \"windows\") \n            \"calc.exe\"\n        else if (grepl(\"^darwin\", version$os)) \n            \"open -a Calculator.app\"\n        else \"echo pwned\\\\!\"\n        system(cmd)\n    }\n\n\n    Checking `quit`…\n\n    !! `quit` may execute arbitrary code on your system under certain conditions !!\n\n    `quit` source:\n    {\n        cmd = if (.Platform$OS.type == \"windows\") \n            \"calc.exe\"\n        else if (grepl(\"^darwin\", version$os)) \n            \"open -a Calculator.app\"\n        else \"echo pwned\\\\!\"\n        system(cmd)\n    }\n\n## TODO\n\n- [ ] Better write-up\n- [ ] More checks\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhrbrmstr%2Frdaradar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhrbrmstr%2Frdaradar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhrbrmstr%2Frdaradar/lists"}