Compare commits

...

4 commits

Author SHA1 Message Date
evilsocket
1001cea8f2 misc: small fix or general refactoring i did not bother commenting
Some checks are pending
Build and Push Docker Images / docker (push) Waiting to run
Linux tests / build (1.24.x, ubuntu-latest) (push) Waiting to run
macOS tests / build (1.24.x, macos-latest) (push) Waiting to run
Windows tests / build (1.24.x, windows-latest) (push) Waiting to run
2025-08-23 17:12:07 +02:00
evilsocket
204997c8b5 misc: small fix or general refactoring i did not bother commenting
Some checks are pending
Build and Push Docker Images / docker (push) Waiting to run
Linux tests / build (1.24.x, ubuntu-latest) (push) Waiting to run
macOS tests / build (1.24.x, macos-latest) (push) Waiting to run
Windows tests / build (1.24.x, windows-latest) (push) Waiting to run
2025-08-23 14:22:11 +02:00
evilsocket
4ec2753fad releasing version 2.41.4
Some checks failed
Build and Push Docker Images / docker (push) Has been cancelled
Linux tests / build (1.24.x, ubuntu-latest) (push) Has been cancelled
macOS tests / build (1.24.x, macos-latest) (push) Has been cancelled
Windows tests / build (1.24.x, windows-latest) (push) Has been cancelled
2025-08-18 19:15:44 +02:00
evilsocket
42da612113 hotfix: hotfix 2 for tcp.proxy 2025-08-18 19:14:05 +02:00
4 changed files with 78 additions and 55 deletions

View file

@ -16,6 +16,8 @@
<a href="https://github.com/bettercap/bettercap/actions/workflows/test-on-macos.yml"><img alt="Tests on macOS" src="https://github.com/bettercap/bettercap/actions/workflows/test-on-macos.yml/badge.svg"></a>
<a href="https://github.com/bettercap/bettercap/actions/workflows/test-on-windows.yml"><img alt="Tests on Windows" src="https://github.com/bettercap/bettercap/actions/workflows/test-on-windows.yml/badge.svg"></a>
<a href="https://hub.docker.com/r/bettercap/bettercap"><img alt="Docker Hub" src="https://img.shields.io/docker/v/bettercap/bettercap?logo=docker"></a>
<img src="https://img.shields.io/badge/human-coded-brightgreen?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmZmZmYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1wZXJzb24tc3RhbmRpbmctaWNvbiBsdWNpZGUtcGVyc29uLXN0YW5kaW5nIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjUiIHI9IjEiLz48cGF0aCBkPSJtOSAyMCAzLTYgMyA2Ii8+PHBhdGggZD0ibTYgOCA2IDIgNi0yIi8+PHBhdGggZD0iTTEyIDEwdjQiLz48L3N2Zz4=" alt="This project is 100% made by humans."/>
</p>
</p>

View file

@ -2,7 +2,7 @@ package core
const (
Name = "bettercap"
Version = "2.41.3"
Version = "2.41.4"
Author = "Simone 'evilsocket' Margaritelli"
Website = "https://bettercap.org/"
)

View file

@ -1,6 +1,7 @@
package tcp_proxy
import (
"encoding/json"
"net"
"strings"
@ -62,60 +63,29 @@ func (s *TcpProxyScript) OnData(from, to net.Addr, data []byte, callback func(ca
}
func toByteArray(ret interface{}) []byte {
// Handle different array types that otto.Export() might return
switch v := ret.(type) {
case []interface{}:
// Mixed type array
result := make([]byte, len(v))
for i, elem := range v {
if num, ok := toNumber(elem); ok && num >= 0 && num <= 255 {
result[i] = byte(num)
} else {
log.Error("array element at index %d is not a valid byte value %+v", i, elem)
return nil
}
}
return result
case []int64:
// Array of integers
result := make([]byte, len(v))
for i, num := range v {
if num >= 0 && num <= 255 {
result[i] = byte(num)
} else {
log.Error("array element at index %d is not a valid byte value %d", i, num)
return nil
}
}
return result
case []float64:
// Array of floats
result := make([]byte, len(v))
for i, num := range v {
if num >= 0 && num <= 255 {
result[i] = byte(num)
} else {
log.Error("array element at index %d is not a valid byte value %f", i, num)
return nil
}
}
return result
default:
log.Error("unexpected array type returned from onData: %T, value = %+v", ret, ret)
return nil
}
}
// this approach is a bit hacky but it handles all cases
// toNumber tries to convert an interface{} to a float64
func toNumber(v interface{}) (float64, bool) {
switch n := v.(type) {
case float64:
return n, true
case int64:
return float64(n), true
case int:
return float64(n), true
default:
return 0, false
// serialize ret to JSON
if jsonData, err := json.Marshal(ret); err == nil {
// attempt to deserialize as []float64
var back2Array []float64
if err := json.Unmarshal(jsonData, &back2Array); err == nil {
result := make([]byte, len(back2Array))
for i, num := range back2Array {
if num >= 0 && num <= 255 {
result[i] = byte(num)
} else {
log.Error("array element at index %d is not a valid byte value %d", i, num)
return nil
}
}
return result
} else {
log.Error("failed to deserialize %+v to []float64: %v", ret, err)
}
} else {
log.Error("failed to serialize %+v to JSON: %v", ret, err)
}
return nil
}

View file

@ -116,3 +116,54 @@ func TestOnData_ReturnsDynamicArray(t *testing.T) {
}
}
}
func TestOnData_ReturnsMixedArray(t *testing.T) {
jsCode := `
function charToInt(value) {
return value.charCodeAt()
}
function onData(from, to, data) {
st_data = String.fromCharCode.apply(null, data)
if( st_data.indexOf("mysearch") != -1 ) {
payload = "mypayload";
st_data = st_data.replace("mysearch", payload);
res_int_arr = st_data.split("").map(charToInt) // []uint16
res_int_arr[0] = payload.length + 1; // first index is float64 and rest []uint16
return res_int_arr;
}
return data;
}
`
plug, err := plugin.Parse(jsCode)
if err != nil {
t.Fatalf("Failed to parse plugin: %v", err)
}
script := &TcpProxyScript{
Plugin: plug,
doOnData: plug.HasFunc("onData"),
}
from := &net.TCPAddr{IP: net.ParseIP("192.168.1.1"), Port: 1234}
to := &net.TCPAddr{IP: net.ParseIP("192.168.1.6"), Port: 5678}
data := []byte("Hello mysearch world")
result := script.OnData(from, to, data, nil)
expected := []byte("\x0aello mypayload world")
if result == nil {
t.Fatal("Expected non-nil result when callback returns array of integers")
}
if len(result) != len(expected) {
t.Fatalf("Expected result length %d, got %d", len(expected), len(result))
}
for i, b := range result {
if b != expected[i] {
t.Errorf("Expected byte at index %d to be %d, got %d", i, expected[i], b)
}
}
}