{"id":13537368,"url":"https://github.com/david942j/one_gadget","last_synced_at":"2026-10-19T08:43:36.887Z","repository":{"id":38325500,"uuid":"81182710","full_name":"david942j/one_gadget","owner":"david942j","description":"The best tool for finding one gadget RCE in libc.so.6","archived":false,"fork":false,"pushed_at":"2026-10-07T07:56:02.000Z","size":24197,"stargazers_count":2359,"open_issues_count":0,"forks_count":151,"subscribers_count":17,"default_branch":"master","last_synced_at":"2026-10-11T19:55:10.680Z","etag":null,"topics":["ctf","exploit","gadget","glibc","libc","one-gadget-rce","pwn","pwnable","shell"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/david942j.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2017-02-07T08:03:34.000Z","updated_at":"2026-10-08T07:39:58.000Z","dependencies_parsed_at":"2026-09-29T03:25:57.273Z","dependency_job_id":null,"html_url":"https://github.com/david942j/one_gadget","commit_stats":{"total_commits":274,"total_committers":11,"mean_commits":24.90909090909091,"dds":0.3284671532846716,"last_synced_commit":"f640cd80b330953c9df25aa39d762e8873d81146"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/david942j/one_gadget","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Fone_gadget","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Fone_gadget/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Fone_gadget/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Fone_gadget/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/david942j","download_url":"https://codeload.github.com/david942j/one_gadget/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david942j%2Fone_gadget/sbom","scorecard":{"id":325973,"data":{"date":"2025-08-11","repo":{"name":"github.com/david942j/one_gadget","commit":"1a06fcf53bafc9e6a5b7b041865d78af25ac21d4"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/8 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":6,"reason":"8 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ruby.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Binary-Artifacts","score":0,"reason":"binaries present in source code","details":["Warn: binary detected: spec/data/aarch64-libc-2.23.so:1","Warn: binary detected: spec/data/aarch64-libc-2.24.so:1","Warn: binary detected: spec/data/aarch64-libc-2.27.so:1","Warn: binary detected: spec/data/filename$with+special\u0026keys:1","Warn: binary detected: spec/data/libc-2.19-cf699a15caae64f50311fc4655b86dc39a479789.so:1","Warn: binary detected: spec/data/libc-2.19-fd51b20e670e9a9f60dc3b06dc9761fb08c9358b.so:1","Warn: binary detected: spec/data/libc-2.23-60131540dadc6796cab33388349e6e4e68692053.so:1","Warn: binary detected: spec/data/libc-2.23-926eb99d49cab2e5622af38ab07395f5b32035e9.so:1","Warn: binary detected: spec/data/libc-2.24-8cba3297f538691eb1875be62986993c004f3f4d.so:1","Warn: binary detected: spec/data/libc-2.26-2104f3d4ad5cf68603afbe7ba1a17f5ac99c5988.so:1","Warn: binary detected: spec/data/libc-2.26-ddcc13122ddbfe5e5ef77d4ebe66d124ae5762c2.so:1","Warn: binary detected: spec/data/libc-2.26-f65648a832414f2144ce795d75b6045a1ec2e252.so:1","Warn: binary detected: spec/data/libc-2.27-63b3d43ad45e1b0f601848c65b067f9e9b40528b.so:1","Warn: binary detected: spec/data/libc-2.27-b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0.so:1","Warn: binary detected: spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so:1","Warn: binary detected: spec/data/test_near_file.elf:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ruby.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/david942j/one_gadget/ruby.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ruby.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/david942j/one_gadget/ruby.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ruby.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/david942j/one_gadget/ruby.yml/master?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T02:29:35.367Z","repository_id":38325500,"created_at":"2025-08-18T02:29:35.367Z","updated_at":"2025-08-18T02:29:35.367Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38352847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-19T02:00:06.414Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ctf","exploit","gadget","glibc","libc","one-gadget-rce","pwn","pwnable","shell"],"created_at":"2024-08-01T09:00:58.183Z","updated_at":"2026-10-19T08:43:36.872Z","avatar_url":"https://github.com/david942j.png","language":"Ruby","funding_links":[],"categories":["\u003ca id=\"9eee96404f868f372a6cbc6769ccb7f8\"\u003e\u003c/a\u003e新添加的","Exploits","Pentesting","shell","Exploiting / Pwn"],"sub_categories":["\u003ca id=\"31185b925d5152c7469b963809ceb22d\"\u003e\u003c/a\u003e新添加的","ShellCodes"],"readme":"[![Downloads](https://img.shields.io/gem/dt/one_gadget)](https://rubygems.org/gems/one_gadget)\n\n\n[![Gem Version](https://badge.fury.io/rb/one_gadget.svg)](https://badge.fury.io/rb/one_gadget)\n[![Build Status](https://github.com/david942j/one_gadget/workflows/build/badge.svg)](https://github.com/david942j/one_gadget/actions)\n[![Maintainability](https://qlty.sh/gh/david942j/projects/one_gadget/maintainability.svg)](https://qlty.sh/gh/david942j/projects/one_gadget)\n[![Code Coverage](https://qlty.sh/gh/david942j/projects/one_gadget/coverage.svg)](https://qlty.sh/gh/david942j/projects/one_gadget)\n[![API Docs](https://img.shields.io/badge/API-RubyDoc-blue.svg)](https://www.rubydoc.info/gems/one_gadget/)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/)\n\n## OneGadget\n\nWhen solving CTF pwn challenges we usually want a one-gadget RCE: a single address in\nlibc that, jumped to, calls `execve(\"/bin/sh\", NULL, NULL)`.\n\nThis gem finds them for you, so you don't have to dig through objdump or IDA Pro every\ntime :wink:\n\nPoint it at a libc -- `one_gadget /path/to/libc` -- and enjoy the magic :laughing:\n\n## Installation\n\nAvailable on RubyGems.org!\n```bash\n$ gem install one_gadget\n```\n\n## Supported Architectures\n\n- [x] i386\n- [x] amd64 (x86-64)\n- [x] aarch64 (ARMv8)\n- [x] arm (ARMv7, A32/Thumb-2)\n- [x] riscv64 (RV64GC)\n- [x] mips (MIPS32 o32, big- and little-endian)\n\n## Implementation\n\nOneGadget symbolically executes the code around each candidate address to work out what\nhas to hold for the gadget to work.\n\nGadgets are found by walking the control-flow graph backward from each `exec`/`posix_spawn`\ncall, following conditional branches both ways. When a gadget is only reachable if a branch is\n(not) taken, that decision shows up as an extra constraint, e.g. `x2 == 0x1`.\n\nThe article introducing how I develop this tool can be found [on my blog](https://david942j.blogspot.com/2017/02/project-one-gadget-in-glibc.html).\n\n### Checked by running them\n\nConstraints are only worth as much as they are complete, so the gadgets this repository\nships are verified by being run. [Aletheia](aletheia/README.md) loads the libc in a live\nprocess, arranges exactly what a gadget's constraints ask for, poisons every register and\npage they *don't* mention, jumps to the offset, and requires a real `/bin/sh` to come back\nand list the root directory. A gadget whose constraint list is missing something fails\nthere instead of passing by luck -- which is how several missing constraints were found.\n\n```bash\nbundle exec rake aletheia:verify                # every libc under spec/data, level 0\nbundle exec rake \"aletheia:verify[1, aarch64]\"  # one output level, one architecture\n```\n\nAletheia is development tooling: it lives outside `lib/` and `bin/`, so it is not part of\nthe published gem.\n\n## Usage\n\n### Command Line Interface\n\n```bash\n$ one_gadget\n# Usage: one_gadget \u003cFILE|-b BuildID\u003e [options]\n#     -b, --build-id BuildID           BuildID[sha1] of libc.\n#     -f, --[no-]force-file            Force search gadgets in file instead of build id first.\n#     -l, --level OUTPUT_LEVEL         The output level.\n#                                      OneGadget automatically selects gadgets with higher successful probability.\n#                                      Increase this level to ask OneGadget show more gadgets it found.\n#                                      Default: 0\n#     -n, --near FUNCTIONS/FILE        Order gadgets by their distance to the given functions or to the GOT functions of the given file.\n#     -o, --output-format FORMAT       Output format. FORMAT should be one of \u003cpretty|raw|json\u003e.\n#                                      Default: pretty\n#     -r, --raw                        Alias of -o raw. Output gadgets offset only, split with one space.\n#     -s, --script exploit-script      Run exploit script with all possible gadgets.\n#                                      The script will be run as 'exploit-script $offset'.\n#         --info BuildID               Show version information given BuildID.\n#         --base BASE_ADDRESS          The base address of libc.\n#                                      Default: 0\n#         --version                    Current gem version.\n\n```\n\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so\n# 0xe3b31 execve(\"/bin/sh\", r15, rdx)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3b34 execve(\"/bin/sh\", rsi, rdx)\n# constraints:\n#   [rsi] == NULL || rsi == NULL || rsi is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3c20 execve(\"/bin/sh\", r15, r12)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0x107cea posix_spawn(rsp+0x64, \"/bin/sh\", [rsp+0x38], 0, rsp+0x70, environ)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n#   [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] \u003c= 0x0\n\n```\n![x86_64](https://github.com/david942j/one_gadget/blob/master/examples/x86_64.png?raw=true)\n\n#### Given BuildID\n```bash\n$ one_gadget -b b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0\n# 0x4f322 execve(\"/bin/sh\", rsp+0x40, environ)\n# constraints:\n#   [rsp+0x40] == NULL || {[rsp+0x40], [rsp+0x48], [rsp+0x50], [rsp+0x58], ...} is a valid argv\n#\n# 0xe56d8 execve(\"/bin/sh\", r14, r12)\n# constraints:\n#   [r14] == NULL || r14 == NULL || r14 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe5863 execve(\"/bin/sh\", r10, rdx)\n# constraints:\n#   [r10] == NULL || r10 == NULL || r10 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0x10a38c execve(\"/bin/sh\", rsp+0x70, environ)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n\n```\n![build id](https://github.com/david942j/one_gadget/blob/master/examples/from_build_id.png?raw=true)\n\nThe gem carries the gadgets of the libcs most likely to be asked for -- the glibc of\nevery Ubuntu LTS still in standard support, and every libc the tests cover. Any other\nBuildID is fetched from this repository, which keeps them all.\n\n#### Gadgets Near Functions\n\n##### Why\n\nConsider this situation while exploiting:\n1. You can write to the GOT (Global Offset Table).\n2. The base address of libc is *unknown*.\n\nHere you can overwrite the low two bytes of a GOT entry with the low two bytes of a\none-gadget. If the function sits close enough to the gadget, only one nibble is left to\nguess -- at least a 1 in 16 chance of success.\n\n##### Usage\n\nSorts the gadgets by how far they are from the functions you name.\n\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near exit,mkdir\n# [OneGadget] Gadgets near exit(0x46a70):\n# 0xe3b31 execve(\"/bin/sh\", r15, rdx)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3b34 execve(\"/bin/sh\", rsi, rdx)\n# constraints:\n#   [rsi] == NULL || rsi == NULL || rsi is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3c20 execve(\"/bin/sh\", r15, r12)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0x107cea posix_spawn(rsp+0x64, \"/bin/sh\", [rsp+0x38], 0, rsp+0x70, environ)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n#   [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] \u003c= 0x0\n#\n# [OneGadget] Gadgets near mkdir(0x10dc80):\n# 0x107cea posix_spawn(rsp+0x64, \"/bin/sh\", [rsp+0x38], 0, rsp+0x70, environ)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n#   [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] \u003c= 0x0\n#\n# 0xe3c20 execve(\"/bin/sh\", r15, r12)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3b34 execve(\"/bin/sh\", rsi, rdx)\n# constraints:\n#   [rsi] == NULL || rsi == NULL || rsi is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3b31 execve(\"/bin/sh\", r15, rdx)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n\n```\n![near](https://github.com/david942j/one_gadget/blob/master/examples/near.png?raw=true)\n\nRegular expressions work too.\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near 'write.*' --raw\n# [OneGadget] Gadgets near writev(0x1144a0):\n# 1080554 932896 932660 932657\n#\n# [OneGadget] Gadgets near write(0x10e090):\n# 1080554 932896 932660 932657\n#\n\n```\n\nPass an ELF file instead, and OneGadget uses every function in its GOT.\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near spec/data/test_near_file.elf --raw\n# [OneGadget] Gadgets near exit(0x46a70):\n# 932657 932660 932896 1080554\n#\n# [OneGadget] Gadgets near puts(0x84450):\n# 932657 932660 932896 1080554\n#\n# [OneGadget] Gadgets near printf(0x61cc0):\n# 932657 932660 932896 1080554\n#\n# [OneGadget] Gadgets near strlen(0x9f660):\n# 932657 932660 932896 1080554\n#\n# [OneGadget] Gadgets near __cxa_finalize(0x46f40):\n# 932657 932660 932896 1080554\n#\n# [OneGadget] Gadgets near __libc_start_main(0x23fc0):\n# 932657 932660 932896 1080554\n#\n\n```\n\n#### Show More Gadgets\n\nA libc holds far more gadgets than fit on a screen, and most of them ask more of you\nthan a handful of others do. `--level` chooses how much of what was found to show.\n\n| Level | Shows | Use it when |\n| --- | --- | --- |\n| `0` (default) | the few gadgets whose constraints are easiest to arrange | always, first |\n| `1` | every gadget, one line per address, minus any that asks for everything an easier one asks for and more | none of the level-0 gadgets fit what you control |\n| `2` | everything found, including an address listed once per set of constraints it can be reached under | you want to see every way in, including the awkward ones |\n\nLevel 1 drops a gadget when an easier one already asks for everything it does; level 0\nthen scores what is left by how hard its constraints look and keeps only the best few;\nlevel 2 drops nothing. On the glibc 2.31 below that is 4, 32 and 97 entries -- the last\nover 96 addresses, since one of them is reachable two ways with different requirements.\n\nLevel 2 reads the libc you point at directly, where the levels below it answer from the\npre-built gadget database when it knows the file's BuildID -- the same gadgets either\nway. Pass `-f` to search the file at every level.\n\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --level 1\n# 0x51df8 posix_spawn(rsp+0xc, \"/bin/sh\", 0, rsp+0x210, rsp+0x50, environ)\n# constraints:\n#   readable: r12\n#   readable: r13\n#   rsp \u0026 0xf == 0x0\n#   {\"sh\", \"-c\", rbx, NULL} is a valid argv\n#   rsp+0x210 == NULL || (u16)[rsp+0x210] == 0x0\n#\n# 0x51e2b posix_spawn(rsp+0xc, \"/bin/sh\", 0, rbp, rsp+0x50, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   {\"sh\", \"-c\", rbx, NULL} is a valid argv\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e32 posix_spawn(rsp+0xc, \"/bin/sh\", 0, rbp, rsp+0x50, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rax == NULL || {\"sh\", rax, rbx, NULL} is a valid argv\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e39 posix_spawn(rsp+0xc, \"/bin/sh\", 0, rbp, rsp+0x50, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, rax, rbx, NULL} is a valid argv\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e40 posix_spawn(rsp+0xc, \"/bin/sh\", rdx, rbp, rsp+0x50, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, (u64)xmm1, rbx, NULL} is a valid argv\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e45 posix_spawn(rsp+0xc, \"/bin/sh\", rdx, rbp, rsp+0x50, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, rbx, NULL} is a valid argv\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e55 posix_spawn(rdi, \"/bin/sh\", rdx, rbp, rsp+0x50, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 \u003e\u003e 64), rbx, NULL} is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rdi == NULL || writable: rdi\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x51e5a posix_spawn(rdi, \"/bin/sh\", rdx, rbp, r8, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   [r8] == NULL || r8 is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rdi == NULL || writable: rdi\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rbp == NULL || (u16)[rbp] == 0x0\n#\n# 0x84165 posix_spawn(rbx+0xe0, \"/bin/sh\", r12, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   {\"sh\", \"-c\", rbp, NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   r12 == NULL || (s32)[r12+0x4] \u003c= 0x0\n#\n# 0x8416c posix_spawn(rbx+0xe0, \"/bin/sh\", r12, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rax == NULL || {\"sh\", rax, rbp, NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   r12 == NULL || (s32)[r12+0x4] \u003c= 0x0\n#\n# 0x84173 posix_spawn(rbx+0xe0, \"/bin/sh\", r12, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   r12 == NULL || (s32)[r12+0x4] \u003c= 0x0\n#\n# 0x84176 posix_spawn(rbx+0xe0, \"/bin/sh\", rdx, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x8417b posix_spawn(rbx+0xe0, \"/bin/sh\", rdx, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, rax, [rsp+0x70], NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x84180 posix_spawn(rbx+0xe0, \"/bin/sh\", rdx, 0, rsp+0x60, environ)\n# constraints:\n#   rsp \u0026 0xf == 0x0\n#   rcx == NULL || {rcx, (u64)xmm1, [rsp+0x70], NULL} is a valid argv\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x8418c posix_spawn(rbx+0xe0, \"/bin/sh\", rdx, 0, rsp+0x60, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, [rsp+0x70], NULL} is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x84192 posix_spawn(rbx+0xe0, \"/bin/sh\", rdx, rcx, rsp+0x60, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 \u003e\u003e 64), [rsp+0x70], NULL} is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rbx+0xe0 == NULL || writable: rbx+0xe0\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rcx == NULL || (u16)[rcx] == 0x0\n#\n# 0x84199 posix_spawn(rdi, \"/bin/sh\", rdx, rcx, rsp+0x60, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 \u003e\u003e 64), [rsp+0x70], NULL} is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rdi == NULL || writable: rdi\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rcx == NULL || (u16)[rcx] == 0x0\n#\n# 0x841a0 posix_spawn(rdi, \"/bin/sh\", rdx, rcx, r8, [rax])\n# constraints:\n#   readable: rax\n#   rsp \u0026 0xf == 0x0\n#   [r8] == NULL || r8 is a valid argv\n#   [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp\n#   rdi == NULL || writable: rdi\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#   rcx == NULL || (u16)[rcx] == 0x0\n#\n# 0xe3b31 execve(\"/bin/sh\", r15, rdx)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3b34 execve(\"/bin/sh\", rsi, rdx)\n# constraints:\n#   [rsi] == NULL || rsi == NULL || rsi is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3c20 execve(\"/bin/sh\", r15, r12)\n# constraints:\n#   [r15] == NULL || r15 == NULL || r15 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3d26 execve(\"/bin/sh\", r10, rdx)\n# constraints:\n#   address rbp-0x78 is writable\n#   [r10] == NULL || r10 == NULL || r10 is a valid argv\n#   [rdx] == NULL || rdx == NULL || rdx is a valid envp\n#\n# 0xe3d88 execve(\"/bin/sh\", [rbp-0x78], r12)\n# constraints:\n#   address rbp-0x78 is writable\n#   [[rbp-0x78]] == NULL || [rbp-0x78] == NULL || [rbp-0x78] is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3d90 execve(\"/bin/sh\", r10, r12)\n# constraints:\n#   address rbp-0x78 is writable\n#   [r10] == NULL || r10 == NULL || r10 is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3d92 execve(\"/bin/sh\", rbp-0x50, r12)\n# constraints:\n#   address rbp-0x50 is writable\n#   r13 == NULL || {\"/bin/sh\", r13, NULL} is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3d99 execve(\"/bin/sh\", rbp-0x50, r12)\n# constraints:\n#   address rbp-0x50 is writable\n#   rax == NULL || {rax, r13, NULL} is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3da0 execve(\"/bin/sh\", rbp-0x50, r12)\n# constraints:\n#   address rbp-0x50 is writable\n#   rax == NULL || {rax, [rbp-0x48], NULL} is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3dd7 execve(\"/bin/sh\", rbp-0x50, r12)\n# constraints:\n#   address rbp-0x78 is writable\n#   [rbp-0x68] == NULL || {\"/bin/sh\", [rbp-0x68], NULL} is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0xe3de1 execve(\"/bin/sh\", rbp-0x50, r12)\n# constraints:\n#   address rbp-0x78 is writable\n#   rax == NULL || {rax, [rbp-0x68], NULL} is a valid argv\n#   [r12] == NULL || r12 == NULL || r12 is a valid envp\n#\n# 0x1075e7 posix_spawn(rsp+0x64, \"/bin/sh\", rdx, 0, rsp+0x70, r9)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n#   [r9] == NULL || r9 == NULL || r9 is a valid envp\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x1075f1 posix_spawn(rdi, \"/bin/sh\", rdx, 0, r8, r9)\n# constraints:\n#   [r8] == NULL || r8 is a valid argv\n#   [r9] == NULL || r9 == NULL || r9 is a valid envp\n#   rdi == NULL || writable: rdi\n#   rdx == NULL || (s32)[rdx+0x4] \u003c= 0x0\n#\n# 0x107cea posix_spawn(rsp+0x64, \"/bin/sh\", [rsp+0x38], 0, rsp+0x70, environ)\n# constraints:\n#   [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv\n#   [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] \u003c= 0x0\n\n```\n\n#### Other Architectures\n\n##### i386\n```bash\n$ one_gadget spec/data/libc-2.27-63b3d43ad45e1b0f601848c65b067f9e9b40528b.so\n# 0x3cbf7 execve(\"/bin/sh\", esp+0x40, environ)\n# constraints:\n#   esi is the GOT address of libc\n#   [esp+0x40] == NULL || {[esp+0x40], [esp+0x44], [esp+0x48], [esp+0x4c], ...} is a valid argv\n#\n# 0x6729f execl(\"/bin/sh\", eax)\n# constraints:\n#   esi is the GOT address of libc\n#   eax == NULL\n#\n# 0x672a0 execl(\"/bin/sh\", [esp])\n# constraints:\n#   esi is the GOT address of libc\n#   [esp] == NULL\n#\n# 0x13573e execl(\"/bin/sh\", eax)\n# constraints:\n#   ebx is the GOT address of libc\n#   eax == NULL\n#\n# 0x13573f execl(\"/bin/sh\", [esp])\n# constraints:\n#   ebx is the GOT address of libc\n#   [esp] == NULL\n\n```\n![i386](https://github.com/david942j/one_gadget/blob/master/examples/i386.png?raw=true)\n\n##### AArch64\n```bash\n$ one_gadget spec/data/aarch64-libc-2.27.so\n# 0x3f160 execve(\"/bin/sh\", sp+0x70, environ)\n# constraints:\n#   address x20+0x338 is writable\n#   x22 == NULL\n#   x3 == NULL || {x3, \"-c\", x23, NULL} is a valid argv\n#\n# 0x63e90 execl(\"/bin/sh\", x1)\n# constraints:\n#   x1 == NULL\n#\n# 0xa321c execve(\"/bin/sh\", sp+0x40, x2)\n# constraints:\n#   [x1] == 0x0\n#   x0 == NULL || {\"/bin/sh\", x0, NULL} is a valid argv\n#   [x2] == NULL || x2 == NULL || x2 is a valid envp\n#\n# 0xa32e8 execve(\"/bin/sh\", x29+0x40, x23)\n# constraints:\n#   address x29+0x40 is writable\n#   x0 == NULL || {\"/bin/sh\", x0, NULL} is a valid argv\n#   [x23] == NULL || x23 == NULL || x23 is a valid envp\n\n```\n![aarch64](https://github.com/david942j/one_gadget/blob/master/examples/aarch64.png?raw=true)\n\n##### ARM32\n\n```bash\n$ one_gadget spec/data/arm-libc-2.39.so\n# 0x38f6c posix_spawn(r0, \"/bin/sh\", r2, r8, [sp], r3)\n# constraints:\n#   [[sp]] == NULL || [sp] is a valid argv\n#   [r3] == NULL || r3 == NULL || r3 is a valid envp\n#   r0 == NULL || writable: r0\n#   r2 == NULL || (s32)[r2+0x4] \u003c= 0x0\n#   r8 == NULL || (u16)[r8] == 0x0\n#\n# 0x88a7c execve(\"/bin/sh\", r4, r5)\n# constraints:\n#   [r4] == NULL || r4 == NULL || r4 is a valid argv\n#   [r5] == NULL || r5 == NULL || r5 is a valid envp\n#\n# 0x9f2be posix_spawn([sp+0x34], \"/bin/sh\", [sp+0x2c], 0, [sp+0x3c], r3)\n# constraints:\n#   [[sp+0x3c]] == NULL || [sp+0x3c] is a valid argv\n#   [r3] == NULL || r3 == NULL || r3 is a valid envp\n#   [sp+0x34] == NULL || writable: [sp+0x34]\n#   [sp+0x2c] == NULL || (s32)[[sp+0x2c]+0x4] \u003c= 0x0\n\n```\n\n##### RISC-V (RV64)\n\n```bash\n$ one_gadget spec/data/riscv64-libc-2.39.so\n# 0x9f73a execve(\"/bin/sh\", s1, a2)\n# constraints:\n#   [s1] == NULL || s1 == NULL || s1 is a valid argv\n#   [a2] == NULL || a2 == NULL || a2 is a valid envp\n#\n# 0x9f73c execve(\"/bin/sh\", a1, a2)\n# constraints:\n#   [a1] == NULL || a1 == NULL || a1 is a valid argv\n#   [a2] == NULL || a2 == NULL || a2 is a valid envp\n#\n# 0x9f778 execve(\"/bin/sh\", s1, s2)\n# constraints:\n#   [s1] == NULL || s1 == NULL || s1 is a valid argv\n#   [s2] == NULL || s2 == NULL || s2 is a valid envp\n#\n# 0xb5adc posix_spawn(sp+0x44, \"/bin/sh\", [sp+0x30], 0, sp+0x50, environ)\n# constraints:\n#   [sp+0x50] == NULL || {[sp+0x50], [sp+0x58], [sp+0x60], [sp+0x68], ...} is a valid argv\n#   [sp+0x30] == NULL || (s32)[[sp+0x30]+0x4] \u003c= 0x0\n\n```\n\n##### MIPS\n\nBig-endian is as common as little-endian here, and both are read. This one is\nOpenWrt's musl for ath79, which ships with no section headers -- the shape a\nrouter's libc usually arrives in.\n\n```bash\n$ one_gadget spec/data/mips-musl-1.2.4.so\n# 0x668e8 posix_spawn(sp+0x20, \"/bin/sh\", 0, s0, sp+0x28, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   {\"sh\", \"-c\", s1, NULL} is a valid argv\n#   s0 == NULL || (u16)[s0] == 0x0\n#\n# 0x668ec posix_spawn(sp+0x20, \"/bin/sh\", 0, s0, sp+0x28, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   {\"sh\", \"-c\", [sp+0x30], NULL} is a valid argv\n#   s0 == NULL || (u16)[s0] == 0x0\n#\n# 0x668f0 posix_spawn(sp+0x20, \"/bin/sh\", 0, a3, sp+0x28, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   {\"sh\", \"-c\", [sp+0x30], NULL} is a valid argv\n#   a3 == NULL || (u16)[a3] == 0x0\n#\n# 0x668f4 posix_spawn(sp+0x20, \"/bin/sh\", 0, a3, sp+0x28, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   v0-0x7c70 == NULL || {v0-0x7c70, \"-c\", [sp+0x30], NULL} is a valid argv\n#   a3 == NULL || (u16)[a3] == 0x0\n#\n# 0x77b44 posix_spawn(sp+0x20, \"/bin/sh\", s2, 0, sp+0x2c, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   {\"sh\", \"-c\", s7, NULL} is a valid argv\n#   s2 == NULL || (s32)[s2+0x4] \u003c= 0x0\n#\n# 0x77b48 posix_spawn(sp+0x20, \"/bin/sh\", s2, 0, sp+0x2c, environ)\n# constraints:\n#   gp is the GOT address of libc\n#   v0-0x7c70 == NULL || {v0-0x7c70, \"-c\", s7, NULL} is a valid argv\n#   s2 == NULL || (s32)[s2+0x4] \u003c= 0x0\n\n```\n\n#### Combine with Script\nPass your exploit script to `one_gadget` and it runs the script once per gadget, so you\ndon't have to work through them by hand.\n\n```bash\n$ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so -s 'echo \"offset -\u003e\"'\n```\n\n![--script](https://github.com/david942j/one_gadget/blob/master/examples/script.png?raw=true)\n\n### In Ruby Scripts\n```ruby\nrequire 'one_gadget'\nOneGadget.gadgets(file: 'spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so')\n#=\u003e [932657, 932660, 932896, 1080554]\n\n# or, more briefly\none_gadget('spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so', level: 1)\n#=\u003e [335352, 335403, 335410, 335417, 335424, 335429, 335445, 335450, 541029, 541036, 541043, 541046, 541051, 541056, 541068, 541074, 541081, 541088, 932657, 932660, 932896, 933158, 933256, 933264, 933266, 933273, 933280, 933335, 933345, 1078759, 1078769, 1080554]\n\n# from build id\none_gadget('b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0')\n#=\u003e [324386, 939736, 940131, 1090444]\n\n```\n\n### To Python Lovers\n```python\nimport subprocess\ndef one_gadget(filename):\n  return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')]\n\none_gadget('spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so')\n#=\u003e [932657, 932660, 932896, 1080554]\n\n```\n\n## Make OneGadget Better\nAny suggestion or feature request is welcome, and pull requests even more so!\n\nPlease let me know if you come across a libc OneGadget finds nothing in. And if you like\nthis work, I'd be happy to be [starred](https://github.com/david942j/one_gadget/stargazers) :grimacing:\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid942j%2Fone_gadget","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavid942j%2Fone_gadget","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid942j%2Fone_gadget/lists"}