mosers
/
eaas-vde-proxy
Archiviert
1
0
Fork 0

Dirty version, only for remote access

main
Simon Moser vor 3 Jahren
Ursprung af165f5573
Commit ee257888d7
Signiert von: mosers
GPG-Schlüssel-ID: 96B3365A234B500C

@ -0,0 +1,246 @@
// based on https://github.com/aler9/landiscover/blob/main/layer-nbns.go (MIT License)
package layer_nbns
import (
"encoding/binary"
"fmt"
"strings"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
type layerNbns struct {
layers.BaseLayer
TransactionID uint16
IsResponse bool
Opcode uint8
Truncated bool
Recursion bool
Broadcast bool
Questions []nbnsQuestion
Answers []nbnsAnswer
AuthorityCount uint16
AdditionalCount uint16
}
func NewLayerNbns() *layerNbns {
return &layerNbns{}
}
type nbnsQuestion struct {
Query string
Type uint16
Class uint16
}
type nbnsAnswer struct {
Query string
Type uint16
Class uint16
TTL uint32
Names []nbnsAnswerName
}
type nbnsAnswerName struct {
Name string
Type uint8
Flags uint16
}
func (l *layerNbns) DecodeFromBytes(data []byte) error {
l.BaseLayer = layers.BaseLayer{Contents: data}
if len(data) < 12 {
return fmt.Errorf("invalid packet")
}
l.TransactionID = binary.BigEndian.Uint16(data[0:2])
l.IsResponse = (data[3] >> 7) == 0x01
l.Opcode = (data[3] >> 3) & 0x0F
l.Truncated = (data[3] >> 1) == 0x01
l.Recursion = data[3] == 0x01
l.Broadcast = (data[4] >> 4) == 0x01
questionCount := binary.BigEndian.Uint16(data[4:6])
answerCount := binary.BigEndian.Uint16(data[6:8])
l.AuthorityCount = binary.BigEndian.Uint16(data[8:10])
l.AdditionalCount = binary.BigEndian.Uint16(data[10:12])
pos := 12
if questionCount > 0 {
return fmt.Errorf("is question, unsupported")
}
l.Questions = nil
for i := uint16(0); i < questionCount; i++ {
q := nbnsQuestion{}
var read int
q.Query, read = dnsQueryDecode(data, pos)
if read <= 0 {
return fmt.Errorf("invalid string")
}
pos += read
q.Type = binary.BigEndian.Uint16(data[pos+0 : pos+2])
q.Class = binary.BigEndian.Uint16(data[pos+2 : pos+4])
pos += 4
l.Questions = append(l.Questions, q)
}
l.Answers = nil
for i := uint16(0); i < answerCount; i++ {
a := nbnsAnswer{}
var read int
a.Query, read = dnsQueryDecode(data, pos)
if read <= 0 {
return fmt.Errorf("invalid string")
}
pos += read
a.Type = binary.BigEndian.Uint16(data[pos+0 : pos+2])
a.Class = binary.BigEndian.Uint16(data[pos+2 : pos+4])
a.TTL = binary.BigEndian.Uint32(data[pos+4 : pos+8])
dataLen := binary.BigEndian.Uint16(data[pos+8 : pos+10])
pos += 10
if a.Type == 0x21 { // NB_STAT
pos2 := pos
nameCount := data[pos2]
pos2++
for j := uint8(0); j < nameCount; j++ {
a.Names = append(a.Names, nbnsAnswerName{
Name: strings.TrimSuffix(string(data[pos2:pos2+15]), " "),
Type: data[pos2+15],
Flags: binary.BigEndian.Uint16(data[pos2+16 : pos2+18]),
})
pos2 += 18
}
}
pos += int(dataLen)
l.Answers = append(l.Answers, a)
}
// TODO: Decode Authorities and Additional Information
return nil
}
func (l *layerNbns) SerializeTo(b gopacket.SerializeBuffer) error {
data, err := b.AppendBytes(12)
if err != nil {
panic(err)
}
binary.BigEndian.PutUint16(data[0:2], l.TransactionID)
if l.IsResponse {
data[3] |= 0x01 << 7
}
data[3] |= l.Opcode << 3
if l.Truncated {
data[3] |= 0x01 << 1
}
if l.Recursion {
data[3] |= 0x01
}
if l.Broadcast {
data[4] |= 0x01 << 4
}
binary.BigEndian.PutUint16(data[4:6], uint16(len(l.Questions)))
binary.BigEndian.PutUint16(data[6:8], uint16(len(l.Answers)))
binary.BigEndian.PutUint16(data[8:10], l.AuthorityCount)
binary.BigEndian.PutUint16(data[10:12], l.AdditionalCount)
for _, q := range l.Questions {
enc := dnsQueryEncode(q.Query)
data, err := b.AppendBytes(len(enc) + 4)
if err != nil {
panic(err)
}
copy(data[:len(enc)], enc)
data = data[len(enc):]
binary.BigEndian.PutUint16(data[0:2], q.Type)
binary.BigEndian.PutUint16(data[2:4], q.Class)
}
// TODO: encode answers, authorities and additional informations
return nil
}
// Source: https://github.com/aler9/landiscover/blob/main/utils.go
// <size>part<size>part
func dnsQueryDecode(data []byte, start int) (string, int) {
var read []byte
toread := uint8(0)
pos := start
for ; true; pos++ {
if pos >= len(data) { // decoding terminated before null character
return "", -1
}
if data[pos] == 0x00 {
if toread > 0 { // decoding terminated before part parsing
return "", -1
}
break // query correctly decoded
}
if toread == 0 { // we need a size or pointer
if len(read) > 0 { // add separator
read = append(read, '.')
}
if (data[pos] & 0xC0) == 0xC0 { // pointer
ptr := int(binary.BigEndian.Uint16(data[pos:pos+2]) & 0x3FFF)
pos++ // skip next byte
substr, subread := dnsQueryDecode(data, ptr)
if subread <= 0 {
return "", -1
}
read = append(read, []byte(substr)...)
break // query correctly decoded
} else { // size
toread = data[pos]
}
} else { // byte inside part
read = append(read, data[pos])
toread--
}
}
return string(read), pos + 1 - start
}
func dnsQueryEncode(in string) []byte {
tmp := strings.Split(in, ".")
l := 0
for _, part := range tmp {
bpart := []byte(part)
l++
l += len(bpart)
}
l++
ret := make([]byte, l)
i := 0
for _, part := range tmp {
bpart := []byte(part)
ret[i] = uint8(len(bpart))
i++
copy(ret[i:], bpart)
i += len(bpart)
}
ret[i] = uint8(0)
return ret
}

@ -12,6 +12,7 @@ import (
"net"
"os"
"proxy/cmd"
nbns "proxy/layer-nbns"
. "proxy/util"
"strconv"
"time"
@ -81,7 +82,7 @@ func main() {
c2, VmReader, VmWriter = cmd.Start(*sockProxy)
go pipeForward(cmd.In)
go pipeForward(cmd.Out)
if NewIP == nil {
if NewIP == nil && !Passthrough {
sendDHCPRequest(dhcp4.Discover, net.IPv4zero)
}
if *sockMain != "-" {
@ -121,6 +122,17 @@ func pipeForward(prefix string) {
WritePcap("/tmp/pkg_"+strconv.FormatInt(time.Now().Unix(), 10)+".pcap", frameBytes)
}
// Forward original frame to other plug
if Passthrough {
if _, err := writer.Write(frameLength); err != nil {
log.Error("Error forwarding original packet length", err)
}
if _, err := writer.Write(frameBytes); err != nil {
log.Error("Error forwarding original packet data", err)
}
continue
}
// Convert frame to full stack packet
packet := gopacket.NewPacket(frameBytes, layers.LayerTypeEthernet, gopacket.Default)
@ -136,10 +148,8 @@ func pipeForward(prefix string) {
// Handle DHCPv4 packet (based on IPv4)
if dhcpLayer := packet.Layer(layers.LayerTypeDHCPv4); dhcpLayer != nil {
if !Passthrough {
handleDHCP(dhcpLayer.LayerContents(), frame.DstMAC, frame.SrcMAC, prefix)
continue
}
handleDHCP(dhcpLayer.LayerContents(), frame.DstMAC, frame.SrcMAC, prefix)
continue
}
filterIP(prefix, &ipv4Packet.DstIP, &ipv4Packet.SrcIP, ipv4Packet.LayerType())
@ -164,11 +174,24 @@ func pipeForward(prefix string) {
if err := udpPacket.SetNetworkLayerForChecksum(ipv4Packet); err != nil {
log.Error(prefix, "Error setting network layer for UDP checksum", err)
}
if udpPacket.SrcPort == 137 && udpPacket.DstPort == 137 {
log.Info(prefix, "Trying to decode NBNS payload")
l := nbns.NewLayerNbns()
if err := l.DecodeFromBytes(udpPacket.Payload); err != nil {
log.Warning("Error decoding NBNS: ", err)
}
print(l)
}
if udpPacket.SrcPort == 138 && udpPacket.DstPort == 138 {
log.Info(prefix, "NBDS payload, not implemented (yet)")
}
}
}
// Drop IPv6 packets
if ipv6layer := packet.Layer(layers.LayerTypeIPv6); ipv6layer != nil && !Passthrough {
if ipv6layer := packet.Layer(layers.LayerTypeIPv6); ipv6layer != nil {
log.Info(prefix, "IPv6 packet dropped")
continue
}
@ -183,17 +206,6 @@ func pipeForward(prefix string) {
log.Debug("End packet")
// Forward original frame to other plug
if Passthrough {
if _, err := writer.Write(frameLength); err != nil {
log.Error("Error forwarding original packet length", err)
}
if _, err := writer.Write(frameBytes); err != nil {
log.Error("Error forwarding original packet data", err)
}
continue
}
// Serialize packet back to binary
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{ComputeChecksums: true, FixLengths: true}

@ -39,10 +39,10 @@ start)
$qemu -m 512 -nic vde,mac='52:54:00:12:34:66',sock=$RUN/sw_proxy2.sock -hda alpine2.qcow2 -daemonize -vnc :2 -pidfile $alpine2
;;&
win1 | win | vms | all)
$qemu -vga cirrus -smp 1 -net nic,model=rtl8139 -net vde,sock=$RUN/sw_proxy1.sock -soundhw sb16 -m 128 -usb -usbdevice tablet -drive file=images/win98.raw,format=raw,index=0,media=disk -daemonize -vnc :1 -pidfile $win1
$qemu -vga cirrus -smp 1 -net nic,model=rtl8139 -net vde,sock=$RUN/sw_proxy1.sock -soundhw sb16 -m 128 -usb -usbdevice tablet -drive file=images/win98.raw,format=raw,index=0,media=disk -cdrom images/Win98SE.iso -daemonize -vnc :1 -pidfile $win1
;;&
win2 | win | vms | all)
$qemu -vga cirrus -smp 1 -net nic,model=rtl8139 -net vde,sock=$RUN/sw_proxy2.sock -soundhw sb16 -m 128 -usb -usbdevice tablet -drive file=images/win98-2.raw,format=raw,index=0,media=disk -daemonize -vnc :2 -pidfile $win2
$qemu -vga cirrus -smp 1 -net nic,model=rtl8139,macaddr='52:54:00:12:34:66' -net vde,sock=$RUN/sw_proxy2.sock -soundhw sb16 -m 128 -usb -usbdevice tablet -drive file=images/win98-2.raw,format=raw,index=0,media=disk -cdrom images/Win98SE.iso -daemonize -vnc :2 -pidfile $win2
;;&
kali | vms | all)
$qemu -m 1024 -nic user -nic vde,mac='52:54:00:12:34:76',sock=$RUN/sw_proxy3.sock -hda kali.qcow2 -daemonize -vnc :3 -pidfile $kali