项目作者: david942j

项目描述 :
The best tool for finding one gadget RCE in libc.so.6
高级语言: Ruby
项目地址: git://github.com/david942j/one_gadget.git
创建时间: 2017-02-07T08:03:34Z
项目社区:https://github.com/david942j/one_gadget

开源协议:MIT License

下载


Gem Version
Build Status
Downloads
Code Climate
Issue Count
Test Coverage
Inline docs
Yard Docs
MIT License

OneGadget

When playing ctf pwn challenges we usually need the one-gadget RCE (remote code execution),
which leads to call execve('/bin/sh', NULL, NULL).

This gem provides such gadgets finder, no need to use objdump or IDA-pro every time like a fool :wink:

To use this tool, type one_gadget /path/to/libc in command line and enjoy the magic :laughing:

Installation

Available on RubyGems.org!

  1. $ gem install one_gadget

Note: requires ruby version >= 2.1.0, you can use ruby --version to check.

Supported Architectures

  • i386
  • amd64 (x86-64)
  • aarch64 (ARMv8)

Implementation

OneGadget uses symbolic execution to find the constraints of gadgets to be successful.

The article introducing how I develop this tool can be found on my blog.

Usage

Command Line Interface

  1. $ one_gadget
  2. # Usage: one_gadget <FILE|-b BuildID> [options]
  3. # -b, --build-id BuildID BuildID[sha1] of libc.
  4. # -f, --[no-]force-file Force search gadgets in file instead of build id first.
  5. # -l, --level OUTPUT_LEVEL The output level.
  6. # OneGadget automatically selects gadgets with higher successful probability.
  7. # Increase this level to ask OneGadget show more gadgets it found.
  8. # Default: 0
  9. # -n, --near FUNCTIONS/FILE Order gadgets by their distance to the given functions or to the GOT functions of the given file.
  10. # -o, --output-format FORMAT Output format. FORMAT should be one of <pretty|raw|json>.
  11. # Default: pretty
  12. # -r, --raw Alias of -o raw. Output gadgets offset only, split with one space.
  13. # -s, --script exploit-script Run exploit script with all possible gadgets.
  14. # The script will be run as 'exploit-script $offset'.
  15. # --info BuildID Show version information given BuildID.
  16. # --base BASE_ADDRESS The base address of libc.
  17. # Default: 0
  18. # --version Current gem version.
  1. $ one_gadget /lib/x86_64-linux-gnu/libc.so.6
  2. # 0xe3afe execve("/bin/sh", r15, r12)
  3. # constraints:
  4. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  5. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  6. #
  7. # 0xe3b01 execve("/bin/sh", r15, rdx)
  8. # constraints:
  9. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  10. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  11. #
  12. # 0xe3b04 execve("/bin/sh", rsi, rdx)
  13. # constraints:
  14. # [rsi] == NULL || rsi == NULL || rsi is a valid argv
  15. # [rdx] == NULL || rdx == NULL || rdx is a valid envp

x86_64

Given BuildID

  1. $ one_gadget -b aad7dbe330f23ea00ca63daf793b766b51aceb5d
  2. # 0x4557a execve("/bin/sh", rsp+0x30, environ)
  3. # constraints:
  4. # [rsp+0x30] == NULL || {[rsp+0x30], [rsp+0x38], [rsp+0x40], [rsp+0x48], ...} is a valid argv
  5. #
  6. # 0xf1651 execve("/bin/sh", rsp+0x40, environ)
  7. # constraints:
  8. # [rsp+0x40] == NULL || {[rsp+0x40], [rsp+0x48], [rsp+0x50], [rsp+0x58], ...} is a valid argv
  9. #
  10. # 0xf24cb execve("/bin/sh", rsp+0x60, environ)
  11. # constraints:
  12. # [rsp+0x60] == NULL || {[rsp+0x60], [rsp+0x68], [rsp+0x70], [rsp+0x78], ...} is a valid argv

build id

Gadgets Near Functions

Why

Consider this scenario when exploiting:

  1. Able to write on GOT (Global Offset Table)
  2. Base address of libc is unknown

In this scenario you can choose to write two low-byte on a GOT entry with one-gadget’s two low-byte.
If the function offset on GOT is close enough with the one-gadget,
you will have at least 1/16 chance of success.

Usage

Reorder gadgets according to the distance of given functions.

  1. $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
  2. # [OneGadget] Gadgets near exit(0x46a40):
  3. # 0xe3afe execve("/bin/sh", r15, r12)
  4. # constraints:
  5. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  6. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  7. #
  8. # 0xe3b01 execve("/bin/sh", r15, rdx)
  9. # constraints:
  10. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  11. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  12. #
  13. # 0xe3b04 execve("/bin/sh", rsi, rdx)
  14. # constraints:
  15. # [rsi] == NULL || rsi == NULL || rsi is a valid argv
  16. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  17. #
  18. # [OneGadget] Gadgets near mkdir(0x10de70):
  19. # 0xe3b04 execve("/bin/sh", rsi, rdx)
  20. # constraints:
  21. # [rsi] == NULL || rsi == NULL || rsi is a valid argv
  22. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  23. #
  24. # 0xe3b01 execve("/bin/sh", r15, rdx)
  25. # constraints:
  26. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  27. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  28. #
  29. # 0xe3afe execve("/bin/sh", r15, r12)
  30. # constraints:
  31. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  32. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  33. #

near

Regular expression is acceptable.

  1. $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near 'write.*' --raw
  2. # [OneGadget] Gadgets near writev(0x114690):
  3. # 932612 932609 932606
  4. #
  5. # [OneGadget] Gadgets near write(0x10e280):
  6. # 932612 932609 932606
  7. #

Pass an ELF file as the argument, OneGadget will take all GOT functions for processing.

  1. $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near spec/data/test_near_file.elf --raw
  2. # [OneGadget] Gadgets near exit(0x46a40):
  3. # 932606 932609 932612
  4. #
  5. # [OneGadget] Gadgets near puts(0x84420):
  6. # 932606 932609 932612
  7. #
  8. # [OneGadget] Gadgets near printf(0x61c90):
  9. # 932606 932609 932612
  10. #
  11. # [OneGadget] Gadgets near strlen(0x9f630):
  12. # 932606 932609 932612
  13. #
  14. # [OneGadget] Gadgets near __cxa_finalize(0x46f10):
  15. # 932606 932609 932612
  16. #
  17. # [OneGadget] Gadgets near __libc_start_main(0x23f90):
  18. # 932606 932609 932612
  19. #

Show All Gadgets

Sometimes one_gadget finds too many gadgets to show them in one screen,
by default gadgets would be filtered automatically according to the difficulty of constraints.

Use option --level 1 to show all gadgets found instead of only those with higher probabilities.

  1. $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --level 1
  2. # 0x51dfb posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
  3. # constraints:
  4. # address rsp+0x60 is writable
  5. # rsp & 0xf == 0
  6. # {"sh", "-c", rbx, NULL} is a valid argv
  7. # rbp == NULL || (u16)[rbp] == NULL
  8. #
  9. # 0x51e02 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
  10. # constraints:
  11. # address rsp+0x60 is writable
  12. # rsp & 0xf == 0
  13. # rax == NULL || {"sh", rax, rbx, NULL} is a valid argv
  14. # rbp == NULL || (u16)[rbp] == NULL
  15. #
  16. # 0x51e09 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
  17. # constraints:
  18. # address rsp+0x60 is writable
  19. # rsp & 0xf == 0
  20. # rcx == NULL || {rcx, rax, rbx, NULL} is a valid argv
  21. # rbp == NULL || (u16)[rbp] == NULL
  22. #
  23. # 0x51e10 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ)
  24. # constraints:
  25. # address rsp+0x60 is writable
  26. # rsp & 0xf == 0
  27. # rcx == NULL || {rcx, (u64)xmm1, rbx, NULL} is a valid argv
  28. # rdx == NULL || (s32)[rdx+0x4] <= 0
  29. # rbp == NULL || (u16)[rbp] == NULL
  30. #
  31. # 0x51e15 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ)
  32. # constraints:
  33. # address rsp+0x60 is writable
  34. # rsp & 0xf == 0
  35. # (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, rbx, NULL} is a valid argv
  36. # rdx == NULL || (s32)[rdx+0x4] <= 0
  37. # rbp == NULL || (u16)[rbp] == NULL
  38. #
  39. # 0x51e25 posix_spawn(rdi, "/bin/sh", rdx, rbp, rsp+0x50, [rax])
  40. # constraints:
  41. # address rsp+0x60 is writable
  42. # rsp & 0xf == 0
  43. # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), rbx, NULL} is a valid argv
  44. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  45. # rdi == NULL || writable: rdi
  46. # rdx == NULL || (s32)[rdx+0x4] <= 0
  47. # rbp == NULL || (u16)[rbp] == NULL
  48. #
  49. # 0x51e2a posix_spawn(rdi, "/bin/sh", rdx, rbp, r8, [rax])
  50. # constraints:
  51. # address rsp+0x60 is writable
  52. # rsp & 0xf == 0
  53. # [r8] == NULL || r8 is a valid argv
  54. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  55. # rdi == NULL || writable: rdi
  56. # rdx == NULL || (s32)[rdx+0x4] <= 0
  57. # rbp == NULL || (u16)[rbp] == NULL
  58. #
  59. # 0x51e2d posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
  60. # constraints:
  61. # address rsp+0x60 is writable
  62. # rsp & 0xf == 0
  63. # [r8] == NULL || r8 is a valid argv
  64. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  65. # rdi == NULL || writable: rdi
  66. # rdx == NULL || (s32)[rdx+0x4] <= 0
  67. # rcx == NULL || (u16)[rcx] == NULL
  68. #
  69. # 0x51e32 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
  70. # constraints:
  71. # address rsp+0x68 is writable
  72. # rsp & 0xf == 0
  73. # [r8] == NULL || r8 is a valid argv
  74. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  75. # rdi == NULL || writable: rdi
  76. # rdx == NULL || (s32)[rdx+0x4] <= 0
  77. # rcx == NULL || (u16)[rcx] == NULL
  78. #
  79. # 0x84135 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
  80. # constraints:
  81. # address rsp+0x70 is writable
  82. # rsp & 0xf == 0
  83. # {"sh", "-c", rbp, NULL} is a valid argv
  84. # rbx+0xe0 == NULL || writable: rbx+0xe0
  85. # r12 == NULL || (s32)[r12+0x4] <= 0
  86. #
  87. # 0x8413c posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
  88. # constraints:
  89. # address rsp+0x70 is writable
  90. # rsp & 0xf == 0
  91. # rax == NULL || {"sh", rax, rbp, NULL} is a valid argv
  92. # rbx+0xe0 == NULL || writable: rbx+0xe0
  93. # r12 == NULL || (s32)[r12+0x4] <= 0
  94. #
  95. # 0x84143 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
  96. # constraints:
  97. # address rsp+0x70 is writable
  98. # rsp & 0xf == 0
  99. # rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv
  100. # rbx+0xe0 == NULL || writable: rbx+0xe0
  101. # r12 == NULL || (s32)[r12+0x4] <= 0
  102. #
  103. # 0x84146 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
  104. # constraints:
  105. # address rsp+0x70 is writable
  106. # rsp & 0xf == 0
  107. # rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv
  108. # rbx+0xe0 == NULL || writable: rbx+0xe0
  109. # rdx == NULL || (s32)[rdx+0x4] <= 0
  110. #
  111. # 0x8414b posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
  112. # constraints:
  113. # address rsp+0x78 is writable
  114. # rsp & 0xf == 0
  115. # rcx == NULL || {rcx, rax, [rsp+0x70], NULL} is a valid argv
  116. # rbx+0xe0 == NULL || writable: rbx+0xe0
  117. # rdx == NULL || (s32)[rdx+0x4] <= 0
  118. #
  119. # 0x84150 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
  120. # constraints:
  121. # address rsp+0x78 is writable
  122. # rsp & 0xf == 0
  123. # rcx == NULL || {rcx, (u64)xmm1, [rsp+0x70], NULL} is a valid argv
  124. # rbx+0xe0 == NULL || writable: rbx+0xe0
  125. # rdx == NULL || (s32)[rdx+0x4] <= 0
  126. #
  127. # 0x8415c posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, [rax])
  128. # constraints:
  129. # address rsp+0x78 is writable
  130. # rsp & 0xf == 0
  131. # (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, [rsp+0x70], NULL} is a valid argv
  132. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  133. # rbx+0xe0 == NULL || writable: rbx+0xe0
  134. # rdx == NULL || (s32)[rdx+0x4] <= 0
  135. #
  136. # 0x84162 posix_spawn(rbx+0xe0, "/bin/sh", rdx, rcx, rsp+0x60, [rax])
  137. # constraints:
  138. # address rsp+0x78 is writable
  139. # rsp & 0xf == 0
  140. # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv
  141. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  142. # rbx+0xe0 == NULL || writable: rbx+0xe0
  143. # rdx == NULL || (s32)[rdx+0x4] <= 0
  144. # rcx == NULL || (u16)[rcx] == NULL
  145. #
  146. # 0x84169 posix_spawn(rdi, "/bin/sh", rdx, rcx, rsp+0x60, [rax])
  147. # constraints:
  148. # address rsp+0x78 is writable
  149. # rsp & 0xf == 0
  150. # (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv
  151. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  152. # rdi == NULL || writable: rdi
  153. # rdx == NULL || (s32)[rdx+0x4] <= 0
  154. # rcx == NULL || (u16)[rcx] == NULL
  155. #
  156. # 0x84170 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
  157. # constraints:
  158. # address rsp+0x78 is writable
  159. # rsp & 0xf == 0
  160. # [r8] == NULL || r8 is a valid argv
  161. # [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
  162. # rdi == NULL || writable: rdi
  163. # rdx == NULL || (s32)[rdx+0x4] <= 0
  164. # rcx == NULL || (u16)[rcx] == NULL
  165. #
  166. # 0xe3afe execve("/bin/sh", r15, r12)
  167. # constraints:
  168. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  169. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  170. #
  171. # 0xe3b01 execve("/bin/sh", r15, rdx)
  172. # constraints:
  173. # [r15] == NULL || r15 == NULL || r15 is a valid argv
  174. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  175. #
  176. # 0xe3b04 execve("/bin/sh", rsi, rdx)
  177. # constraints:
  178. # [rsi] == NULL || rsi == NULL || rsi is a valid argv
  179. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  180. #
  181. # 0xe3cf3 execve("/bin/sh", r10, r12)
  182. # constraints:
  183. # address rbp-0x78 is writable
  184. # [r10] == NULL || r10 == NULL || r10 is a valid argv
  185. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  186. #
  187. # 0xe3cf6 execve("/bin/sh", r10, rdx)
  188. # constraints:
  189. # address rbp-0x78 is writable
  190. # [r10] == NULL || r10 == NULL || r10 is a valid argv
  191. # [rdx] == NULL || rdx == NULL || rdx is a valid envp
  192. #
  193. # 0xe3d62 execve("/bin/sh", rbp-0x50, r12)
  194. # constraints:
  195. # address rbp-0x48 is writable
  196. # r13 == NULL || {"/bin/sh", r13, NULL} is a valid argv
  197. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  198. #
  199. # 0xe3d69 execve("/bin/sh", rbp-0x50, r12)
  200. # constraints:
  201. # address rbp-0x48 is writable
  202. # rax == NULL || {rax, r13, NULL} is a valid argv
  203. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  204. #
  205. # 0xe3d70 execve("/bin/sh", rbp-0x50, r12)
  206. # constraints:
  207. # address rbp-0x50 is writable
  208. # rax == NULL || {rax, [rbp-0x48], NULL} is a valid argv
  209. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  210. #
  211. # 0xe3da7 execve("/bin/sh", rbp-0x50, r12)
  212. # constraints:
  213. # address rbp-0x50 is writable
  214. # [rbp-0x68] == NULL || {"/bin/sh", [rbp-0x68], NULL} is a valid argv
  215. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  216. #
  217. # 0xe3db1 execve("/bin/sh", rbp-0x50, r12)
  218. # constraints:
  219. # address rbp-0x50 is writable
  220. # rax == NULL || {rax, [rbp-0x68], NULL} is a valid argv
  221. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  222. #
  223. # 0xe3db5 execve("/bin/sh", r10, r12)
  224. # constraints:
  225. # addresses r10+0x10, rbp-0x50 are writable
  226. # [r10] == NULL || r10 == NULL || r10 is a valid argv
  227. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  228. #
  229. # 0xe3dbd execve("/bin/sh", r10, r12)
  230. # constraints:
  231. # addresses r10+0x10, rbp-0x48 are writable
  232. # [r10] == NULL || r10 == NULL || r10 is a valid argv
  233. # [r12] == NULL || r12 == NULL || r12 is a valid envp
  234. #
  235. # 0x1077ca posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, [rsp+0xf0])
  236. # constraints:
  237. # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
  238. # [[rsp+0xf0]] == NULL || [rsp+0xf0] == NULL || [rsp+0xf0] is a valid envp
  239. # [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0
  240. #
  241. # 0x1077d2 posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, r9)
  242. # constraints:
  243. # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
  244. # [r9] == NULL || r9 == NULL || r9 is a valid envp
  245. # [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0
  246. #
  247. # 0x1077d7 posix_spawn(rsp+0x64, "/bin/sh", rdx, 0, rsp+0x70, r9)
  248. # constraints:
  249. # [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
  250. # [r9] == NULL || r9 == NULL || r9 is a valid envp
  251. # rdx == NULL || (s32)[rdx+0x4] <= 0
  252. #
  253. # 0x1077e1 posix_spawn(rdi, "/bin/sh", rdx, 0, r8, r9)
  254. # constraints:
  255. # [r8] == NULL || r8 is a valid argv
  256. # [r9] == NULL || r9 == NULL || r9 is a valid envp
  257. # rdi == NULL || writable: rdi
  258. # rdx == NULL || (s32)[rdx+0x4] <= 0

Other Architectures

i386
  1. $ one_gadget /lib32/libc.so.6
  2. # 0xc890b execve("/bin/sh", [ebp-0x2c], esi)
  3. # constraints:
  4. # address ebp-0x20 is writable
  5. # ebx is the GOT address of libc
  6. # [[ebp-0x2c]] == NULL || [ebp-0x2c] == NULL || [ebp-0x2c] is a valid argv
  7. # [esi] == NULL || esi == NULL || esi is a valid envp
  8. #
  9. # 0x1421b3 execl("/bin/sh", eax)
  10. # constraints:
  11. # ebp is the GOT address of libc
  12. # eax == NULL
  13. #
  14. # 0x1421b4 execl("/bin/sh", [esp])
  15. # constraints:
  16. # ebp is the GOT address of libc
  17. # [esp] == NULL

i386

AArch64
  1. $ one_gadget spec/data/aarch64-libc-2.27.so
  2. # 0x3f160 execve("/bin/sh", sp+0x70, environ)
  3. # constraints:
  4. # address x20+0x338 is writable
  5. # x3 == NULL
  6. #
  7. # 0x3f184 execve("/bin/sh", sp+0x70, environ)
  8. # constraints:
  9. # addresses x19+0x4, x20+0x338 are writable
  10. # [sp+0x70] == NULL
  11. #
  12. # 0x3f1a8 execve("/bin/sh", x21, environ)
  13. # constraints:
  14. # addresses x19+0x4, x20+0x338 are writable
  15. # [x21] == NULL || x21 == NULL
  16. #
  17. # 0x63e90 execl("/bin/sh", x1)
  18. # constraints:
  19. # x1 == NULL

aarch64

Combine with Script

Pass your exploit script as one_gadget‘s arguments, it can
try all gadgets one by one, so you don’t need to try every possible gadgets manually.

  1. $ one_gadget ./spec/data/libc-2.19.so -s 'echo "offset ->"'

--script

In Ruby Scripts

  1. require 'one_gadget'
  2. OneGadget.gadgets(file: '/lib/x86_64-linux-gnu/libc.so.6')
  3. #=> [932606, 932609, 932612]
  4. # or in shorter way
  5. one_gadget('/lib/x86_64-linux-gnu/libc.so.6', level: 1)
  6. #=> [335355, 335362, 335369, 335376, 335381, 335397, 335402, 335405, 335410, 540981, 540988, 540995, 540998, 541003, 541008, 541020, 541026, 541033, 541040, 932606, 932609, 932612, 933107, 933110, 933218, 933225, 933232, 933287, 933297, 933301, 933309, 1079242, 1079250, 1079255, 1079265]
  7. # from build id
  8. one_gadget('b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0')
  9. #=> [324286, 324293, 324386, 1090444]

To Python Lovers

  1. import subprocess
  2. def one_gadget(filename):
  3. return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')]
  4. one_gadget('/lib/x86_64-linux-gnu/libc.so.6')
  5. #=> [932606, 932609, 932612]

Make OneGadget Better

Any suggestion or feature request is welcome! Feel free to send a pull request.

Please let me know if you find any libc that make OneGadget fail to find gadgets.
And, if you like this work, I’ll be happy to be starred :grimacing: