Python execfile() in daemon - python

I've found 'daemon.py' script by Sander Marechal and I want to use it to execute my simply test script which prints text. When I execute script without 'execfile()' it creates daemon-example.pid and daemon works but when I add 'execfile()' it doesn't work.
here is code:
#!/usr/bin/env python
import sys
from daemon import Daemon
class MyDaemon(Daemon):
def run(self):
while True:
execfile("text.py")
time.sleep(1)
if __name__ == "__main__":
daemon = MyDaemon('/tmp/daemon-example.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)

Related

Python windows privilege escalation

So, I want to run a program in administrator mode (UAC)
After some digging i foud this:
import os
import types
from traceback import print_exc
from sys import argv, executable
def isUserAdmin():
if os.name == 'nt':
import ctypes
# WARNING: requires Windows XP SP2 or higher!
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
print_exc()
print "Admin check failed, assuming not an admin."
return False
elif os.name == 'posix':
# Check for root on Posix
return os.getuid() == 0
else:
raise RuntimeError, "Unsupported operating system for this module: %s" % (os.name,)
def runAsAdmin(cmdLine=None, wait=True):
if os.name != 'nt':
raise RuntimeError, "This function is only implemented on Windows."
import win32api, win32con, win32event, win32process
from win32com.shell.shell import ShellExecuteEx
from win32com.shell import shellcon
python_exe = executable
if cmdLine is None:
cmdLine = [python_exe] + argv
elif type(cmdLine) not in (types.TupleType,types.ListType):
raise ValueError, "cmdLine is not a sequence."
cmd = '"%s"' % (cmdLine[0],)
# XXX TODO: isn't there a function or something we can call to massage command line params?
params = " ".join(['"%s"' % (x,) for x in cmdLine[1:]])
cmdDir = ''
showCmd = win32con.SW_SHOWNORMAL
#showCmd = win32con.SW_HIDE
lpVerb = 'runas' # causes UAC elevation prompt.
# print "Running", cmd, params
# ShellExecute() doesn't seem to allow us to fetch the PID or handle
# of the process, so we can't get anything useful from it. Therefore
# the more complex ShellExecuteEx() must be used.
# procHandle = win32api.ShellExecute(0, lpVerb, cmd, params, cmdDir, showCmd)
procInfo = ShellExecuteEx(nShow=showCmd,
fMask=shellcon.SEE_MASK_NOCLOSEPROCESS,
lpVerb=lpVerb,
lpFile=cmd,
lpParameters=params)
if wait:
procHandle = procInfo['hProcess']
obj = win32event.WaitForSingleObject(procHandle, win32event.INFINITE)
rc = win32process.GetExitCodeProcess(procHandle)
#print "Process handle %s returned code %s" % (procHandle, rc)
else:
rc = None
return rc
def test():
rc = 0
if not isUserAdmin():
print "You're not an admin.", os.getpid(), "params: ", argv
#rc = runAsAdmin(["c:\\Windows\\notepad.exe"])
rc = runAsAdmin()
else:
print "You are an admin!", os.getpid(), "params: ", argv
rc = 0
x = raw_input('Press Enter to exit.')
return rc
if __name__ == "__main__":
if not isUserAdmin():
runAsAdmin()
Which asks the user for admin. permission,but i have two main problems with it:
1.The user needs to give the program permission.(Problematic for pentesting)
2.Every time the program is run the user needs to give the program permission.(which is suspicious)
Is there a way to bypass this?
ps. windows 7 and no direct access
Assuming you have access to the computers this script is running on then you can follow the instructions in this link...
http://www.howtogeek.com/124087/how-to-create-a-shortcut-that-lets-a-standard-user-run-an-application-as-administrator/
It will allow a standard user to run a particular application as an administrator. I've used this guide successfully on other apps but never on a python script. Might work for you.

calling functions from command prompt

Here is the extract of the script (untested)
def start_custer():
try:
myidentifier=mydict['DescribeClustersResponse']['DescribeClustersResult']['Clusters'][0]['ClusterIdentifier']
except IndexError:
conn.restore_from_cluster_snapshot('vi-mar5-deliveryreport-new', mysnapidentifier, availability_zone='us-east-1a')
def stop_cluster():
try:
myidentifier=mydict['DescribeClustersResponse']['DescribeClustersResult']['Clusters'][0]['ClusterIdentifier']
conn.delete_cluster(myidentifier, skip_final_cluster_snapshot=False, final_cluster_snapshot_identifier=myvar)
except:
print "error"
Are these functions technically (syntactically) correct?
How do I call them while calling the python script? I need to either start or stop cluster at a time, not both.
For your second question, I'd parse the command line via argparse:
import argparse
parser = argparse.ArgumentParser(description="Manage the cluster")
parser.add_argument("action", choices=["stop", "start"],
help="Action to perform")
args = parser.parse_args()
if args.action == "start":
start_cluster()
if args.action == "stop":
stop_cluster()
Others have shown you the best way to do this, but for the record, you can also do this from the command line:
python -c "import cluster; cluster.start_cluster()"
(assuming your module file is named cluster.py -- adjust the import statement accordingly if not)
This isn't as user-friendly as parsing the command line yourself but it'll do in a pinch.
1) It's Syntactically correct, if you have defined conn somewhere and imported it !
2)
def stop_cluster():
## Your code
def fun():
## your code
if __name__ == "__main__":
import sys
globals()[sys.argv[1]]()
Usage:
python2.7 test_syn.py fun
I have added a main function to your script which checks for command line args, then prompts you if no valid argument has been supplied:
import sys
def start_custer():
try:
myidentifier=mydict['DescribeClustersResponse']['DescribeClustersResult']['Clusters'][0]['ClusterIdentifier']
except IndexError:
conn.restore_from_cluster_snapshot('vi-mar5-deliveryreport-new', mysnapidentifier, availability_zone='us-east-1a')
def stop_cluster():
try:
myidentifier=mydict['DescribeClustersResponse']['DescribeClustersResult']['Clusters'][0]['ClusterIdentifier']
conn.delete_cluster(myidentifier, skip_final_cluster_snapshot=False, final_cluster_snapshot_identifier=myvar)
except:
print "error"
def main():
valid_args, proc = ['start','stop'], None
# check if cmd line args were passed in (>1 as sys.argv[0] is name of program)
if len(sys.argv) > 1:
if sys.argv[1].lower() in valid_args:
proc = sys.argv[1].lower()
# if a valid arg was passed in this has been stored in proc, if not prompt user
while not proc or proc not in valid_args:
print "\nPlease state which procedure you want to call, valid options are:", valid_args
proc = raw_input('>>> ').lower()
# prompt user if invalid
if proc not in valid_args:
print proc, 'is not a valid selection.'
if proc == 'start':
start_custer()
elif proc == 'stop':
stop_cluster()
# this makes the script automatically call main when starting up
if __name__ == '__main__':
main()
You can call this from the command line e.g. if you were in the same directory as the file (e.g. named cluster_ctrl.py) just:
python cluster_ctrl.py start

Python Daemon calling a subprocess periodically

I am building a simple pyhon daemon based on Sander Marechal's code. Daemon's whole purpose is to run a php file every second (php file loops through database checking values and updating database). Problem arises on the section
subprocess.call(['php','test.php'])
I can run "php test.php" on shell and it does what it is suppose to do but when it is called periodically from the daemon it doesn't seem to be executed. I also know daemon works on the background via checking running process ps aux | grep "daemon-example" also i included a do_something function which records every time function executed and appends time to a text file.
#!/usr/bin/env python
import sys, time,subprocess
from daemon import Daemon
def runphp():
#subprocess.call(['php ~/pydaemon/test.php'], shell=True)
subprocess.call(['python', 'test.py'])
def do_something():
with open("/tmp/current_time.txt",'a') as f:
f.write("The time is now\n" + time.ctime())
class MyDaemon(Daemon):
def run(self):
while True:
time.sleep(1)
do_something()
subprocess.call(['php','test.php'])
#runphp()
if __name__ == "__main__":
daemon = MyDaemon('/tmp/daemon-example.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)
The script you are trying to run is not executed because the working directory is the root directory ('/') and that's because of this piece of code:
# decouple from parent environment
os.chdir("/")
So actually your code tries to execute: python /test.py(which does not exist) and not 'your_current_directory/test.py'.
To fix it either remove os.chdir("/"), or provide the full path to the file like so:
subprocess.call(['python','my_full_path_to_working_directory/test.py'])

Python wrapper script to let a program be executed remotely with no blocking

I am looking for a wrapper script to run a program which is called remotely by a SSH command which terminates without waiting for the result of the program.
Here is my code:
#!/usr/bin/python
import sys
import os, subprocess
def main():
print "PID_last_child", os.getpid()
argpass = ['main_p.py']
for a in sys.argv:
if a.find("wrapper.py") == -1:
argpass.append(a)
pid = subprocess.Popen(argpass).pid
print "PID for the actual process: ", pid
if __name__ == "__main__":
print "PID_MAIN:", os.getpid()
try:
pid = os.fork()
print "FORK1: ", pid
if pid > 0:
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
os.chdir('/')
os.setsid()
os.umask(0)
try:
pid = os.fork()
print "FORK2: ", pid
if pid > 0:
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
main()
I suppose using double forking, i should be able to do that... but no luck so far.
Any thoughts on this is greatly appreciated.
I fully credit this link for the answer in bash syntax: How to starting process as daemon using ssh command?
You don't even need to double-fork. The issue is that the stdout is still connected. Here is the python approach:
wrapper.py
import subprocess
import os
def main():
pid = subprocess.Popen(['nohup', '/path/to/main_p.py'],
stdout = open(os.devnull, 'w+', 0),
stderr = subprocess.STDOUT
).pid
print pid
if __name__ == "__main__":
main()
And then the ssh command would call this wrapper:
ssh server /path/to/wrapper.py
You just need to redirect stdout -> devull, and the process will return right away.

Run web.py as daemon

I have a simple web.py program to load data. In the server I don't want to install apache or any webserver.
I try to put it as a background service with http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
And subclassing:
(from http://www.jejik.com/files/examples/daemon.py)
class Daemon:
def start(self):
"""
Start the daemon
"""
... PID CHECKS....
# Start the daemon
self.daemonize()
self.run()
#My code
class WebService(Daemon):
def run(self):
app.run()
if __name__ == "__main__":
if DEBUG:
app.run()
else:
service = WebService(os.path.join(DIR_ACTUAL,'ElAdministrador.pid'))
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
service.start()
elif 'stop' == sys.argv[1]:
service.stop()
elif 'restart' == sys.argv[1]:
service.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)
However, the web.py software not load (ie: The service no listen)
If I call it directly (ie: No using the daemon code) work fine.
I finally find the problem.
Web.py accept from command-line the optional port number:
python code.py 80
And the script also take input from the command-line:
python WebServer start
then web.py try to use "start" as port number and fail. I don't see the error because was in the bacground.
I fix this with a mini-hack:
if __name__ == "__main__":
if DEBUG:
app.run()
else:
service = WebService(os.path.join(DIR_ACTUAL,'ElAdministrador.pid'))
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
sys.argv[1] = '8080'
service.start()
you can start the web.py by using this command
/usr/bin/python index.py > log.txt 2>&1 &
I don't think you're telling the daemon to run. You need to instantiate a MyDaemon object and call o.run(). It looks like WebService only starts and stops the service interface to your web app, not the actual web app itself.
Instead of overwrite the second argument like you wrote here:
if __name__ == "__main__":
if DEBUG:
app.run()
else:
service = WebService(os.path.join(DIR_ACTUAL,'ElAdministrador.pid'))
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
sys.argv[1] = '8080'
service.start()
you could just delete the second argument on 'start|restart', like this:
if __name__ == "__main__":
if DEBUG:
app.run()
else:
service = WebService(os.path.join(DIR_ACTUAL,'ElAdministrador.pid'))
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
delete del sys.argv[1:2]
service.start()
In this way, the webpy will receive all the arguments you passed from command line except the daemon controller. Then you can run simply:
python WebServer start 8080

Categories