Disable fingerprint in Twisted Web - web

I did a nmap to my server and i watch the fingerprint, how can i disable it?
443/tcp open ssl/http TwistedWeb httpd 9.0.0

The "fingerprint" is how server identifies itself at the start of http session. Thus we should look at what implements Web server in twisted and where does it keep its identification.
Now if we look at http://twistedmatrix.com/trac/browser/tags/releases/twisted-12.2.0/twisted/web/server.py line 498 states
version = "TwistedWeb/%s" % copyright.version
This variable then gets handled by Request.process() method
class Request(pb.Copyable, http.Request, components.Componentized):
....
def process(self):
"Process a request."
# get site from channel
self.site = self.channel.site
# set various default headers
self.setHeader('server', version)
self.setHeader('date', http.datetimeToString())
# Resource Identification
self.prepath = []
self.postpath = map(unquote, string.split(self.path[1:], '/'))
try:
resrc = self.site.getResourceFor(self)
self.render(resrc)
except:
self.processingFailed(failure.Failure())
So you could easily subclass Request and overwrite process method, to do what you like.
Or you in theory could do something like this in your application code:
from twisted.web import server
server.version = "COBOL HTTPD SERVICE"
overriding version value in the imported resource.

Related

Working outside of request context. Flask, SqlAlchemy

I am using Flask and SqlAlchemy, the case is that I have a main database and then I have several databases where I get other information. But the credentials are not defined as fixed, so I have to obtain them from a table in the main database, depending on the plant where the user is. For this I use SQLALCHEMY_BINDS. the problem is that when I try to pass the connection string to the Bind I told myself that the function that returns it is out of context. Here a portion of the code
def scadaConnect():
idplanta_session=str(session['idPlanta'])
usernamequery = db.session.query(Scada.usernameScada).filter(Scada.idPlanta=='5')
hostquery = db.session.query(Scada.hostScada).filter(Scada.idPlanta=='5')
passwordquery = db.session.query(Scada.passScada).filter(Scada.idPlanta=='5')
nombredbquery = db.session.query(Scada.nombrebdScada).filter(Scada.idPlanta=='5')
nombredb = str(nombredbquery[0])[2:len(nombredbquery[0])-4]
host = str(hostquery[0])[2:len(hostquery[0])-4]
password = str(passwordquery[0])[2:len(passwordquery[0])-4]
username = str(usernamequery[0])[2:len(usernamequery[0])-4]
connexion = 'mysql+pymysql://'+username+":"+password+"#"+host+"/"+nombredb+"'"
def retorno():
return str(connexion)
from config import SQLALCHEMY_BINDS
SQLALCHEMY_BINDS['scada']= scadaConnect()
The error is as follows
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.
session (first line in scadaConnect()) is only available in a request context a.k.a. view. It lives in the session cookie on the client and is sent to the server (and available to your view) only when the browser makes a request.
You will have to move the call to scadaConnect() to a view if you want to use session.

How to lock virtualbox to get a screenshot through SOAP API

I'm trying to use the SOAP interface of Virtualbox 6.1 from Python to get a screenshot of a machine. I can start the machine but get locking errors whenever I try to retrieve the screen layout.
This is the code:
import zeep
# helper to show the session lock status
def show_lock_state(session_id):
session_state = service.ISession_getState(session_id)
print('current session state:', session_state)
# connect
client = zeep.Client('http://127.0.0.1:18083?wsdl')
service = client.create_service("{http://www.virtualbox.org/}vboxBinding", 'http://127.0.0.1:18083?wsdl')
manager_id = service.IWebsessionManager_logon('fakeuser', 'fakepassword')
session_id = service.IWebsessionManager_getSessionObject(manager_id)
# get the machine id and start it
machine_id = service.IVirtualBox_findMachine(manager_id, 'Debian')
progress_id = service.IMachine_launchVMProcess(machine_id, session_id, 'gui')
service.IProgress_waitForCompletion(progress_id, -1)
print('Machine has been started!')
show_lock_state(session_id)
# unlock and then lock to be sure, doesn't have any effect apparently
service.ISession_unlockMachine(session_id)
service.IMachine_lockMachine(machine_id, session_id, 'Shared')
show_lock_state(session_id)
console_id = service.ISession_getConsole(session_id)
display_id = service.IConsole_getDisplay(console_id)
print(service.IDisplay_getGuestScreenLayout(display_id))
The machine is started properly but the last line gives the error VirtualBox error: rc=0x80004001 which from what I read around means locked session.
I tried to release and acquire the lock again, but even though it succeeds the error remains. I went through the documentation but cannot find other types of locks that I'm supposed to use, except the Write lock which is not usable here since the machine is running. I could not find any example in any language.
I found an Android app called VBoxManager with this SOAP screenshot capability.
Running it through a MITM proxy I reconstructed the calls it performs and wrote them as the Zeep equivalent. In case anyone is interested in the future, the last lines of the above script are now:
console_id = service.ISession_getConsole(session_id)
display_id = service.IConsole_getDisplay(console_id)
resolution = service.IDisplay_getScreenResolution(display_id, 0)
print(f'display data: {resolution}')
image_data = service.IDisplay_takeScreenShotToArray(
display_id,
0,
resolution['width'],
resolution['height'],
'PNG')
with open('screenshot.png', 'wb') as f:
f.write(base64.b64decode(image_data))

How to get client host name in bottle python?

from bottle import Bottle, request
import socket
app = Bottle()
my_ip = socket.gethostbyname(socket.gethostname())
#app.route('/hello')
def hello():
client_ip = request.environ.get('REMOTE_ADDR')
print("Client IP is ", client_ip)
#Code to read client hostname or machine name
return ['Your IP is: {}\n'.format(client_ip)]
app.run(host=my_ip, port=8080)
I am using the bottle(WSGI micro web-framework for Python). I know how to get IP of the client who requested the service. But I also want to know the hostname(machine name) of the client as well.
I tried reading hostname with windows commands like nbtstat & ping but they are not 100% reliable. Are there any other options available?
A couple of things:
You're probably better off not doing this at all. Instead, consider logging all the IP addresses to a file (better yet, do nothing and simply use an existing access_log) and then resolving them, offline, in batch.
If you do insist on resolving the IP addresses inline, you don't need to call out to Windows commands in order to do it. It'll be a lot faster, simper, and more robust to resolve the addresses in-process. I've included some sample code for you below.
Finally, I'd like to address your comment:
I tried... but they are not 100% reliable
That is a problem with your expectation, not with your DNS resolver. Reverse DNS lookups will inherently yield far less than 100% matches.
Here's the sample code to do the reverse lookup in Python. Good luck!
from socket import gethostbyaddr, herror
def resolve_address(addr):
'''
Resolve the ip address string ``addr`` and return its DNS name. If no name
is found, return None.
Raises any exceptions thrown by gethostbyaddr, except for NOTFOUND (which
is handled by returning None).
NOTE: Illustrative purposes only, not for production use.
'''
try:
record = gethostbyaddr(addr)
except herror as exc:
if exc.errno == 1:
print(f'no name found for address "{addr}"')
return None
else:
print(f'an error occurred while resolving {addr}: {exc}')
raise
print(f'the name of "{addr}" is: {record[0]}')
return record[0]
assert resolve_address('151.236.216.85') == 'li560-85.members.linode.com'
assert resolve_address('10.1.1.1') is None

Setting and Getting Variables within an imported Class

All, I'm implementing websockets using flask/uWSGI. This is relegated to a module that's instantiated in the main application. Redacted code for the server and module:
main.py
from WSModule import WSModule
app = Flask(__name__)
wsmodule = WSModule()
websock = WebSocket(app)
#websock.route('/websocket')
def echo(ws):
wsmodule.register(ws)
print("websock clients", wsmodule.clients)
while True: # This while loop is related to the uWSGI websocket implementation
msg = ws.receive()
if msg is not None:
ws.send(msg)
else: return
#app.before_request
def before_request():
print ("app clients:",wsmodule.clients)
and WSModule.py:
class WSModule(object):
def __init__(self):
self.clients = list()
def register(self, client):
self.clients.append(client)
Problem: When a user connects using websockets (into the '/websocket' route), the wsmodule.register appends their connection socket, this works fine- printout 'websocket clients' shows the appended connection.
The issue is that I can't access those sockets from the main application. This is seen by the 'app clients' printout which never updates (list stays empty). Something is clearly updating, but how to access those changes?
It sounds like your program is being run with either threads or processes, and a wsmodule exists for each thread/process that is running.
So one wsmodule is being updated with the client info, while a different one is being asked for clients... but the one being asked is still empty.
If you are using threads, check out thread local storage.

urllib.request.urlretrieve with proxy?

somehow I can't download files trough a proxyserver, and I don't know what i have done wrong. I just get a timeout. Any advice?
import urllib.request
urllib.request.ProxyHandler({"http" : "myproxy:123"})
urllib.request.urlretrieve("http://myfile", "file.file")
You need to use your proxy-object, not just instanciate it (you created an object, but didn't assign it to a variable and therefore can't use it). Try using this pattern:
#create the object, assign it to a variable
proxy = urllib.request.ProxyHandler({'http': '127.0.0.1'})
# construct a new opener using your proxy settings
opener = urllib.request.build_opener(proxy)
# install the openen on the module-level
urllib.request.install_opener(opener)
# make a request
urllib.request.urlretrieve('http://www.google.com')
Or, if you do not need to rely on the std-lib, use requests (this code is from the official documentation):
import requests
proxies = {"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080"}
requests.get("http://example.org", proxies=proxies)
urllib reads proxy settings from the system environment.
According to the code snippet in the urllib\request.py, just set http_proxy and https_proxy to the environment variable.
In the meantime, it is also documented here: https://www.cmi.ac.in/~madhavan/courses/prog2-2015/docs/python-3.4.2-docs-html/howto/urllib2.html#proxies
# Proxy handling
def getproxies_environment():
"""Return a dictionary of scheme -> proxy server URL mappings.
Scan the environment for variables named <scheme>_proxy;
this seems to be the standard convention. If you need a
different way, you can pass a proxies dictionary to the
[Fancy]URLopener constructor.
"""
proxies = {}
# in order to prefer lowercase variables, process environment in
# two passes: first matches any, second pass matches lowercase only
for name, value in os.environ.items():
name = name.lower()
if value and name[-6:] == '_proxy':
proxies[name[:-6]] = value
# CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY
# (non-all-lowercase) as it may be set from the web server by a "Proxy:"
# header from the client
# If "proxy" is lowercase, it will still be used thanks to the next block
if 'REQUEST_METHOD' in os.environ:
proxies.pop('http', None)
for name, value in os.environ.items():
if name[-6:] == '_proxy':
name = name.lower()
if value:
proxies[name[:-6]] = value
else:
proxies.pop(name[:-6], None)
return proxies
If you have to use a SOCKS5 proxy, here's the solution:
import socks
import socket
import urllib.request
proxy_ip = "127.0.0.1"
proxy_port = 1080
socks.set_default_proxy(socks.PROXY_TYPE_SOCKS5, proxy_ip, proxy_port)
socket.socket = socks.socksocket
url = 'https://example.com/foo/bar.jpg'
urllib.request.urlretrieve(url, 'bar.png')
More Info:
This works very well, but if we want to use ProxyHandler, for some reason it errors for SOCKS proxies, even though it should support it.
proxy = urllib.request.ProxyHandler({'socks': 'socks://127.0.0.1:1080'})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, 'bar.png')
class urllib.request.ProxyHandler(proxies=None)
Cause requests to go
through a proxy. If proxies is given, it must be a dictionary mapping
protocol names to URLs of proxies. The default is to read the list of
proxies from the environment variables _proxy. If no proxy
environment variables are set, then in a Windows environment proxy
settings are obtained from the registry’s Internet Settings section,
and in a macOS environment proxy information is retrieved from the
System Configuration Framework.
When a SOCKS5 proxy is globally set on my Windows OS, I get this:
>>> urllib.request.getproxies()
{'socks': 'socks://127.0.0.1:1080'}
But it still fails.

Resources