pmq20 / ruby-packer

Packing your Ruby application into a single executable.
MIT License
1.56k stars 99 forks source link

Insecure rpath in binary and embedded ruby #66

Open ronisaacson opened 6 years ago

ronisaacson commented 6 years ago

After building a binary with rubyc, the binary contains an insecure rpath. The ruby interpreter in the embedded squashfs also contains the same insecure rpath, and same for any so's built for gems with native components.

% readelf -d a.out | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/tmp/rubyc/ruby-2.4.1-0.4.0/build/lib]

% readelf -d /tmp/rubyc/rubyc_work_dir/__enclose_io_memfs__/bin/ruby | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/tmp/rubyc/ruby-2.4.1-0.4.0/build/lib]

% readelf -d /tmp/rubyc/rubyc_work_dir/__enclose_io_memfs__/lib/ruby/gems/2.4.0/gems/json-*/lib/json/ext/parser.so | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/tmp/rubyc/ruby-2.4.1-0.4.0/build/lib]

These all use shared libraries. An attacker could easily create /tmp/rubyc/ruby-2.4.1-0.4.0/build/lib and put a malicious libc.so.6 in there, for example, compromising any other user running a rubyc-built binary on that system.

As a demonstration:

% mkdir -p /tmp/rubyc/ruby-2.4.1-0.4.0/build/lib
% touch /tmp/rubyc/ruby-2.4.1-0.4.0/build/lib/libc.so.6
% ./a.out
./a.out: error while loading shared libraries: /tmp/rubyc/ruby-2.4.1-0.4.0/build/lib/libc.so.6: file too short
kke commented 6 years ago

This, I think, is work-aroundable by using the -d parameter to set the temporary path during builds. (You don't have to rebuild rubyc)

Maybe if you set it to /root it's more secure.

ronisaacson commented 6 years ago

Well, sort of, but then you have to run your build as root. This is not generally recommended, and you're still building in an unnecessary and insecure path. A better option would be to include --disable-rpath in the configure options.

kke commented 6 years ago

Yes, but it's still better than /tmp until an option like that is available. You could build inside a chroot jail or a docker container without root.