This commit is contained in:
xvzc 2024-08-14 17:01:14 +09:00
parent c76e21cec0
commit 7f1ad9e7ec
6 changed files with 85 additions and 111 deletions

View File

@ -53,11 +53,7 @@ type HttpPacket struct {
version string
}
func ParseUrl(raw []byte) {
}
func NewHttpPacketFromReader(rdr io.Reader) (*HttpPacket, error) {
func ReadHttpPacket(rdr io.Reader) (*HttpPacket, error) {
sb := strings.Builder{}
tee := io.TeeReader(rdr, &sb)
p := &HttpPacket{}

View File

@ -1,15 +1,66 @@
package packet
type HttpsPacket struct {
raw []byte
import (
"encoding/binary"
"io"
)
type TLSMessageType byte
const (
TLSHeaderLen = 5
TLSInvalid TLSMessageType = 0x0
TLSChangeCipherSpec TLSMessageType = 0x14
TLSAlert TLSMessageType = 0x15
TLSHandshake TLSMessageType = 0x16
TLSApplicationData TLSMessageType = 0x17
TLSHeartbeat TLSMessageType = 0x18
)
type TLSMessage struct {
Header TLSHeader
Raw []byte //Header + Payload
RawHeader []byte
RawPayload []byte
}
func NewHttpsPacket(raw []byte) HttpsPacket {
return HttpsPacket{
raw: raw,
type TLSHeader struct {
Type TLSMessageType
ProtoVersion uint16 // major | minor
PayloadLen uint16
}
func ReadTLSMessage(r io.Reader) (*TLSMessage, error) {
var rawHeader [TLSHeaderLen]byte
_, err := io.ReadFull(r, rawHeader[:])
if err != nil {
return nil, err
}
header := TLSHeader{
Type: TLSMessageType(rawHeader[0]),
ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]),
PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]),
}
raw := make([]byte, header.PayloadLen+TLSHeaderLen)
copy(raw[0:TLSHeaderLen], rawHeader[:])
_, err = io.ReadFull(r, raw[TLSHeaderLen:])
if err != nil {
return nil, err
}
hello := &TLSMessage{
Header: header,
Raw: raw,
RawHeader: raw[:TLSHeaderLen],
RawPayload: raw[TLSHeaderLen:],
}
return hello, nil
}
func (p *HttpsPacket) Raw() []byte {
return p.raw
func (m *TLSMessage) IsClientHello() bool {
// According to RFC 8446 section 4.
// first byte (Raw[5]) of handshake message should be 0x1 - means client_hello
return m.Header.Type == TLSHandshake && m.Raw[5] == 0x01
}

View File

@ -1,66 +0,0 @@
package proxy
import (
"encoding/binary"
"io"
)
const headerLen = 5
type TLSMessageType byte
const (
TLSInvalid TLSMessageType = 0x0
TLSChangeCipherSpec TLSMessageType = 0x14
TLSAlert TLSMessageType = 0x15
TLSHandshake TLSMessageType = 0x16
TLSApplicationData TLSMessageType = 0x17
TLSHeartbeat TLSMessageType = 0x18
)
type TlsMessage struct {
Header TlsHeader
Raw []byte //Header + Payload
RawHeader []byte
RawPayload []byte
}
type TlsHeader struct {
Type TLSMessageType
ProtoVersion uint16 // major | minor
PayloadLen uint16
}
func ReadTlsMessage(r io.Reader) (*TlsMessage, error) {
var rawHeader [5]byte
_, err := io.ReadFull(r, rawHeader[:])
if err != nil {
return nil, err
}
header := TlsHeader{
Type: TLSMessageType(rawHeader[0]),
ProtoVersion: binary.BigEndian.Uint16(rawHeader[1:3]),
PayloadLen: binary.BigEndian.Uint16(rawHeader[3:5]),
}
raw := make([]byte, header.PayloadLen+headerLen)
copy(raw[0:headerLen], rawHeader[:])
_, err = io.ReadFull(r, raw[headerLen:])
if err != nil {
return nil, err
}
hello := &TlsMessage{
Header: header,
Raw: raw,
RawHeader: raw[:headerLen],
RawPayload: raw[headerLen:],
}
return hello, nil
}
func IsClientHello(message *TlsMessage) bool {
// According to RFC 8446 section 4.
// first byte (Raw[5]) of handshake message should be 0x1 - means client_hello
return message.Header.Type == TLSHandshake &&
message.Raw[5] == 0x1
}

View File

@ -45,8 +45,8 @@ func (pxy *Proxy) handleHttps(lConn *net.TCPConn, exploit bool, initPkt *packet.
log.Debug("[HTTPS] Sent 200 Connection Estabalished to ", lConn.RemoteAddr())
// Read client hello
m, err := ReadTlsMessage(lConn)
if err != nil || !IsClientHello(m) {
m, err := packet.ReadTLSMessage(lConn)
if err != nil || !m.IsClientHello() {
log.Debug("[HTTPS] Error reading client hello from the client", err)
return
}
@ -55,24 +55,18 @@ func (pxy *Proxy) handleHttps(lConn *net.TCPConn, exploit bool, initPkt *packet.
log.Debug("[HTTPS] Client sent hello ", len(clientHello), "bytes")
// Generate a go routine that reads from the server
chPkt := packet.NewHttpsPacket(clientHello)
// lConn.SetLinger(3)
// rConn.SetLinger(3)
go Serve(rConn, lConn, "[HTTPS]", rConn.RemoteAddr().String(), initPkt.Domain(), pxy.timeout, pxy.bufferSize)
if exploit {
log.Debug("[HTTPS] Writing chunked client hello to ", initPkt.Domain())
chunks := splitInChunks(chPkt.Raw(), pxy.windowSize)
if _, err := WriteChunks(rConn, chunks); err != nil {
chunks := splitInChunks(clientHello, pxy.windowSize)
if _, err := writeChunks(rConn, chunks); err != nil {
log.Debug("[HTTPS] Error writing chunked client hello to ", initPkt.Domain(), err)
return
}
} else {
log.Debug("[HTTPS] Writing plain client hello to ", initPkt.Domain())
if _, err := rConn.Write(chPkt.Raw()); err != nil {
if _, err := rConn.Write(clientHello); err != nil {
log.Debug("[HTTPS] Error writing plain client hello to ", initPkt.Domain(), err)
return
}
@ -116,3 +110,18 @@ func splitInChunks(bytes []byte, size int) [][]byte {
return [][]byte{raw[:1], raw[1:]}
}
func writeChunks(conn *net.TCPConn, c [][]byte) (n int, err error) {
total := 0
for i := 0; i < len(c); i++ {
b, err := conn.Write(c[i])
if err != nil {
return 0, nil
}
total += b
}
return total, nil
}

View File

@ -13,7 +13,7 @@ import (
"github.com/xvzc/SpoofDPI/util"
)
const BUFFER_SIZE = 1024
const BufferSize = 1024
type Proxy struct {
addr string
@ -33,7 +33,7 @@ func New(config *util.Config) *Proxy {
windowSize: *config.WindowSize,
allowedPattern: config.AllowedPattern,
resolver: dns.NewResolver(config),
bufferSize: BUFFER_SIZE,
bufferSize: BufferSize,
}
}
@ -61,19 +61,15 @@ func (pxy *Proxy) Start() {
}
go func() {
pkt, err := packet.NewHttpPacketFromReader(conn)
if err != nil {
return
}
log.Debug("[PROXY] Request from ", conn.RemoteAddr(), "\n\n", string(pkt.Raw()))
pkt, err := packet.ReadHttpPacket(conn)
if err != nil {
log.Debug("[PROXY] Error while parsing request: ", string(pkt.Raw()))
conn.Close()
return
}
log.Debug("[PROXY] Request from ", conn.RemoteAddr(), "\n\n", string(pkt.Raw()))
if !pkt.IsValidMethod() {
log.Debug("[PROXY] Unsupported method: ", pkt.Method())
conn.Close()

View File

@ -9,19 +9,7 @@ import (
log "github.com/sirupsen/logrus"
)
func WriteChunks(conn *net.TCPConn, c [][]byte) (n int, err error) {
total := 0
for i := 0; i < len(c); i++ {
b, err := conn.Write(c[i])
if err != nil {
return 0, nil
}
total += b
}
return total, nil
}
const TLSHeaderLen = 5
func ReadBytes(conn *net.TCPConn, dest []byte) ([]byte, error) {
n, err := readBytesInternal(conn, dest)