I'm trying to implement an authentication section into the smbserver.py from the impacket lib.
I changed the errorCode at the Line 2201 to STATUS_LOGON_FAILURE under some conditions, but my windows client keeps requesting with the same credentials like 10 times before he asks the user to enter new credentials. When I submit the windows dialog the credentials dont get sent to the script.
Heres my code section:
if not authenticateMessage['user_name'] == "testUser":
print "username not valid"
errorCode = STATUS_LOGON_FAILURE
respToken['NegResult'] = '\x02'
else:
print "logged in" + authenticateMessage['user_name']
errorCode = STATUS_SUCCESS
respToken['NegResult'] = '\x00'
Did somebody write a working authentication section there? Thanks!
The link you have provided is not the official repository for the library. Use https://github.com/CoreSecurity/impacket in the future.
The code you specified is almost right except the fact that the user_name field inside the authenticateMessage is Unicode encoded.
You can see the contents of the authenticateMessage structure by calling its dump() method (authenticateMessage.dump()).
I've replaced your code with:
authenticateMessage.dump()
respToken = SPNEGO_NegTokenResp()
if authenticateMessage['user_name'].decode('utf-16le') == "testUser":
errorCode = STATUS_SUCCESS
respToken['NegResult'] = '\x00'
else:
errorCode = STATUS_LOGON_FAILURE
respToken['NegResult'] = '\x02'
If you cloned master (https://github.com/CoreSecurity/impacket) you will see a new example called examples/smbserver.py (don't get confused with the impacket/smbserver.py library) which makes it easier to launch a simple server. Just run:
smbserver.py shareName sharePath
(e.g. smbserver.py TMP /tmp)
I made the aforementioned changes and ran the smbserver.py example and then, from a windows 7 cmd.exe prompt I ran (assuming the SMB server runs at 172.16.123.1 and the logged in username is not testUser):
start \\172.16.123.1
If you sniff the traffic you will see three attempts to login unsuccessfully and then Windows Explorer will popup a dialog box asking for new credentials. If you specify testUser as username (password can be anything) you will end up connecting to the target SMB server.
Related
I am pretty new to Pyvmomi and vsphere automation.
I have been trying to automate the user and group creation in vsphere but could not locate the method in Pyvmomi which could help me automate the process of user creation.
I already have a user created in vcenter (abc#xyz.local)
This user has administrative privileges
Now, I want to create a session with user abc#xyz.local and add new users in Vcenter 'users and groups'. Once the new users are created, I have to add these users to different groups.
All these has to be done via automation using python.
Is there a way to automate this?
Unfortunately, the SSO API is all private and unavailable through pyvmomi and the rest of the SDKs.
As #Kyle Ruddy says, it looks like pyvmomi does not support SSO APIs. However, the golang alternative (govmomi) does. Govmomi also has an a CLI called GOVC which provides a nice wrapper to perform the following (and other things!):
Creating groups
Adding users to groups
Creating users
You could look at GOVCs source code and try and figure out the SOAP calls, but I think that would be more trouble than its worth.
If you are open to the idea of launching a bash commands from python then you could do the following:
import subprocess
import os
# Handy function for GOVC and assume GOVC is on your $PATH
def govc_runner(command):
my_env = os.environ.copy()
# Admin user will need to perform the commmands
my_env["GOVC_USERNAME"] = "abc#xyz.local"
my_env["GOVC_PASSWORD"] = "<ABC_PASSWORD>"
my_env["GOVC_URL"] = "https://<VCENTER>"
my_env["GOVC_INSECURE"] = "true"
process = subprocess.Popen(command, env=my_env, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
return output, error
# New group and user info
newUserUsername = "praseemol"
newUserPassword = "<PARASEEMOL_PASSWORD>"
newGroup = "prasGroup"
# Creating new group and user
govc_runner("govc sso.group.create " + newGroup)
govc_runner("govc sso.user.create -p '" + newUserPassword + "' '" + newUserUsername + "'")
govc_runner("govc sso.group.update -a " + newUserUsername + " " + newGroup)
# Check if it has worked
output, error = govc_runner("govc sso.user.id " + newUserUsername)
if newGroup in output:
print("Yay, it worked:\n" + output)
else:
print("Something went wrong :(")
Hope that helps!
You can automate shell(vcenter) execution by doing ssh through putty for creation of user in system domain of vcenter and mimic same using paramiko library of python.
Official docs to refer for system domain user creation:
https://docs.vmware.com/en/VMware-vSphere/6.0/com.vmware.vsphere.security.doc/GUID-4FBEA58E-9492-409B-B584-C18477F041D8.html
Commands to be executed on vcenter shell:
/usr/lib/vmware-vmafd/bin/dir-cli user create --account william --first-name william --last-name lam --user-password 'VMware1!'
Refer:https://williamlam.com/2015/05/vcenter-server-6-0-tidbits-part-9-creating-managing-sso-users-using-dir-cli.html
To connect to vcenter using paramiko:
How do you execute multiple commands in a single session in Paramiko? (Python)
Pick the answer by "This".
You can fetch the created user using powercli commands:
Get-VIAccount
While using this be sure to find your created user in system domain.
Get_VIAccount -Domain 'domain_name'
The default domain name is usually like: "vsphere.local"
You can also find your domain by using putty to vcenter, enter shell and write,
"sso-config.sh -get_identity_sources"
You will be able to read Sys_Domain: '......'
You can assign role to user using powercli:
Get-VIPermission
If You can automate local user creation, let me know:
https://docs.vmware.com/en/VMware-vSphere/6.7/com.vmware.vsphere.vcsa.doc/GUID-533AE852-A1F9-404E-8AC6-5D9FD65464E5.html
I am using Python 2.7 Paramiko to SSH into a very old system that uses IBM 3151 keymapping. Keyboards back then had an enter or "send" key used to submit responses. In Secure NetTerm, I am able to access this system and the "send" key is mapped to the right ctrl key on the keyboard. For the life of me, I can't figure out how to send the "send" key to the terminal with Paramiko. Below is my test code. I am able to make it through the first few menu options which accept \n, but I am running into a "popup" screen that requires the "send" key. Pressing the right ctrl key works in the emulator, but I can't seem to get anything to work in Paramiko. Any help would be appreciated.
import paramiko
import time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect('some_server.com', port=22,username='some_user', password='some_password')
except paramiko.SSHException:
print "Connection Failed"
quit()
channel = ssh.invoke_shell(term='IBM-3151', width=80, height=24, width_pixels=0, height_pixels=0)
channel_data = str()
host = str()
srcfile = str()
while True:
if channel.recv_ready():
channel_data += channel.recv(9999)
else:
continue
print channel_data
#Go to store
if channel_data.endswith('> '):# in channel_data:
channel.send('5\n')
# Select a store
if channel_data.endswith(' : '): # in channel_data:
channel.send('0330\n')
if channel_data.endswith('): '): # in channel_data:
channel.send('Y\n')
if 'PRESS SEND TO CONTINUE....' in str(channel_data):
print 'test1' # if statement works
time.sleep(5)
channel.send('^[!l^M') # tried all kinds of stuff here
print 'test2' # script passes to here with no errors.
I'd determine what characters are actually sent by the Send (or Enter) key by
capture all of the characters from a session using script on the AIX system (you might need this for analysis)
in a shell on the AIX system, use cat (to echo) and press control-V before pressing *Enter.
Do that with the working terminal of course. If the data shown by cat does not work with your script, it's possible that there's some initialization done, e.g., putting Secure NetTerm into application mode.
Anyone know if this is possible?
I just want to automate dropping some documents into my onedrive for business account.
I tried
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest
redirect_uri = 'http://localhost:8080'
client_id = 'appid'
client_secret = 'mysecret'
discovery_uri = 'https://api.office.com/discovery/'
auth_server_url='https://login.live.com/oauth20_authorize.srf?scope=wl.skydrive_update'
#auth_server_url='https://login.microsoftonline.com/common/oauth2/authorize',
auth_token_url='https://login.microsoftonline.com/common/oauth2/token'
http = onedrivesdk.HttpProvider()
auth = onedrivesdk.AuthProvider(http,
client_id,
auth_server_url=auth_server_url,
auth_token_url=auth_token_url)
auth_url = auth.get_auth_url(redirect_uri)
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
auth.authenticate(code, redirect_uri, client_secret, resource=resource)
# If you have access to more than one service, you'll need to decide
# which ServiceInfo to use instead of just using the first one, as below.
service_info = ResourceDiscoveryRequest().get_service_info(auth.access_token)[0]
auth.redeem_refresh_token(service_info.service_resource_id)
client = onedrivesdk.OneDriveClient(service_info.service_resource_id + '/_api/v2.0/', auth, http)
I registered an APP and got a secret and id. But when I ran this I got scope is invalid errors. Plus it tries to launch a webpage which isn't great for a command line kinda environment. I think this SDK might be outdated as well because originally this script had login.microsoftonline, but that wasn't reachable so I changed it to login.live.com.
I wrote this sample code you posted. You replaced the auth_server_URLwith the authentication URL for Microsoft Account authentication, which can only be used to access OneDrive (the consumer product). You need to continue using the login.microsoftonline.com URL to log into your OneDrive for Business account.
You are correct that this pops up a dialog. However, you can write a little supporting code so that only happens the first time you log into a particular app. Follow these steps (assuming you are using the default implementation of AuthProvider:
Use the sample code above up through the line auth.redeem_refresh_token()
The AuthProvider will now have a Session object, which caches the credentials of the current user and session. Use AuthProvider.save_session() to save the credentials for later.
Next time you start your app, use AuthProvider.load_session() and AuthProvider.refresh_token() to retrieve the previous session and refresh the auth token. This will all be headless.
Take note that the default implementation of SessionBase (found here) uses Pickle and is not safe for product use. Make sure to create a new implementation of Session if you intend to deploy this app to other users.
Onerive's website shows "Not Yet" on "OneDrive SDK for Python" to "OneDrive for Business"
https://dev.onedrive.com/SDKs.htm
The github sample codes did not work for me either, it tried to popup a window of authentication, but IE can not find the address:
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx9-9xx8-4xxf-bexx-1bc5xxxxbd0c&response_type=code
or removed all the "-" in client id
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx99xx84xxfbexx1bc5xxxxbd0c&response_type=code
Either way, I got the same result, IE did not show the popup with a line "This page can’t be displayed"
So I've got redis feature and tornado running on my server and whenever I open my websocket chat through a login, the terminal displays the following message
Error: Authentication missing
I'm not sure why this is happening because there are cookies in the authentication part of the app,
# Save user when authentication was successful.
def on_user_find(result, user=user):
##todo: We should check if email is given even though we can assume.
if result == "null" or not result:
# If user does not exist, create a new entry.
self.application.client.set("user:" + user["email"], tornado.escape.json_encode(user))
else:
# Update existing user.
# #todo: Should use $set to update only needed attributes?
dbuser = tornado.escape.json_decode(result)
dbuser.update(user)
user = dbuser
self.application.client.set("user:" + user["email"], tornado.escape.json_encode(user))
# Save user id in cookie.
self.set_secure_cookie("user", user["email"])
self.application.usernames[user["email"]] = user.get("name") or user["email"]
And in the websocket.py (where I run the script) I've made it so that the websocket handle checks if there are cookies available first before user access the app,
class ChatSocketHandler(tornado.websocket.WebSocketHandler):
def open(self, user):
self.login = self.get_secure_cookie("user")
if not self.login:
# self.login = "anonymous"
print "Not authorized"
self.disconnect()
return
Yet it's still displaying the error, I've searched online and checked several SO answers but they don't show any solid solution in regards to this question. So far the most I've gotten is that I have to access the websocket header to put the above code inside, but I have no clue how I would do that. Help?
I am trying to come up with a script to check if a domain name resolves to its IP address via dns; using a python script I wrote.
I want to be able to do this in a few sequential loops, however after trying to run a loop once, the second time i run the script, the names that previously returned a successful dns resolution response, now do not.
Below is my script:
#! C:\Python27
import socket,time
localtime = time.asctime( time.localtime(time.time()) )
def hostres(hostname):
print "Attempting to resolve " + hostname
try:
socket.gethostbyname(hostname)
print "Resolved Successfully!"
except socket.error:
print "Could Not Resolve"
print "*************************************************"
print "Website loop starting.."
print "Local current time :", localtime
print "*************************************************"
print ""
text_file = open("sites.txt", "r")
lines = text_file.readlines()
for line in lines:
hostres(line)
text_file.close()
The contents of the text file are:
www.google.com
en.wikipedia.org
www.youtube.com
us.gamespot.com
I am thinking it is to do with these domains servers recognizing the script as a "bot" rather than a legitimate end-user, would it be correct to assume this?
If so, how can I still check if the dns name resolves by looking up the name of the website (or IP, does not matter) and be able to run this without getting a false reading of "request failed" despite the fact that the service is fully accessible from a browser?
Several problems in this question.
You are not checking if "a website responds" you are testing DNS resolution. All your DNS requests go to a single name server, your LDNS resolver. If all of them resolve, it still says nothing about the status of the website. Also, since you aren't actually talking to these website, they have no way of knowing you're a bot. They can only detect this (based on the HTTP user-agent header) if you make a HTTP request.
Regarding your code problem, you need to trim the newline character before you can do a socket.gethostbyname() on it. Replace socket.gethostbyname(hostname) with socket.gethostbyname(hostname.rstrip()) and you'll be fine.