Version 1.8.0 defaults to posix_spawn gadgets
0x4d5a-ctf opened this issue · comments
Seems like version 1.8.0 prefers the posix_spawn
gadgets and does not list execve
-gadgets with default output-level 0. Those posix_spawn
gadgets have much harder contraints and shouldn't be displayed instead of the easier execve
-gadgets.
Tests were conducted on the libc of the Ubuntu Docker: FROM ubuntu@sha256:a02c32cf0c2a7e8743c74deef66637aa70e063c9bd40e9e1f8c0b3ea0750b0ba
/usr/lib/x86_64-linux-gnu/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=89c3cb85f9e55046776471fed05ec441581d1969, for GNU/Linux 3.2.0, stripped
Output with one_gadget 1.7.4:
root@ecb44960ff3e:/home/ctf# one_gadget --version
OneGadget Version 1.7.4
root@ecb44960ff3e:/home/ctf# one_gadget /usr/lib/x86_64-linux-gnu/libc.so.6
0xebcf1 execve("/bin/sh", r10, [rbp-0x70])
constraints:
address rbp-0x78 is writable
[r10] == NULL || r10 == NULL
[[rbp-0x70]] == NULL || [rbp-0x70] == NULL
0xebcf5 execve("/bin/sh", r10, rdx)
constraints:
address rbp-0x78 is writable
[r10] == NULL || r10 == NULL
[rdx] == NULL || rdx == NULL
0xebcf8 execve("/bin/sh", rsi, rdx)
constraints:
address rbp-0x78 is writable
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL
Output with 1.8.0:
root@ecb44960ff3e:/home/ctf# gem install one_gadget --version 1.8.0
Fetching one_gadget-1.8.0.gem
Successfully installed one_gadget-1.8.0
Parsing documentation for one_gadget-1.8.0
Installing ri documentation for one_gadget-1.8.0
Done installing documentation for one_gadget after 3 seconds
1 gem installed
root@ecb44960ff3e:/home/ctf# one_gadget --version
OneGadget Version 1.8.0
root@ecb44960ff3e:/home/ctf# one_gadget /usr/lib/x86_64-linux-gnu/libc.so.6
0x50a37 posix_spawn(rsp+0x1c, "/bin/sh", 0, rbp, rsp+0x60, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
rbp == NULL || (u16)[rbp] == NULL
0x10dbc2 posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x40], 0, rsp+0x70, [rsp+0xf0])
constraints:
[rsp+0x70] == NULL
[[rsp+0xf0]] == NULL || [rsp+0xf0] == NULL
[rsp+0x40] == NULL || (s32)[[rsp+0x40]+0x4] <= 0
0x10dbca posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x40], 0, rsp+0x70, r9)
constraints:
[rsp+0x70] == NULL
[r9] == NULL || r9 == NULL
[rsp+0x40] == NULL || (s32)[[rsp+0x40]+0x4] <= 0
0x10dbcf posix_spawn(rsp+0x64, "/bin/sh", rdx, 0, rsp+0x70, r9)
constraints:
[rsp+0x70] == NULL
[r9] == NULL || r9 == NULL
rdx == NULL || (s32)[rdx+0x4] <= 0
Thanks for your report!
TBH it might not be clear which set of constraints is easier to achieve:
address rbp-0x78 is writable
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL
vs
[rsp+0x70] == NULL
[r9] == NULL || r9 == NULL
rdx == NULL || (s32)[rdx+0x4] <= 0
But let me check whether I should properly tune my scoring system of gadgets' constraints.
True, the "easier to achieve" rating was quite subjective for my special use case. I still think that, from my limited personal experience, constraints on the stack are harder to fulfill.
Thanks for taking a look into it and the fast response!
With the PR it becomes:
0x50a37 posix_spawn(rsp+0x1c, "/bin/sh", 0, rbp, rsp+0x60, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
rbp == NULL || (u16)[rbp] == NULL
0xebcf1 execve("/bin/sh", r10, [rbp-0x70])
constraints:
address rbp-0x78 is writable
[r10] == NULL || r10 == NULL
[[rbp-0x70]] == NULL || [rbp-0x70] == NULL
0xebcf5 execve("/bin/sh", r10, rdx)
constraints:
address rbp-0x78 is writable
[r10] == NULL || r10 == NULL
[rdx] == NULL || rdx == NULL
0xebcf8 execve("/bin/sh", rsi, rdx)
constraints:
address rbp-0x78 is writable
[rsi] == NULL || rsi == NULL
[rdx] == NULL || rdx == NULL
This result looks better to me as well
Released v1.8.1