Get TCP response from server - python

I have a program (.exe) that gets certain info from a server, and I wanted to be able to get that info from the command line too. I started netcat and listened on the port the program uses to communicate with its target, because I wanted to know what "requests" to make from a script, and I received this over netcat, plain text:
net.tcp://[my ip address]:41012/Lapis.Btouch/ServerInfo
I tried sending exactly that to the target (replacing my IP for its IP) using socket.send() but it wouldn't return anything. What does that mean and how can I get the data?
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('[server ip address]',41012))
while True:
s.send('net.tcp://[server ip address]:41012/Lapis.Btouch/ServerInfo')
response = s.recv(1024)
print response
s.close()
That's the code I'm using to send the request to the target server. It won't return anything, so I think I'm not making the request in the right way. Thanks for any help.

Try capture your network packet on port 41012, via tcpdump or wireshark or ...
Then check:
does your code send the request?
does the response returned to you?
If the answer for question (1) is False, problem is side of you and your machine. so go and solve it (review your code, check your firewall and ...)
If the answer of question (1) is True, but server doesn't send any response (this case often not happened) review your request format (check you URL or test it via browser or ...). also based on the server you connect to, maybe needed to your machine's IP recognized for server (I mean some server only give response to requests, that come from known IP addresses, in this case you need introduce yourself to server (e.g. add your IP to trusted list on server), before sending request)
Last case, if answer of both questions are correct (I guess it's your problem), you most correct your code (response = s.recv(1024)) why do you used 1024 for your response length?. Use correct and accurate parameters.
In python exist several methods for receiving response via socket (from server), search stackoverflow and you can find useful tips and commands. commands like use non-blocking ways, ascync ways and ...

Related

Python socket.recv hanging

I'm trying to retrieve data from a PLC (AutomationDirect P2000). I have set up the PLC as the server with their software program (I can also connect to it with their software via Ethernet and use Wireshark to see it is in fact sending UDP packets to my machine at roughly every 200ms). I am trying to set up a very simple Python script to retrieve said data, without bothering to encode it or do anything with it, but my program hangs at the socket.recv(). Whenever I try to run it "Got here" will be printed, but "Now here" will not. From what I've read the fact that it hangs means there's no data to be received, but from my (limited) understanding of what I see on Wireshark this is not the case. I am pretty new to all of this and would appreciate any help.
I have tried using socket.recvfrom(), which produces the same result. I've also tried using socket.bind() instead of socket.connect() but I get a "The requested address is not valid in its context" exception. Additionally, I've tried playing around with various IPs and ports. For example, I've tried using IP = '' instead of the actual IP, and I've tried the source/destination information from Wireshark as what I try to bind or connect to, but nothing thus far has worked.
import socket
IP = '192.168.3.1'
PORT = 9999
BUFFER_SIZE = 4096
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((IP, PORT))
while True:
print("Got here")
data = s.recv(BUFFER_SIZE)
print("Now here")
print(f"Received {data}")
I am expecting to get a print out of the packet in byte format, but instead the program is hanging. If I try socket.bind() instead of socket.connect() I get an error message reading "...line 8, in
s.bind((IP, PORT))
OSError: [WinError 10049] The requested address is not valid in its context"
you can't use bind like this, because the ip address does not belong to your PC.
when you connect to the server, it (the server) doesn't send anything, but you try to get data from the server, so the socket awaits until it gets data, and only then it will continue the execution (this is called a blocking function, since it blocks the execution until it finishes).
The issue was with how I set up the PLC as the server. The UDP data I was seeing on port 9999 wasn't the communications I was thinking it was, and was only the inherent communication between the PLC and the network via its proprietary program. For anyone curious, I am using a P2000 PLC from AutomationDirect and initially I set it up as an EtherNet/IP Adapter following one of their videos, but I had to use the Custom Protocol over Ethernet functionality provided in the "Communications" section.

SMTP server in Python using sockets is apparently inaccessible through Gmail

I decided to play around with the SMTP and wrote a very simple test script in Python:
import socket
sock = socket.socket()
sock.bind(("",25))
sock.listen(1)
print("Server started...")
while True:
conn,addr = sock.accept()
print(addr,"connected")
print(conn.recv(4096))
conn.close()
The script does exactly what I want it to do when I connect to it via ncat: it prints out the data it gets, then closes. I also set up my router to forward connections on port 25 to my computer, so it should be able to be accessed externally.
However, when I send an email via Gmail to test#<my ip address>, I never receive it. Why does this happen?
I understand that there is a SMTP library for Python, but I'm not trying to make a serious mail server, I just want to learn how it works.
As I have said before, I don't understand SMTP very well, but I was under the assumption that it would work pretty much like any other network protocol and I would be able to at least print out the request I would get using this program.
The text, test#<my ip address> isn't a valid syntax for an email address.
Assuming that your ip address is, say, 198.51.100.43, try this email address:
test#[198.51.100.43]
References:
https://www.ietf.org/rfc/rfc2822.txt
https://www.ietf.org/rfc/rfc2821.txt , section 4.1.3
As I have said before, I don't understand SMTP very well, but I was under the assumption that it would work pretty much like any other network protocol and I would be able to at least print out the request I would get using this program.
I suggest that your understanding of "pretty much like any other network protocol" is too much influenced by HTTP. Because all the classic protocols like SMTP, FTP, IMAP, POP, NNTP ... consist of several handshakes between client and server and the first one for all of these protocols is a message from the server. Which means that the SMTP client will connect to the server and time out after a while because the initial greeting was not received.
For the basic specification of SMTP see RFC 2821, but there will be others to read if you want to support TLS and other extensions.

Identifying services listening on remote ports

I'd like to elaborate a little bit on this question and, particularly, on this answer. Let's suppose I have a fixed list of services to check, say: ('ftp', 'ssh', 'http'). Opening a socket to port 22 of a remote server:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = s.connect_ex(('my_remote_server', 22))
if(result == 0) :
print s.recv(256)
s.close()
I get the following output:
'SSH-2.0-OpenSSH_6.1p1 Debian-4\r\n'
So I can guess there's a ssh service listening on that port. Therefore my question is: where or how can I find the welcome messages (or similar) for different kind of services? Are these regulated in some way? In the case of ssh, does it always start with SSH-?
The response you get from a server depens both on the exact protocol and server configuration.
HTTP has a Server header for example, but many server out on the internet lies about what server is responding, to throw off malicious hackers trying to exploit server-specific flaws. Moreover, the server remains silent until the client has sent a request; your code has to send something before there is any response.
The best you can do is try out different protocols and see if the other side responds sensibly. Trying to send an SSH handshake to a HTTP port is likely to result in a HTTP/1.0 400 Bad Request response, for example.
In other words, there is no ready-made solution for this, you'll have to create your own heuristics based on what protocols you are trying to detect.
The best you can do is probably search for the string ssh(/ftp/http) and conclude based on that.
Even that would be a guess, of course, as this can usually be changed(see here) with a config parameter and it is considered good security practice to change it so as to not expose the server program/version.

Simple python localhost proxy - almost working

I'm working on a slightly larger project of my own and I need to make a localhost proxy in python.
The way I wrote mine is that there's a TCP server (using socket and SOCK_STREAM) on port 8080 on the localhost. It accepts a request from the local host, using slicing, string.find(), and gethostbyname() finds that target IP, so it opens up another TCP socket, sends the request and recv's a reply. After that, it relays the reply back to the localhost proxy which in turn throws it back at the browser.
This is the code with ample debugging messages and a debug file to collect the requests of the browser and the replies received back (also note this is just a prototype, hence the limited for loop instead of a while 1 loop):
import socket
local = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
f = open('test.txt', 'a')
local.bind(('localhost', 8080))
local.listen(5)
for i in xrange(20):
print '=====%d=====\n' % i
out = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data, addr = local.accept()
print 'Connection accepted'
buffer = data.recv(4096)
print 'data recieved'
f.write('=============================================================\n')
f.write(buffer)
end = buffer.find('\n')
print buffer
#print buffer[:end]
host = buffer[:end].split()[1]
end = host[7:].find('/')
print host[7:(end+7)]
host_ip = socket.gethostbyname(host[7:(end+7)])
#print 'remote host: ' + host + ' IP: ' + host_ip
print 'sending buffer to remote host'
out.connect((host_ip, 80))
out.sendall(buffer)
print 'recieving data from remote host'
reply = out.recv(4096)
out.close()
print 'data recieved from remote host'
f.write('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n')
f.write(reply)
f.write('\n\n\n')
print 'sending data back to local host'
data.sendall(reply)
print 'data sent'
local.close()
out.close()
f.close()
Now my problem is that it seems to work fine for the first few requests, it gets the html and a few images but at some point it always stops at the "data received" point and quits, because it gets no data ie. the buffer is empty. The browser still shows it's loading elements of the page, but when it stops and I look at the text log file, I see that the buffer was empty, meaning that the browser didn't submit anything to the proxy?
I am guessing that the issue lies somewhere in how a browser submits requests and my script not reacting properly to this behavior.
I know I could use the Twist framework, however I want to learn to write this kinda stuff myself. I've been reading about SocketServer and I might use that, but I have no clue if it'll solve the issue because frankly, I don't really understand what's causing the issue here. Is my script too slow for the browser? Do servers send more than one answer and my receiving socket should listen for more packets? Is my buffer size (4096) too small?
I'd really appreciate a nudge in the right direction.
Thanks!
Well, I managed to answer my question. What I suspected previously was partly true - the browser was waiting for something and that something was replies.
I fired up wire shark, did some experiments and I noticed that my proxy makes a lot of ugly TCP RST appear in wireshark. I also noticed that in a normal connection, a lot of the server replies are split up into a few different packets.
Basically, my program wasn't getting all the answers back from the server because the out.recv was getting just one part of the reply. The obvious answer was to make a loop and listen for all the replies. I found the perfect solution at http://www.binarytides.com/receive-full-data-with-the-recv-socket-function-in-python/ .
I quickly recoded my program a bit and it works like a charm. Now I can move on forward with my whole project.
I hope this might help anyone else in the future with a similar issue.

Packet spoofing using python

I'm trying to write a proof of concept code, which will automatically spoof packets to a thick-client application.
I've chosen python as the language of choice. I have found resources to help me monitor for packets using scapy or other similar libraries.
How do I go about spoofing the packet.
Eg. Scenario :
Client C, Server S
C sends get request R(HTTP) to S
Proxy_python intercepts request R
Proxy_python crafts a HTTP response (r)
Proxy_python sends r to C
Essentially a MiTm on C. Is this possible. One condition to note is that, the proxy i'm writing should not need any configuration to get redirected to. It should ubiquotously listen for all packets.
Which makes me ask me another question : Can I make the python proxy listen to a particular PID ?
At least to answer the question regarding whether you can tie a PID to the packets being sent, this is not something that is explicitly included within the packet data. However, you can determine which port the process is sending traffic on and associate packets on that port to the process. I would reference this question for some information on how to get that port info. Hope this helps a little, not sure exactly what else you are looking for at the moment.

Categories

Resources