Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gotls shared object not supported #549

Closed
AmmeySaini opened this issue May 19, 2024 · 11 comments
Closed

gotls shared object not supported #549

AmmeySaini opened this issue May 19, 2024 · 11 comments
Labels
help wanted Extra attention is needed wontfix This will not be worked on

Comments

@AmmeySaini
Copy link

Describe the bug
I'm not sure if this is a bug or is not supported.

To Reproduce
Steps to reproduce the behavior:
./ecapture gotls --elfpath="tls-client-x86.so" --hex

Expected behavior
No TLS or HTTPS request gets intercepted while using a GO compiled .so file

Linux Server/Android (please complete the following information):

  • Env: Linux
  • OS: Ubuntu 22.04
  • Arch: x86_64
  • Kernel Version: 6.5.0-35-generic

Additional context
I have the compiled GO code into .so format which I use to load through the Python environment and make the HTTPS/TLS requests, however after running the above command no traffic is captured by ecapture.

@cfc4n
Copy link
Member

cfc4n commented May 20, 2024

Please give more detailed error information.

@cfc4n cfc4n added the help wanted Extra attention is needed label May 21, 2024
@AmmeySaini
Copy link
Author

I'm using tls-client lib with Python (a wrapper around GO shared object)

tls-client library link (.so file)

Python code example here link
The above Python code loads the .so file compiled from the GO code into the memory and then is used to execute the requests at the GO side

what I'm doing with ecapture is:

  1. Start capturing using the shared object file.
    ./ecapture gotls --elfpath="tls-client-x86.so" --hex
  2. Start the Python script as normal (load tls-client-x86.so in memory)
  3. Make TLS/HTTPS requests through the compiled .so file, commands are passed from the Python code, but requests are made at the GO side.

After all the above processes there is no traffic being intercepted by ecapture. (I'm not sure if .so also needs linking with the Python or maybe some extra stuff is also required)

@cfc4n
Copy link
Member

cfc4n commented May 22, 2024

eCapture can correctly analyze this dynamic link library and correctly find the offset address of the symbol crypto/tls.(*Conn).Read.

However, it did not capture this communication. I am unable to determine where the issue lies, and I also do not have the time to analyze this library. I suggest you debug it yourself to confirm whether the crypto/tls functions are not being used.

sudo bin/ecapture gotls -m text --elfpath=/home/cfc4n/project/python-test/tls-client-linux-arm64-1.7.5.so
[sudo] password for cfc4n:
2024-05-22T14:44:45Z INF AppName="eCapture(旁观者)"
2024-05-22T14:44:45Z INF HomePage=https://ecapture.cc
2024-05-22T14:44:45Z INF Repository=https://github.com/gojue/ecapture
2024-05-22T14:44:45Z INF Author="CFC4N <cfc4ncs@gmail.com>"
2024-05-22T14:44:45Z INF Description="Capturing SSL/TLS plaintext without a CA certificate using eBPF. Supported on Linux/Android kernels for amd64/arm64."
2024-05-22T14:44:45Z INF Version=linux_arm64:0.7.7-20240303-bfb4a8c:5.15.0-105-generic
2024-05-22T14:44:45Z INF listen=localhost:28256
2024-05-22T14:44:45Z INF https server starting...You can update the configuration file via the HTTP interface.
2024-05-22T14:44:45Z WRN ========== module starting. ==========
2024-05-22T14:44:45Z INF Kernel Info=5.15.148 Pid=231170
2024-05-22T14:44:45Z INF BTF bytecode mode: CORE. btfMode=0
2024-05-22T14:44:45Z INF GoTlsProbe init keylogFile= model=Text
2024-05-22T14:44:45Z INF module initialization. isReload=false moduleName=EBPFProbeGoTLS
2024-05-22T14:44:45Z INF Module.Run()
2024-05-22T14:44:45Z INF HOOK type:Golang elf GoVersion=go1.20 binrayPath=/home/cfc4n/project/python-test/tls-client-linux-arm64-1.7.5.so buildInfo=" -buildmode=c-shared -compiler=gc CGO_ENABLED=1 GOARCH=arm64 GOOS=linux vcs=git vcs.revision=a0890ed4f1cd67d5e33ffcb2985c7620c3432eb9 vcs.time=2024-05-01T17:59:26Z vcs.modified=true" isRegisterABI=true
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=286848
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=286870
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=2868D4
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=2869F0
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=286A20
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=286A80
2024-05-22T14:44:45Z INF golang uretprobe added. function=crypto/tls.(*Conn).Read offset=286A9C
2024-05-22T14:44:45Z INF target all process.
2024-05-22T14:44:45Z INF target all users.
2024-05-22T14:44:45Z INF BPF bytecode file is matched. bpfFileName=user/bytecode/gotls_kern_core.o
2024-05-22T14:44:45Z INF perfEventReader created mapSize(MB)=4
2024-05-22T14:44:45Z INF module started successfully. isReload=false moduleName=EBPFProbeGoTLS

@AmmeySaini
Copy link
Author

Thanks for the update, I'll debug the library this weekend,
can you also confirm if you tested the Python side of the code using this link or if there is any other example code you used please refer me the link.
Thanks

@cfc4n
Copy link
Member

cfc4n commented May 24, 2024

Yes, my test code also used this link.

@cfc4n cfc4n closed this as completed May 25, 2024
@AmmeySaini
Copy link
Author

I did debug the library and I can confirm the crypto/tls is being used in the lib.

There are multiple methods for crypto/tls being used when we submit a request to the client, but ecapture is not able to intercept any.
I'm also not sure why you marked this issue as completed and closed this but the issue is probably somewhere with ecapture not being able to capture the communication.

@cfc4n cfc4n reopened this May 26, 2024
@cfc4n
Copy link
Member

cfc4n commented May 26, 2024

I think this may not be related to eCapture; if you need it, you can open it. Feel free to share your new findings.

@AmmeySaini
Copy link
Author

I tied all possible ways I could have thought of, but ecapture doesn't seem to hook into the dynamic lib properly though it does find the offset addresses correctly, something doesn't seem to be right while the shared lib is loaded into the memory, and does perform all the crypto/tls operations.

I'm closing this for now because I have managed to directly hook into crypto/tls methods to fetch the SSLKEYLOGFILE from the dynamically loaded lib without ecapture, will probably open it again if I find more on this in the future.

@cfc4n
Copy link
Member

cfc4n commented May 27, 2024

In the source code of the library, it can be seen that it uses a custom TLS handshake packet, instead of the official implementation by golang.

https://github.com/bogdanfinn/tls-client/blob/077a497dc1047d3ed5f53f257af383b334a7a609/roundtripper.go#L154

conn := tls.UClient(rawConn, tlsConfig, rt.clientHelloId, rt.withRandomTlsExtensionOrder, rt.forceHttp1)
if err = conn.HandshakeContext(ctx); err != nil {
_ = conn.Close()

return nil, err
}

err = rt.certificatePinner.Pin(conn, host)

if err != nil {
return nil, err
}

About tls.UClient

tls.UClient used package bogdanfinn/utls , As project introduction

uTLS is a fork of "crypto/tls", which provides ClientHello fingerprinting resistance, low-level access to handshake, fake session tickets and some other features. Handshake is still performed by "crypto/tls", this library merely changes ClientHello part of it and provides low-level access.

So, this is not a flaw of eCapture; you need to study the project and find the appropriate HOOK symbol.

Solution

You can change the hook symbol crypto/tls.(*Config).writeKeyLog to github.com/bogdanfinn/utls.(*Config).writeKeyLog, which may solve your problem.

const (
GoTlsReadFunc = "crypto/tls.(*Conn).Read"
GoTlsWriteFunc = "crypto/tls.(*Conn).writeRecordLocked"
GoTlsMasterSecretFunc = "crypto/tls.(*Config).writeKeyLog"
)

image

@cfc4n
Copy link
Member

cfc4n commented May 27, 2024

It works.
image

@AmmeySaini
Copy link
Author

AmmeySaini commented May 27, 2024

Thanks for looking into it, this works :)

@cfc4n cfc4n added the wontfix This will not be worked on label May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants