Using WMI-Client-Wrapper to execute an exe and get output logs - python

Objective:
I am using Ubuntu 16.04 and am using WMI-CLient-Wrapper module to connect to a remote Windows Machine and send an executable to it(eg. Process Explorer) and further execute it and collect the logs it creates and fetch them back to my Linux Machine for further processing. Using WMI CLient Wrapper is the only option available as WMI Module doesn't work with Linux.
Problem:
I am able to send the file to the remote Windows machine, by establishing a connection using WMI-Client-Wrapper and SMB File Transfer Mechanism. After that when I try to create a Process for the same and try to execute that process it gives me an error stating that some of the attributes that WMI actually has, are not supported by WMI client Wrapper.
What I tried
Python Code:
import os
import wmi_client_wrapper as wmic
from socket import *
import time
wmic = wmic.WmiClientWrapper(
host ="192.168.115.128",
username = "LegalWrongDoer",
password = "sasuke14"
)
SW_SHOWNORMAL = 1
str = "smbclient //192.168.115.128/C$ -U LegalWrongDoer%sasuke14 -c \'put \"procexp64.exe\"\'"
os.system(str)
print("Folder sent")
process_startup = wmic.Win32_ProcessStartup.new()
process_startup.ShowWindow = SW_SHOWNORMAL
process_id, result = wmic.Win32_Process.Create(CommandLine="C:/procexp64.exe", ProcessStartupInformation=process_startup)
process_startup.ShowWindow = SW_SHOWNORMAL
if result == 0:
print("Process started successfully")
else:
print("Sorry, but can't execute Process!")
When I run this python file, it gives me the output to the initial query I make. But the Process_StartUp fails.
Further Traceback Calls:
Traceback (most recent call last):
File "WMIClient.py", line 22, in <module>
process_startup = wmic.Win32_ProcessStartup.new()
AttributeError: 'WmiClientWrapper' object has no attribute 'Win32_ProcessStartup'
I'd be extremely grateful if anyone of you can be able to help me through this. Thanks in advance :)

Well I finally managed to get a work-around for this whole scenario, and it might look a little messy but it sure does work for me.
Firstly I use smbclient to transfer the executable to the end-point where I want to execute it. Inside my code I use os.system() calls to make this happen.
import os
str1 = "smbclient //'<HostMachineIP>'/admin$ -U '<domain>\\<username>%<password>' -c \'lcd /usr/local/acpl/bin/endPoint/; put \"EndPointForeignsics.exe\"\'"
os.system(str1)
This helps me put the executable in desired shared folder that the user has access(Admin in my case) to and then use WMI-query through a tool called Winexe to get access to the console/command prompt of the end-point. I use another os.system() call to execute this again.
str2 = r'/usr/local/bin/winexe -U "<domain>\\<username>%<password>" //<HostMachineIP> "cmd /c c:\windows\EndPointForeignsics.exe '
os.system(str2)
P.S:-- Winexe is a tool that you'll have to download off the internet and compile it. It may take some time and effort to do that, but is quite achievable. You'll get a lot of help on the same from StackOverflow and Documentation of the tool.

Related

Multithreading code is getting executed twice through Robot file

I am running a python multithreaded code which runs only once if i run it through python file but runs twice if i run it through Robot file :
python file code :
def connect():
print("Step 12: Reload devices")
config_threads_list = []
ipAddress = '172.22.12.14'
username = 'abcd'
password = 'abcd'
devices = ['5023','5024','5025','5026']
for ports in devices:
consoleServer, username, password, port = ipAddress, username, password, ports
print ('Creating thread for: ', ports)
config_threads_list.append(threading.Thread(target=obj.router_reload, args=(consoleServer, username, password, port)))
print ('\n---- Begin get config threading ----\n')
for config_thread in config_threads_list:
config_thread.start()
for config_thread in config_threads_list:
config_thread.join()
connect()
this code works fine when i run it through python only . However when i run it through robot framework its running twice
robot file :
Documentation Test case
Library <path to above py file >
*** Test Cases ***
TEST CASE LEL-TC-1
connect
Just to share why it is executed twice when you run the robot file.
You call connect() at the end of the Python file. This is the single invocation when the Python script is executed.
Now when you import the Python file as a library its actually gets executed. So the connect() will be called at the end. That is one.
Then you call it explicitly as a keyword in the test case. That is two.
To avoid this simply remove the connect() call from the end of the Python file.
Thanks to https://stackoverflow.com/users/4180176/joshua-nixon
after using the below mentioned simple/basic yet very effective code my issue has been resolved from robot file as well and code is only getting executed once :
if __name__ == "__main__":
connect()

Copy file from local to remote desktop in Python using subprocess

I am trying to create a program for a project of mine where I needed to copy some files from my local machine to some remote desktop pc's desktop directory. It is a part of automating the whole connecting and copying files to all the remote PCs. I have used subprocess to connect to a remote desktop. As I am a beginner of using subprocess or cmd commands, I am unable to find a way to do this. This is the code:
from pynput.keyboard import Key,Controller
import time
import subprocess
def process_exists(process_name):
call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
output = subprocess.check_output(call)
last_line = output.decode("utf-8").strip().split('\r\n')[-1]
return last_line.lower().startswith(process_name.lower())
#os.system('cmd /k "mstsc /v:192.168.0.107"')
#os.system('cmd /c "notepad"')
from subprocess import Popen
p = Popen('mstsc /v:192.168.0.107')
time.sleep(1)
keyboard = Controller()
# Password is given here
for i in range(10):
if process_exists('mstsc.exe'):
time.sleep(1)
keyboard.type("**********")
keyboard.press(Key.enter)
time.sleep(0.12)
break
time.sleep(3)
Here I used subprocess just to connect to that remote PC. I tried
Popen(r'copy /Y "E:\test.jar" "\\192.168.0.107\c\"')
But it didn't help. Though I didn't know the basic of this line. The error it showed was:
FileNotFoundError: [WinError 2] The system cannot find the file specified
This code is only for test, that's why I used only time delay, didn't check whether it ran correctly.
The remote desktop started successfully. But unable to start the copying process.
Sorry for my bad English. Thanks in advance

ValueError: I/O operation on closed file python flask

I am having a problem with python code. In main thread i am creating a new threading holding a flask api with:
thread = Thread(target=app.run, kwargs={'host':'127.0.0.1', 'port':5000, 'debug':False, 'use_reloader':False})
then in main thread i have i while loop waiting for commands from terminal with:
while True:
command = input("> ")
the problem is that after some commands i get:
File "run.py", line 44, in cli_app
command = input("> ")
ValueError: I/O operation on closed file.
although my cli is still on and i can communicate from other terminals, that client can no longer create a command.
all i found was about opening csv files, thats why i am asking.
thanks in advace.
Are you trying to create terminal commands in flask, right? so flask have a decorators to make this easy :
import click
from flask import Flask
app = Flask(__name__)
#app.cli.command("create-user")
#click.argument("name")
def create_user(name):
#logic
return
And to Run this command you only need to write this command in terminal flask create-user admin, the first arg is the function and the second is the value(dont forget to use in this, you need to set FLASK_APP), for a complete doc look this flask doc
The other way, if you are using multiple server in same host, create a route like commands, and to call this command access the url.
#app.route("/user")
def create_user():
name= request.args.get('name')
#logic
return
And call it in url localhost:5001/user?name=Thomas
And create a script to run every server in background(i dont now if you are using gunicorn, so i use vallina thread pool`, and i using linux terminal)
nohup python server1/main.py &
nohup python server2/main.py &
nohup python server3/main.py &
nohup python server4/main.py &
nohup python server5/main.py &

Executable out of script containing serial_for_url

I have developed a python script for making a serial communication to a digital pump. I now need to make an executable out of it. However even though it works perfectly well when running it with python and py2exe does produce the .exe properly when I run the executable the following error occurs:
File: pump_model.pyc in line 96 in connect_new
File: serial\__init__.pyc in line 71 in serial_for_url
ValueError: invalid URL protocol 'loop' not known
The relevant piece of my code is the following:
# New serial connection
def connect_new(self, port_name):
"""Function for configuring a new serial connection."""
try:
self.ser = serial.Serial(port = port_name,\
baudrate = 9600,\
parity = 'N',\
stopbits = 1,\
bytesize = 8,\
timeout = self.timeout_time)
except serial.SerialException:
self.ser = serial.serial_for_url('loop://',\
timeout = self.timeout_time) # This line BLOWS!
except:
print sys.exc_info()[0]
finally:
self.initialize_pump()
I should note that the application was written in OSX and was tested on Windows with the Canopy Python Distribution.
I had the exact same problem with "socket://" rather than "loop://"
I wasn't able to get the accepted answer to work however the following seems to succeed:
1) Add an explicit import of the offending urlhandler.* module
import serial
# explicit import for py2exe - to fix "socket://" url issue
import serial.urlhandler.protocol_socket
# explicit import for py2exe - to fix "loop://" url issue (OP's particular prob)
import serial.urlhandler.protocol_loop
# use serial_for_url in normal manner
self._serial = serial.serial_for_url('socket://192.168.1.99:12000')
2) Generate a setup script for py2exe (see https://pypi.python.org/pypi/py2exe/) -- I've installed py2exe to a virtualenv:
path\to\env\Scripts\python.exe -m py2exe myscript.py -W mysetup.py
3) edit mysetup.py to include option
zipfile="library.zip" # default generated value is None
(see also http://www.py2exe.org/index.cgi/ListOfOptions)
3) build it:
path\to\env\Scripts\python.exe mysetup.py py2exe
4) run it
dist\myscript.exe
Found it!
It seems that for some reason the 'loop://' arguement can't be recognised after the .exe production.
I figured out by studying the pyserial/init.py script that when issuing the command serial.serial_for_url(‘loop://') you essentially call:
sys.modules['serial.urlhandler.protocol_loop’].Serial(“loop://“)
So you have to first import the serial.urlhandler.protocol_loop
and then issue that command in place of the one malfunctioning.
So you can now type:
__import__('serial.urlhandler.protocol_loop')
sys.modules[‘serial.urlhandler.protocol_loop’].Serial("loop://")
After this minor workaround it worked fine.

How to get linux screen title from command line

How can I fetch the title of a screen session from the command line?
I came up with a very small and simple python script with pexpect to do it.
It is handy in multiuser environments where some host is reserved and status is written to screen title by user.
It works for me, feel free to make it better.
In order to fetch specific session title, you need to modify the script and call for correct session.
If you run this through remote connection as local script (through SSH for example), remember to set export TERM=xterm before execution.
try:
import pexpect
import sys
child=pexpect.spawn('screen -x')
child.sendcontrol('a');
child.send('A');
i = child.expect('Set window.*')
child.sendcontrol('c');
child.sendcontrol('a');
child.send('d');
TITLE=str(child.after)
TITLE_P=TITLE.split('7m')
if str(TITLE_P[-1]) == '':
print 'Title not found'
else:
print str(TITLE_P[-1])
except:
print 'Could not check screen Title'

Categories