one_gadget 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +215 -65
  3. data/README.md +96 -22
  4. data/lib/one_gadget/abi.rb +41 -5
  5. data/lib/one_gadget/builds/libc-2.31-93b46e0027747153e336c3fd9431ce9a5d82ad00.rb +563 -0
  6. data/lib/one_gadget/builds/libc-2.35-891c1403437a4e30e684e0c8e34b87a09e4298e5.rb +434 -0
  7. data/lib/one_gadget/builds/libc-2.39-a1d1cf4badf1f5dfe57ff1d17bd692ccc6fcd5c5.rb +531 -0
  8. data/lib/one_gadget/builds/libc-2.39-cd8f5a207dd67aea370d2b471a54c3e56f44ab18.rb +531 -0
  9. data/lib/one_gadget/builds/libc-2.43-b50ceafbd17dc6bceee344a66671c7eaa152bef4.rb +15 -0
  10. data/lib/one_gadget/emulators/aarch64.rb +5 -2
  11. data/lib/one_gadget/emulators/amd64.rb +1 -0
  12. data/lib/one_gadget/emulators/arm.rb +27 -18
  13. data/lib/one_gadget/emulators/arm_family.rb +35 -160
  14. data/lib/one_gadget/emulators/conditional.rb +28 -22
  15. data/lib/one_gadget/emulators/constraints.rb +269 -0
  16. data/lib/one_gadget/emulators/data_processing.rb +167 -0
  17. data/lib/one_gadget/emulators/i386.rb +4 -6
  18. data/lib/one_gadget/emulators/instruction.rb +24 -1
  19. data/lib/one_gadget/emulators/lambda.rb +6 -4
  20. data/lib/one_gadget/emulators/mips.rb +289 -0
  21. data/lib/one_gadget/emulators/processor.rb +33 -455
  22. data/lib/one_gadget/emulators/register_file.rb +19 -10
  23. data/lib/one_gadget/emulators/riscv64.rb +265 -0
  24. data/lib/one_gadget/emulators/safe_calls.rb +9 -3
  25. data/lib/one_gadget/emulators/tracked_memory.rb +209 -0
  26. data/lib/one_gadget/emulators/x86.rb +32 -22
  27. data/lib/one_gadget/fetchers/aarch64.rb +0 -27
  28. data/lib/one_gadget/fetchers/amd64.rb +0 -24
  29. data/lib/one_gadget/fetchers/argument_resolution.rb +340 -0
  30. data/lib/one_gadget/fetchers/arm.rb +99 -44
  31. data/lib/one_gadget/fetchers/base.rb +142 -640
  32. data/lib/one_gadget/fetchers/candidate_walk.rb +150 -0
  33. data/lib/one_gadget/fetchers/disassembly.rb +252 -0
  34. data/lib/one_gadget/fetchers/dynamic_symbols.rb +104 -0
  35. data/lib/one_gadget/fetchers/i386.rb +5 -8
  36. data/lib/one_gadget/fetchers/mips.rb +478 -0
  37. data/lib/one_gadget/fetchers/objdump.rb +25 -3
  38. data/lib/one_gadget/fetchers/riscv64.rb +78 -0
  39. data/lib/one_gadget/fetchers/x86.rb +19 -0
  40. data/lib/one_gadget/fetchers.rb +22 -6
  41. data/lib/one_gadget/gadget.rb +27 -37
  42. data/lib/one_gadget/helper.rb +19 -5
  43. data/lib/one_gadget/one_gadget.rb +6 -0
  44. data/lib/one_gadget/version.rb +1 -1
  45. data/lib/one_gadget.rb +1 -1
  46. metadata +18 -6
  47. data/lib/one_gadget/builds/libc-2.26-2104f3d4ad5cf68603afbe7ba1a17f5ac99c5988.rb +0 -227
  48. data/lib/one_gadget/builds/libc-2.26-ddcc13122ddbfe5e5ef77d4ebe66d124ae5762c2.rb +0 -300
  49. data/lib/one_gadget/builds/libc-2.26-f65648a832414f2144ce795d75b6045a1ec2e252.rb +0 -199
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cce7f8fbd56224d205d4dc7fdd08f8d642ff586da671574ae44f29f4c1fd63d3
4
- data.tar.gz: edb152ef2e3a2cad812a4eb2561854552a40e826ceb770d5aa04d7003d2e20d6
3
+ metadata.gz: 5ca49762b99002c30608cd2fd4943d32ba487ce0f404352958676484b44d6b29
4
+ data.tar.gz: f40ade7e7c295261394bb5d820918bbdb719e1eb64a20441e4cb5d884fc5f5b5
5
5
  SHA512:
6
- metadata.gz: 10ec07de38a263a7ff7035e6ec97d47b111a12e344d54fef3fa8aa0f41d3cff29e59d688a180e97a1b10eb5f610d24d51a889967299445134785ec631d7274c5
7
- data.tar.gz: 0adecd70607f6054831c155c3ac7f64e19a97db8a772f8265cb0d35b0bedc620d9fb8c5371ceaf5c6f804249c2381ca7dac74eaf6aa5f29f661266fc548d319e
6
+ metadata.gz: b92c28c40e01b38fd3475eba6d1e43f1506ce9f7c6b3bfe43d05e364a9b79c824f8bd943922285dab63587311d234345d545667898bed10778079d1e84c7f739
7
+ data.tar.gz: 1588172eed225a3d5c6e49081134d07b8f46f991321fdb53776ca432c12a28fd760bd65b6ba75c06d6ea110cd2ad48607999934eca1b9740cbcabe1055b18dc4
data/CHANGELOG.md CHANGED
@@ -7,6 +7,75 @@ Notable changes to one_gadget, newest first. The format follows
7
7
  A change worth a user's attention lands with its entry under *Unreleased*;
8
8
  releases are cut by giving that section a version and a date.
9
9
 
10
+ ## v2.1.1 - 2026-09-05
11
+
12
+ ### Changed
13
+
14
+ - The pre-generated gadgets for the libcs the gem does not ship were rebuilt
15
+ ([#468]) -- all 883 entries are now current. They dated from 2023 and predate a
16
+ year of emulator work, so a BuildID lookup could report gadgets that no longer
17
+ work and miss ones that do: 10,326 recorded gadgets became 43,410.
18
+
19
+ ### Fixed
20
+
21
+ - Looking up a BuildID the gem does not ship no longer advises updating the gem
22
+ ([#467]). The gem carries 34 of 883 builds by design, so that advice reached
23
+ almost every remote lookup, and updating would not have added them. It now says
24
+ the build is being fetched.
25
+
26
+ ## v2.1.0 - 2026-09-05
27
+
28
+ Two more architectures, and a libc that ships without section headers -- as an
29
+ embedded one usually does -- can now be searched at all.
30
+
31
+ ### Added
32
+
33
+ - RISC-V (RV64) support, alongside i386, amd64, aarch64 and arm ([#420], [#421],
34
+ [#422], [#423], [#425]). Every gadget it reports has been run under a debugger and
35
+ seen to spawn a shell ([#424]).
36
+ - MIPS (32-bit o32) support, in both byte orders ([#448]), verified the same way.
37
+ - Reads a libc that ships without section headers, as OpenWrt's musl does
38
+ ([#432]). Every architecture reports the same gadgets as the intact file.
39
+ - A terminal `posix_spawn` whose symbol carries no version marker, as musl's
40
+ does not, is no longer passed over ([#432]).
41
+
42
+ ### Changed
43
+
44
+ - The gem no longer carries gadgets for the three glibc 2.26 builds it shipped
45
+ ([#443]) -- no supported Ubuntu LTS ships 2.26. Those BuildIDs now answer from
46
+ the remote database.
47
+ - Searching a MIPS libc takes 0.7s, was 2.3s ([#453]).
48
+ - Searching the same file twice in one process reuses what the first search
49
+ found ([#455]).
50
+ - Further search speedups, gadgets unchanged: objdump is asked what it supports
51
+ once per binary rather than once per command ([#454]), the scan locating calls
52
+ decodes far fewer words ([#456]), and a quarter as much is disassembled around
53
+ each call ([#457]).
54
+ - Requires elftools >= 2.2.0 ([#442], [#465]), which reads a symbol table without
55
+ building an object per symbol. A libc with no section headers searches in 0.24s,
56
+ was 0.44s; one with its sections intact is unchanged.
57
+
58
+ ### Fixed
59
+
60
+ - 67 more gadgets across the test corpus ([#460]): a backward walk threw away any
61
+ path that hit its length limit, so what a libc reported depended on how far
62
+ back it had been disassembled. Every new gadget was run under a debugger.
63
+ - MIPS gadgets that could not work are no longer reported ([#460]). Entering at a
64
+ call leaves the callee without the address o32 requires in `t9`, and six such
65
+ gadgets were verified not to spawn a shell.
66
+ - arm found nothing at all in a libc with no section headers ([#441]): Thumb code
67
+ was read as A32, symbol addresses were off by one, and literal-pool loads went
68
+ unresolved.
69
+ - A libc with no section headers lost the calls at an address its symbol table
70
+ gives more than one name, such as `sigaction`/`__sigaction` -- 20 aarch64
71
+ gadgets ([#440]).
72
+ - A libc with no section headers reported fewer gadgets on aarch64 and RISC-V
73
+ than the same libc intact -- 84 across the corpus ([#439]).
74
+ - amd64 discarded every `execl` candidate before emulating it ([#434]). No fixture
75
+ reports a new gadget as a result, but one could.
76
+ - A search could abort with `TypeError` where it should have dropped the
77
+ candidate ([#434]).
78
+
10
79
  ## v2.0.0 - 2026-08-29
11
80
 
12
81
  Reported gadgets are not offset-for-offset comparable with 1.x: constraints are
@@ -15,145 +84,140 @@ test corpus reports has been run under a debugger and seen to spawn a shell.
15
84
 
16
85
  ### Added
17
86
 
18
- - ARM32 support, alongside the existing amd64, i386 and aarch64 (#316).
87
+ - ARM32 support, alongside the existing amd64, i386 and aarch64 ([#316]).
19
88
  - Output level 2, which lists every gadget including the ones lower levels drop
20
- as duplicate or harder-to-satisfy (#350). `--level` is documented in the
21
- README with what each level shows (#397).
89
+ as duplicate or harder-to-satisfy ([#350]). `--level` is documented in the
90
+ README with what each level shows ([#397]).
22
91
  - Aletheia, a verification harness that loads a libc under gdb (natively or
23
92
  through qemu-user), applies a constraint-satisfying plan, and requires a real
24
- shell to run `ls /` before a gadget counts as real (#399). Run it with
93
+ shell to run `ls /` before a gadget counts as real ([#399]). Run it with
25
94
  `rake "aletheia:verify[level, target]"`. Every gadget the fixtures report is
26
95
  verified this way.
27
96
  - Gadgets say which file descriptors they close on the way to the exec, so a
28
- reader knows when the spawned shell would lose its I/O (#371).
97
+ reader knows when the spawned shell would lose its I/O ([#371]).
29
98
  - `rake builds:refresh` rebuilds the shipped gadget database from what the
30
99
  Ubuntu archive publishes now, and `rake builds:check` fails when a shipped
31
- entry has gone stale -- at most once a week, never on CI (#405, #406).
32
- - posix_spawn gadgets on aarch64 (#317), and the string a gadget reaches
33
- through the GOT is shown rather than left opaque (#372).
100
+ entry has gone stale -- at most once a week, never on CI ([#405], [#406]).
101
+ - posix_spawn gadgets on aarch64 ([#317]), and the string a gadget reaches
102
+ through the GOT is shown rather than left opaque ([#372]).
34
103
 
35
104
  ### Changed
36
105
 
37
- - **The gem ships a curated gadget database.** It carries the glibc of every
38
- Ubuntu LTS in standard support plus every libc the tests cover -- 33 entries,
39
- taking the packaged gem from 3.4MB to 112KB. Any other BuildID is fetched from
40
- this repository on demand, as before, so nothing is unreachable; but an
41
- offline `-b` for an arbitrary libc no longer answers from the gem alone
42
- (#405).
106
+ - **The gem ships a curated gadget database** -- 33 entries, taking the packaged
107
+ gem from 3.4MB to 112KB ([#405]). Any other BuildID is fetched on demand as
108
+ before, so an offline `-b` for an arbitrary libc no longer answers from the gem
109
+ alone.
43
110
  - **An output level means the same thing however a libc is looked up.** `-b`
44
111
  now honours `--level`, where it previously handed back whatever the database
45
112
  stored, and level 1 picks the same gadget however the emulator happened to
46
- find it (#402).
113
+ find it ([#402]).
47
114
  - The database was regenerated; entries had been built before a year of
48
- constraint work and reported gadgets their libc no longer produces (#405).
115
+ constraint work and reported gadgets their libc no longer produces ([#405]).
49
116
  - Constraints read consistently: pointers compare to `NULL` and values to hex,
50
- never a bare `0` (#334), and readability is stated as `readable: <reg>`
51
- (#344). A mask a gadget applies is named rather than given up on (#370), and
52
- a value required to be zero scores the same however it is spelled (#377,
53
- #401).
117
+ never a bare `0` ([#334]), and readability is stated as `readable: <reg>`
118
+ ([#344]). A mask a gadget applies is named rather than given up on ([#370]), and
119
+ a value required to be zero scores the same however it is spelled ([#377],
120
+ [#401]).
54
121
  - Emulation stops at the terminal `exec*` call instead of running past it
55
- (#325), and a candidate whose path cannot hold is rejected (#359, #360).
122
+ ([#325]), and a candidate whose path cannot hold is rejected ([#359], [#360]).
56
123
  - Searching a libc got roughly five times faster: the test corpus at level 0
57
- went from 42.5s to 8.6s (#388, #389, #390, #393, #394, #395, #396).
58
- - Requires Ruby >= 3.3 (#293) and elftools >= 2.0.0.
124
+ went from 42.5s to 8.6s ([#388], [#389], [#390], [#393], [#394], [#395], [#396]).
125
+ - Requires Ruby >= 3.3 ([#293]) and elftools >= 2.0.0.
59
126
 
60
127
  ### Fixed
61
128
 
62
129
  - Gadgets that could not actually spawn a shell, each found by running them:
63
130
  a dereferenced pointer argument of a "safe" libc call went unconstrained
64
- (#323, #340), a writable constraint was lost when its base was reassigned
65
- (#341), frame-pointer stores did not require the frame be writable (#345),
66
- an argv that disables shell execution was reported as usable (#348), an
67
- uncontrolled dereference was not required to be readable (#354), and a slot
131
+ ([#323], [#340]), a writable constraint was lost when its base was reassigned
132
+ ([#341]), frame-pointer stores did not require the frame be writable ([#345]),
133
+ an argv that disables shell execution was reported as usable ([#348]), an
134
+ uncontrolled dereference was not required to be readable ([#354]), and a slot
68
135
  was read back as its entry value rather than what the gadget had put there
69
- (#364).
136
+ ([#364]).
70
137
  - A GOT-base register the window establishes itself was seeded as a
71
- precondition (#385), and the GOT-base constraint is now only stated where a
72
- caller can actually put it -- in a register (#404).
138
+ precondition ([#385]), and the GOT-base constraint is now only stated where a
139
+ caller can actually put it -- in a register ([#404]).
73
140
  - Windowed disassembly lost gadgets whose branch predecessor sits after the
74
- call, and could invent gadgets by falling through a window boundary (#391,
75
- #392).
76
- - The "not glibc" check did not fire for aarch64 files (#311).
141
+ call, and could invent gadgets by falling through a window boundary ([#391],
142
+ [#392]).
143
+ - The "not glibc" check did not fire for aarch64 files ([#311]).
77
144
  - **Certificates are verified again when fetching a gadget database entry.**
78
- Verification had been switched off, and what comes back from that request is
79
- written to a file and required as Ruby, so anyone able to answer it could run
80
- code as the user.
81
- - Shipped entries reported fewer gadgets than reading the same libc as a file,
82
- having been generated before the emulator learned to run `xchg`. They are
83
- regenerated, and `rake builds:audit` now fails when an entry stops matching
145
+ Verification had been off, and the response is written to a file and required
146
+ as Ruby -- so anyone able to answer that request could run code as the user.
147
+ - Shipped entries reported fewer gadgets than reading the same libc as a file.
148
+ They are regenerated, and `rake builds:audit` now fails when one stops matching
84
149
  its libc.
85
150
  - An architecture is recognised by the machine type its ELF header states, not
86
- by the name the reader library prints for it -- the latter is that library's
87
- wording and changed in elftools 2.0.0, which left every aarch64 and amd64 file
88
- reading as an unknown architecture.
151
+ by the name elftools prints for it, whose wording changed in 2.0.0 and left
152
+ every aarch64 and amd64 file reading as unknown.
89
153
 
90
154
  ## v1.10.0 - 2024-10-04
91
155
 
92
- - Added JSON output, `--output-format json` (#225).
93
- - Requires Ruby >= 3.1 (#216).
156
+ - Added JSON output, `--output-format json` ([#225]).
157
+ - Requires Ruby >= 3.1 ([#216]).
94
158
 
95
159
  ## v1.9.0 - 2023-11-30
96
160
 
97
- - Sharper constraints for `argv` and `envp` (#206).
98
- - Added `--dwarf-start=0` so the output carries no local file path (#205).
161
+ - Sharper constraints for `argv` and `envp` ([#206]).
162
+ - Added `--dwarf-start=0` so the output carries no local file path ([#205]).
99
163
 
100
164
  ## v1.8.1 - 2022-03-25
101
165
 
102
166
  - Stack registers score higher on writable constraints, so easier gadgets rank
103
- first (#190).
167
+ first ([#190]).
104
168
 
105
169
  ## v1.8.0 - 2022-03-20
106
170
 
107
- - posix_spawn call sites are treated as one-gadgets (#183).
108
- - amd64: loosened the restriction on gadgets reached by `jmp` (#178).
171
+ - posix_spawn call sites are treated as one-gadgets ([#183]).
172
+ - amd64: loosened the restriction on gadgets reached by `jmp` ([#178]).
109
173
 
110
174
  ## v1.7.4 - 2021-01-13
111
175
 
112
- - Writable constraints on the x86 architectures (#156).
176
+ - Writable constraints on the x86 architectures ([#156]).
113
177
 
114
178
  ## v1.7.3 - 2019-10-25
115
179
 
116
- - Added the `--base` option (#100).
117
- - Constraints for XMM alignment, and stack alignment scores higher (#87).
180
+ - Added the `--base` option ([#100]).
181
+ - Constraints for XMM alignment, and stack alignment scores higher ([#87]).
118
182
 
119
183
  ## v1.7.2 - 2019-05-05
120
184
 
121
- - Added `--near`, ordering gadgets by distance from given functions (#76).
122
- - Introduced the CLI module (#81).
185
+ - Added `--near`, ordering gadgets by distance from given functions ([#76]).
186
+ - Introduced the CLI module ([#81]).
123
187
 
124
188
  ## v1.7.1 - 2019-04-19
125
189
 
126
- - Added gemspec metadata (#75).
190
+ - Added gemspec metadata ([#75]).
127
191
 
128
192
  ## v1.7.0 - 2019-03-07
129
193
 
130
- - AArch64 support (#64).
131
- - Constraints are scored, so the easiest gadgets are reported first (#67).
194
+ - AArch64 support ([#64]).
195
+ - Constraints are scored, so the easiest gadgets are reported first ([#67]).
132
196
 
133
197
  ## v1.6.2 - 2018-10-25
134
198
 
135
- - one_gadget is usable as a library (#47).
199
+ - one_gadget is usable as a library ([#47]).
136
200
 
137
201
  ## v1.6.1 - 2018-09-13
138
202
 
139
- - Improved update checking (#43) and custom error classes (#40).
203
+ - Improved update checking ([#43]) and custom error classes ([#40]).
140
204
 
141
205
  ## v1.6.0 - 2018-04-28
142
206
 
143
- - Added the xmm instructions and glibc 2.27 builds (#27).
144
- - Added `--info`, showing what is known about a BuildID (#25).
207
+ - Added the xmm instructions and glibc 2.27 builds ([#27]).
208
+ - Added `--info`, showing what is known about a BuildID ([#25]).
145
209
 
146
210
  ## v1.5.0 - 2017-11-06
147
211
 
148
- - Emulator rework, and the build database is generated from libc files (#15).
212
+ - Emulator rework, and the build database is generated from libc files ([#15]).
149
213
 
150
214
  ## v1.4.1 - 2017-11-01
151
215
 
152
- - Checks for a newer version automatically (#13).
216
+ - Checks for a newer version automatically ([#13]).
153
217
 
154
218
  ## v1.4.0 - 2017-06-23
155
219
 
156
- - Warns when a BuildID is not found, and added Ubuntu 16.04/17.04 libcs (#9).
220
+ - Warns when a BuildID is not found, and added Ubuntu 16.04/17.04 libcs ([#9]).
157
221
 
158
222
  ## v1.3.8 - 2017-05-26
159
223
 
@@ -166,7 +230,7 @@ test corpus reports has been run under a debugger and seen to spawn a shell.
166
230
  ## v1.3.6 - 2017-04-01
167
231
 
168
232
  - Added builds for glibc >= 2.19; a given libc file is no longer looked up
169
- remotely (#6).
233
+ remotely ([#6]).
170
234
 
171
235
  ## v1.3.5 - 2017-03-27
172
236
 
@@ -215,3 +279,89 @@ test corpus reports has been run under a debugger and seen to spawn a shell.
215
279
  ## v0.1.0 - 2017-02-11
216
280
 
217
281
  - First release.
282
+
283
+ [#6]: https://github.com/david942j/one_gadget/pull/6
284
+ [#9]: https://github.com/david942j/one_gadget/pull/9
285
+ [#13]: https://github.com/david942j/one_gadget/pull/13
286
+ [#15]: https://github.com/david942j/one_gadget/pull/15
287
+ [#25]: https://github.com/david942j/one_gadget/pull/25
288
+ [#27]: https://github.com/david942j/one_gadget/pull/27
289
+ [#40]: https://github.com/david942j/one_gadget/pull/40
290
+ [#43]: https://github.com/david942j/one_gadget/pull/43
291
+ [#47]: https://github.com/david942j/one_gadget/pull/47
292
+ [#64]: https://github.com/david942j/one_gadget/pull/64
293
+ [#67]: https://github.com/david942j/one_gadget/pull/67
294
+ [#75]: https://github.com/david942j/one_gadget/pull/75
295
+ [#76]: https://github.com/david942j/one_gadget/pull/76
296
+ [#81]: https://github.com/david942j/one_gadget/pull/81
297
+ [#87]: https://github.com/david942j/one_gadget/pull/87
298
+ [#100]: https://github.com/david942j/one_gadget/pull/100
299
+ [#156]: https://github.com/david942j/one_gadget/pull/156
300
+ [#178]: https://github.com/david942j/one_gadget/pull/178
301
+ [#183]: https://github.com/david942j/one_gadget/pull/183
302
+ [#190]: https://github.com/david942j/one_gadget/pull/190
303
+ [#205]: https://github.com/david942j/one_gadget/pull/205
304
+ [#206]: https://github.com/david942j/one_gadget/pull/206
305
+ [#216]: https://github.com/david942j/one_gadget/pull/216
306
+ [#225]: https://github.com/david942j/one_gadget/pull/225
307
+ [#293]: https://github.com/david942j/one_gadget/pull/293
308
+ [#311]: https://github.com/david942j/one_gadget/pull/311
309
+ [#316]: https://github.com/david942j/one_gadget/pull/316
310
+ [#317]: https://github.com/david942j/one_gadget/pull/317
311
+ [#323]: https://github.com/david942j/one_gadget/pull/323
312
+ [#325]: https://github.com/david942j/one_gadget/pull/325
313
+ [#334]: https://github.com/david942j/one_gadget/pull/334
314
+ [#340]: https://github.com/david942j/one_gadget/pull/340
315
+ [#341]: https://github.com/david942j/one_gadget/pull/341
316
+ [#344]: https://github.com/david942j/one_gadget/pull/344
317
+ [#345]: https://github.com/david942j/one_gadget/pull/345
318
+ [#348]: https://github.com/david942j/one_gadget/pull/348
319
+ [#350]: https://github.com/david942j/one_gadget/pull/350
320
+ [#354]: https://github.com/david942j/one_gadget/pull/354
321
+ [#359]: https://github.com/david942j/one_gadget/pull/359
322
+ [#360]: https://github.com/david942j/one_gadget/pull/360
323
+ [#364]: https://github.com/david942j/one_gadget/pull/364
324
+ [#370]: https://github.com/david942j/one_gadget/pull/370
325
+ [#371]: https://github.com/david942j/one_gadget/pull/371
326
+ [#372]: https://github.com/david942j/one_gadget/pull/372
327
+ [#377]: https://github.com/david942j/one_gadget/pull/377
328
+ [#385]: https://github.com/david942j/one_gadget/pull/385
329
+ [#388]: https://github.com/david942j/one_gadget/pull/388
330
+ [#389]: https://github.com/david942j/one_gadget/pull/389
331
+ [#390]: https://github.com/david942j/one_gadget/pull/390
332
+ [#391]: https://github.com/david942j/one_gadget/pull/391
333
+ [#392]: https://github.com/david942j/one_gadget/pull/392
334
+ [#393]: https://github.com/david942j/one_gadget/pull/393
335
+ [#394]: https://github.com/david942j/one_gadget/pull/394
336
+ [#395]: https://github.com/david942j/one_gadget/pull/395
337
+ [#396]: https://github.com/david942j/one_gadget/pull/396
338
+ [#397]: https://github.com/david942j/one_gadget/pull/397
339
+ [#399]: https://github.com/david942j/one_gadget/pull/399
340
+ [#401]: https://github.com/david942j/one_gadget/pull/401
341
+ [#402]: https://github.com/david942j/one_gadget/pull/402
342
+ [#404]: https://github.com/david942j/one_gadget/pull/404
343
+ [#405]: https://github.com/david942j/one_gadget/pull/405
344
+ [#406]: https://github.com/david942j/one_gadget/pull/406
345
+ [#420]: https://github.com/david942j/one_gadget/pull/420
346
+ [#421]: https://github.com/david942j/one_gadget/pull/421
347
+ [#422]: https://github.com/david942j/one_gadget/pull/422
348
+ [#423]: https://github.com/david942j/one_gadget/pull/423
349
+ [#424]: https://github.com/david942j/one_gadget/pull/424
350
+ [#425]: https://github.com/david942j/one_gadget/pull/425
351
+ [#432]: https://github.com/david942j/one_gadget/pull/432
352
+ [#434]: https://github.com/david942j/one_gadget/pull/434
353
+ [#439]: https://github.com/david942j/one_gadget/pull/439
354
+ [#440]: https://github.com/david942j/one_gadget/pull/440
355
+ [#441]: https://github.com/david942j/one_gadget/pull/441
356
+ [#442]: https://github.com/david942j/one_gadget/pull/442
357
+ [#443]: https://github.com/david942j/one_gadget/pull/443
358
+ [#448]: https://github.com/david942j/one_gadget/pull/448
359
+ [#453]: https://github.com/david942j/one_gadget/pull/453
360
+ [#454]: https://github.com/david942j/one_gadget/pull/454
361
+ [#455]: https://github.com/david942j/one_gadget/pull/455
362
+ [#456]: https://github.com/david942j/one_gadget/pull/456
363
+ [#457]: https://github.com/david942j/one_gadget/pull/457
364
+ [#460]: https://github.com/david942j/one_gadget/pull/460
365
+ [#465]: https://github.com/david942j/one_gadget/pull/465
366
+ [#467]: https://github.com/david942j/one_gadget/pull/467
367
+ [#468]: https://github.com/david942j/one_gadget/pull/468
data/README.md CHANGED
@@ -11,12 +11,13 @@
11
11
 
12
12
  ## OneGadget
13
13
 
14
- When playing ctf pwn challenges we usually need the one-gadget RCE (remote code execution),
15
- which leads to call `execve('/bin/sh', NULL, NULL)`.
14
+ When solving CTF pwn challenges we usually want a one-gadget RCE: a single address in
15
+ libc that, jumped to, calls `execve("/bin/sh", NULL, NULL)`.
16
16
 
17
- This gem provides such gadgets finder, no need to use objdump or IDA-pro every time like a fool :wink:
17
+ This gem finds them for you, so you don't have to dig through objdump or IDA Pro every
18
+ time :wink:
18
19
 
19
- To use this tool, type `one_gadget /path/to/libc` in command line and enjoy the magic :laughing:
20
+ Point it at a libc -- `one_gadget /path/to/libc` -- and enjoy the magic :laughing:
20
21
 
21
22
  ## Installation
22
23
 
@@ -25,18 +26,19 @@ Available on RubyGems.org!
25
26
  $ gem install one_gadget
26
27
  ```
27
28
 
28
- Note: requires ruby version >= 2.1.0, you can use `ruby --version` to check.
29
-
30
29
  ## Supported Architectures
31
30
 
32
31
  - [x] i386
33
32
  - [x] amd64 (x86-64)
34
33
  - [x] aarch64 (ARMv8)
35
34
  - [x] arm (ARMv7, A32/Thumb-2)
35
+ - [x] riscv64 (RV64GC)
36
+ - [x] mips (MIPS32 o32, big- and little-endian)
36
37
 
37
38
  ## Implementation
38
39
 
39
- OneGadget uses symbolic execution to find the constraints of gadgets to be successful.
40
+ OneGadget symbolically executes the code around each candidate address to work out what
41
+ has to hold for the gadget to work.
40
42
 
41
43
  Gadgets are found by walking the control-flow graph backward from each `exec`/`posix_spawn`
42
44
  call, following conditional branches both ways. When a gadget is only reachable if a branch is
@@ -144,17 +146,17 @@ BuildID is fetched from this repository, which keeps them all.
144
146
 
145
147
  ##### Why
146
148
 
147
- Consider this scenario when exploiting:
148
- 1. Able to write on GOT (Global Offset Table)
149
- 2. Base address of libc is *unknown*
149
+ Consider this situation while exploiting:
150
+ 1. You can write to the GOT (Global Offset Table).
151
+ 2. The base address of libc is *unknown*.
150
152
 
151
- In this scenario you can choose to write two low-byte on a GOT entry with one-gadget's two low-byte.
152
- If the function offset on GOT is close enough with the one-gadget,
153
- you will have at least 1/16 chance of success.
153
+ Here you can overwrite the low two bytes of a GOT entry with the low two bytes of a
154
+ one-gadget. If the function sits close enough to the gadget, only one nibble is left to
155
+ guess -- at least a 1 in 16 chance of success.
154
156
 
155
157
  ##### Usage
156
158
 
157
- Reorder gadgets according to the distance of given functions.
159
+ Sorts the gadgets by how far they are from the functions you name.
158
160
 
159
161
  ```bash
160
162
  $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near exit,mkdir
@@ -204,7 +206,7 @@ $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --n
204
206
  ```
205
207
  ![near](https://github.com/david942j/one_gadget/blob/master/examples/near.png?raw=true)
206
208
 
207
- Regular expression is acceptable.
209
+ Regular expressions work too.
208
210
  ```bash
209
211
  $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near 'write.*' --raw
210
212
  # [OneGadget] Gadgets near writev(0x1144a0):
@@ -216,7 +218,7 @@ $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --n
216
218
 
217
219
  ```
218
220
 
219
- Pass an ELF file as the argument, OneGadget will take all GOT functions for processing.
221
+ Pass an ELF file instead, and OneGadget uses every function in its GOT.
220
222
  ```bash
221
223
  $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so --near spec/data/test_near_file.elf --raw
222
224
  # [OneGadget] Gadgets near exit(0x46a70):
@@ -573,9 +575,81 @@ $ one_gadget spec/data/arm-libc-2.39.so
573
575
 
574
576
  ```
575
577
 
578
+ ##### RISC-V (RV64)
579
+
580
+ ```bash
581
+ $ one_gadget spec/data/riscv64-libc-2.39.so
582
+ # 0x9f73a execve("/bin/sh", s1, a2)
583
+ # constraints:
584
+ # [s1] == NULL || s1 == NULL || s1 is a valid argv
585
+ # [a2] == NULL || a2 == NULL || a2 is a valid envp
586
+ #
587
+ # 0x9f73c execve("/bin/sh", a1, a2)
588
+ # constraints:
589
+ # [a1] == NULL || a1 == NULL || a1 is a valid argv
590
+ # [a2] == NULL || a2 == NULL || a2 is a valid envp
591
+ #
592
+ # 0x9f778 execve("/bin/sh", s1, s2)
593
+ # constraints:
594
+ # [s1] == NULL || s1 == NULL || s1 is a valid argv
595
+ # [s2] == NULL || s2 == NULL || s2 is a valid envp
596
+ #
597
+ # 0xb5adc posix_spawn(sp+0x44, "/bin/sh", [sp+0x30], 0, sp+0x50, environ)
598
+ # constraints:
599
+ # [sp+0x50] == NULL || {[sp+0x50], [sp+0x58], [sp+0x60], [sp+0x68], ...} is a valid argv
600
+ # [sp+0x30] == NULL || (s32)[[sp+0x30]+0x4] <= 0x0
601
+
602
+ ```
603
+
604
+ ##### MIPS
605
+
606
+ Big-endian is as common as little-endian here, and both are read. This one is
607
+ OpenWrt's musl for ath79, which ships with no section headers -- the shape a
608
+ router's libc usually arrives in.
609
+
610
+ ```bash
611
+ $ one_gadget spec/data/mips-musl-1.2.4.so
612
+ # 0x668e8 posix_spawn(sp+0x20, "/bin/sh", 0, s0, sp+0x28, environ)
613
+ # constraints:
614
+ # gp is the GOT address of libc
615
+ # {"sh", "-c", s1, NULL} is a valid argv
616
+ # s0 == NULL || (u16)[s0] == 0x0
617
+ #
618
+ # 0x668ec posix_spawn(sp+0x20, "/bin/sh", 0, s0, sp+0x28, environ)
619
+ # constraints:
620
+ # gp is the GOT address of libc
621
+ # {"sh", "-c", [sp+0x30], NULL} is a valid argv
622
+ # s0 == NULL || (u16)[s0] == 0x0
623
+ #
624
+ # 0x668f0 posix_spawn(sp+0x20, "/bin/sh", 0, a3, sp+0x28, environ)
625
+ # constraints:
626
+ # gp is the GOT address of libc
627
+ # {"sh", "-c", [sp+0x30], NULL} is a valid argv
628
+ # a3 == NULL || (u16)[a3] == 0x0
629
+ #
630
+ # 0x668f4 posix_spawn(sp+0x20, "/bin/sh", 0, a3, sp+0x28, environ)
631
+ # constraints:
632
+ # gp is the GOT address of libc
633
+ # v0-0x7c70 == NULL || {v0-0x7c70, "-c", [sp+0x30], NULL} is a valid argv
634
+ # a3 == NULL || (u16)[a3] == 0x0
635
+ #
636
+ # 0x77b44 posix_spawn(sp+0x20, "/bin/sh", s2, 0, sp+0x2c, environ)
637
+ # constraints:
638
+ # gp is the GOT address of libc
639
+ # {"sh", "-c", s7, NULL} is a valid argv
640
+ # s2 == NULL || (s32)[s2+0x4] <= 0x0
641
+ #
642
+ # 0x77b48 posix_spawn(sp+0x20, "/bin/sh", s2, 0, sp+0x2c, environ)
643
+ # constraints:
644
+ # gp is the GOT address of libc
645
+ # v0-0x7c70 == NULL || {v0-0x7c70, "-c", s7, NULL} is a valid argv
646
+ # s2 == NULL || (s32)[s2+0x4] <= 0x0
647
+
648
+ ```
649
+
576
650
  #### Combine with Script
577
- Pass your exploit script as `one_gadget`'s arguments, it can
578
- try all gadgets one by one, so you don't need to try every possible gadgets manually.
651
+ Pass your exploit script to `one_gadget` and it runs the script once per gadget, so you
652
+ don't have to work through them by hand.
579
653
 
580
654
  ```bash
581
655
  $ one_gadget spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so -s 'echo "offset ->"'
@@ -589,7 +663,7 @@ require 'one_gadget'
589
663
  OneGadget.gadgets(file: 'spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so')
590
664
  #=> [932657, 932660, 932896, 1080554]
591
665
 
592
- # or in shorter way
666
+ # or, more briefly
593
667
  one_gadget('spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so', level: 1)
594
668
  #=> [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]
595
669
 
@@ -611,7 +685,7 @@ one_gadget('spec/data/libc-2.31-9fdb74e7b217d06c93172a8243f8547f947ee6d1.so')
611
685
  ```
612
686
 
613
687
  ## Make OneGadget Better
614
- Any suggestion or feature request is welcome! Feel free to send a pull request.
688
+ Any suggestion or feature request is welcome, and pull requests even more so!
615
689
 
616
- Please let me know if you find any libc that make OneGadget fail to find gadgets.
617
- And, if you like this work, I'll be happy to be [starred](https://github.com/david942j/one_gadget/stargazers) :grimacing:
690
+ Please let me know if you come across a libc OneGadget finds nothing in. And if you like
691
+ this work, I'd be happy to be [starred](https://github.com/david942j/one_gadget/stargazers) :grimacing: