OWASP zap python api authentication - python

I'd like to start off by saying that I love this tool and the API is written in a very easy to follow way if you are familiar with Zap. The only troubles I've had is that I can't find much documentation on the python API, so I've gone off of the source code and verifying how it works against the app. I've been able to pull of scans and set contexts, but I can't seem to be able to correctly call anything from the authentication module. One of my problems, I believe, is that I'm not entirely sure the exact variables to use or their respective formats when calling the functions. below is some example code that I've scrapped together. Every use of the authentication functions below fail me. Even if someone were to look at this and tell me where to go or look to solve this problem myself, I would be very grateful.
from zapv2 import ZAPv2
context = 'new_attack'
authmethodname = 'formBasedAuthentication'
authmethodconfigparams = "".join('loginUrl=someloginpage' 'loginRequestData=username%3D%7B%25user1%25%7D%26' 'password%3D%7B%25password%25%7D')
target = 'some target but I cant put more than 2 links in this question'
apikey = 'password'
zap = ZAPv2(apikey=apikey)
print zap.context.new_context('new_attack')
print zap.context.include_in_context(context, 'https://192.168.0.1.*')
print zap.context.context(context)
#anything below here gives me 'Missing Params' an error from zap
print zap.authentication.set_logged_in_indicator(context, loggedinindicatorregex='Logged in')
print zap.authentication.set_logged_out_indicator(context, 'Sorry, the username or password you entered is incorrect')
print zap.authentication.set_authentication_method(context, authmethodname, authmethodconfigparams)

A Dev member on the project was able to answer my question so I thought I would put it here as well. Essentially the authentication functions take the contextid and userid as parameters and I was passing the context name and user name. There are a few other mistakes that I interpreted from the source code as well. Hopefully this helps someone else who's starting out with the API as well, since there is not a lot of documentation.
from github page zaproxy; username thc202 - "
from zapv2 import ZAPv2
context = 'new_attack'
authmethodname = 'formBasedAuthentication'
authmethodconfigparams = "".join('loginUrl=https://192.168.0.1/dologin.html' '&loginRequestData=username%3D%7B%25username%25%7D%26' 'password%3D%7B%25password%25%7D')
target = 'https://192.168.0.1'
apikey = 'password'
zap = ZAPv2(proxies={'http': 'http://127.0.0.1:8119', 'https': 'http://127.0.0.1:8119'}, apikey=apikey)
contextid = zap.context.new_context(context)
print contextid
print zap.context.include_in_context(context, 'https://192.168.0.1.*')
print zap.context.context(context)
print zap.authentication.set_authentication_method(contextid, authmethodname, authmethodconfigparams)
# The indicators should be set after setting the authentication method.
print zap.authentication.set_logged_in_indicator(contextid, loggedinindicatorregex='Logged in')
print zap.authentication.set_logged_out_indicator(contextid, 'Sorry, the username or password you entered is incorrect')
userid = zap.users.new_user(contextid, 'User 1')
print userid
print zap.users.set_authentication_credentials(contextid, userid, 'username=MyUserName&password=MySecretPassword')
print zap.users.set_user_enabled(contextid, userid, True)
print zap.spider.scan_as_user(contextid, userid, target)
"

Related

How can i show a simple instagram feed with the new api permissions

I am trying to set up a instagram plugin on django cms to show my recent images on a homepage by the username set in the plugin. It seems you can no longer simply get public content from instagram. This is the current method im using with my sandbox account.
user_request = requests.get("https://api.instagram.com/v1/users/search?q=" + str(instance.username) + "&access_token=" + settings.INSTAGRAM_ACCESS_TOKEN)
user_id = user_request.json().values()[1][0]["id"]
r = requests.get("https://api.instagram.com/v1/users/"+ user_id +"/media/recent/?access_token=" + settings.INSTAGRAM_ACCESS_TOKEN + "&count=" + str(instance.limit))
recent_media = r.json()
The code above gets the username from the plugin model and makes a get request to the instagram api to get that user (i've heard this method doesn't always show the correct user as its just searching and getting the first user from a list).
Is this the right way to work with the instagram api and python, I was going to use python-instagram but that is no longer supported. The only other way i can think of doing it is authenticating the user on the site and using their access token which seems silly for what i need it for.
EDIT:
Would removing the username field and adding access_token instead be a better method ? Then use "/users/self/media/recent" and rule out the query to search for a user by username.
Yes, the first results is not always the match, you have loop through all the search results and compare the username to your searched username, and then get id
Something like this:
var user_id = 0;
user_request.json().values()["data"].forEach(function(user){
if(user.username == str(instance.username)){
user_id = user["id"]
}
});
if(user_id){
// make api call
} else {
// user not found
}

unable to retrieve tornado secure cookie

for some reason I'm unable to retrieve a secure cookie I've set with tornado. Using firebug I can see the cookie and it's expiration date, but when I try to print or retrieve it, it keeps coming up as None. Is there some way I'm invalidating it that I can't see. This is the code I'm using:
class loginHandler(tornado.web.RequestHandler):
def post(self):
# first type of request made to this page is a post
userEmail = self.get_argument("username")
password = self.get_argument("password")
deviceType = self.get_argument("deviceType")
# get some info from the client header
userIp = self.request.headers['X-Real-Ip']
userAgentInfo = self.request.headers['User-Agent']
result = pumpkinsdb.loginUser(userEmail, password, deviceType, userIp, userAgentInfo)
if result == None:
self.redirect("/")
else:
fullname = pumpkinsdb.pumpkinsdb_user['fullName']
this_page_title = fullname if fullname else pumpkinsdb.pumpkinsdb_user['userEmail']
# successful login set up user's cookies
# self.set_secure_cookie("memberId", str(user['memberId']), expires_days=0.1, secure=True, httponly=True)
self.set_secure_cookie("memberId", str(pumpkinsdb.pumpkinsdb_user['memberId']))
self.write(str(self.get_secure_cookie("memberId")))
time_now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print "{} [{}::get] pid[{}] login requested for user: [{}] from [{}] using [{}]".format(
time_now, self.__class__.__name__, os.getpid(), pumpkinsdb.pumpkinsdb_user['emailAddress'],
pumpkinsdb.pumpkinsdb_user['userIp'], pumpkinsdb.pumpkinsdb_user['userAgentInfo'])
self.render('calendar.html', title = this_page_title)
def get(self):
validSession = self.get_secure_cookie("memberId")
if validSession:
this_page_title = pumpkinsdb.pumpkinsdb_user['fullName']
self.render('calendar.html', title = this_page_title)
else:
print self.get_secure_cookie("memberId")
self.write(str(validSession))
Is your cookie secret changing somehow when you restart the server? If the cookie secret changes, all existing cookies are invalidated. Note that even though the cookie secret should be randomly generated, this doesn't mean you should have something like cookie_secret=os.urandom(16) in your code, because that will generate a new secret every time. Instead, you need to call os.urandom once and save its output somewhere (keep it safe and private, like your TLS keys).
so basically the problem was I had four tornado processes running behind nginx and for each tornado process I generated a unique random string with:
cookie_secret = base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
obviously that was my problem because each tornado process had a different secret so when i tried to read it tornado thought it was invalid.
The key is to generate a unique random string but then store it somewhere secure such as in your options:
define(cookie_secret, "934893012jer9834jkkx;#$592920231####")
or whatever string you deem fit.
Thank you to everyone that responded. sorry about that.

Writing code using graph APIs

I am extremely new to python , scripting and APIs, well I am just learning. I came across a very cool code which uses facebook api to reply for birthday wishes.
I will add my questions, I will number it so that it will be easier for someone else later too. I hope this question will clear lots of newbies doubts.
1) Talking about APIs, in what format are the usually in? is it a library file which we need to dowload and later import? for instance, twitter API, we need to import twitter ?
Here is the code :
import requests
import json
AFTER = 1353233754
TOKEN = ' <insert token here> '
def get_posts():
"""Returns dictionary of id, first names of people who posted on my wall
between start and end time"""
query = ("SELECT post_id, actor_id, message FROM stream WHERE "
"filter_key = 'others' AND source_id = me() AND "
"created_time > 1353233754 LIMIT 200")
payload = {'q': query, 'access_token': TOKEN}
r = requests.get('https://graph.facebook.com/fql', params=payload)
result = json.loads(r.text)
return result['data']
def commentall(wallposts):
"""Comments thank you on all posts"""
#TODO convert to batch request later
for wallpost in wallposts:
r = requests.get('https://graph.facebook.com/%s' %
wallpost['actor_id'])
url = 'https://graph.facebook.com/%s/comments' % wallpost['post_id']
user = json.loads(r.text)
message = 'Thanks %s :)' % user['first_name']
payload = {'access_token': TOKEN, 'message': message}
s = requests.post(url, data=payload)
print "Wall post %s done" % wallpost['post_id']
if __name__ == '__main__':
commentall(get_posts())`
Questions:
importing json--> why is json imported here? to give a structured reply?
What is the 'AFTER' and the empty variable 'TOKEN' here?
what is the variable 'query' and 'payload' inside get_post() function?
Precisely explain almost what each methods and functions do.
I know I am extremely naive, but this could be a good start. A little hint, I can carry on.
If not going to explain the code, which is pretty boring, I understand, please tell me how to link to APIs after a code is written, meaning how does a script written communicate with the desired API.
This is not my code, I copied it from a source.
json is needed to access the web service and interpret the data that is sent via HTTP.
The 'AFTER' variable is supposed to get used to assume all posts after this certain timestamp are birthday wishes.
To make the program work, you need a token which you can obtain from Graph API Explorer with the appropriate permissions.

Python - Facebook API - Need a working example

Ok, so i've googled around, i've found threads here on stackoverflow and i've checked the official Facebook wiki and.. and what not..
I now hope that one of you guys sits on a Facebook API sample code for Python.
This is what i've got so far and all i get is "Invalid Signature" via PyFacebook which appears to be a dead project:
from facebook import Facebook
api_key = '123456789______'
secret = '<proper secret key>'
OTK = 'XXXXX' # <-- You get this from: https://www.facebook.com/code_gen.php?v=1.0&api_key=123456789______
long_term_key = None
fb = Facebook(api_key, secret)
def generate_session_from_onetime_code(fb, code):
fb.auth_token = code
return fb.auth.getSession()
if not long_term_key:
long_term_key = generate_session_from_onetime_code(fb, OTK)['session_key']
print 'Replace None with this in the .py file for long_term_key:'
print long_term_key
fb.session_key = long_term_key
fb.uid = 000000001 # <-- Your user-id
fb.signature = api_key # <-- This doesn't work at all, MD5 of what?
#fb.validate_signature(fb) # <-- doesn't work either, prob need to pass MD5 handle?
print fb.friends.get() # <-- Generates "Invalid Signature"
"all" i want, is to retrieve my friends list for now,
if there's a better API point me in the right direction but Facebook has officially declared their own Python SDK dead and pyfacebook is almost working for me but not quite..
So, please help.
The unofficial fork of the python sdk is still working fine for me.
To retrieve your friends, generate an access token here:
https://developers.facebook.com/tools/access_token/
Limitations:
A user access token with user_friends permission is required to view
the current person's friends.
This will only return any friends who have used (via Facebook Login) the app making the request.
If a friend of the person declines the user_friends permission, that friend will not show up in the friend list for this person.
Code
import facebook
token = 'your token'
graph = facebook.GraphAPI(token)
profile = graph.get_object("me")
friends = graph.get_connections("me", "friends")
friend_list = [friend['name'] for friend in friends['data']]
print friend_list

What is a post_form_id? (using python urllib2)

I'm interested in writing a python script to log into Facebook and then request some data (mainly checking the inbox). There are few nice examples out there on how to do this. One interesting script i found over here and there is some nice example on stackoverflow itself.
Now i could just copy-paste some of the code i need and get to do what i want, but that wouldn't be a good way to learn. So i am trying to understand what i am actually coding and can't understand some elements of the script in the first example, namely: what is a post_form_id?
Here is the section of the code which refers to "post_form_id" (line 56-72):
# Initialize the cookies and get the post_form_data
print 'Initializing..'
res = browser.open('http://m.facebook.com/index.php')
mxt = re.search('name="post_form_id" value="(\w+)"', res.read())
pfi = mxt.group(1)
print 'Using PFI: %s' % pfi
res.close()
# Initialize the POST data
data = urllib.urlencode({
'lsd' : '',
'post_form_id' : pfi,
'charset_test' : urllib.unquote_plus('%E2%82%AC%2C%C2%B4%2C%E2%82%AC%2C%C2%B4%2C%E6%B0%B4%2C%D0%94%2C%D0%84'),
'email' : user,
'pass' : passw,
'login' : 'Login'
})
Would you be so kind to tell me what a post_form_id is? And accessorily: would you know what the lsd key/value stands for?
Thanks.
I don't understand why you are trying to "hack" this ...
There is an official api from facebook to read the mailbox of a user, and you need to ask the "read_mailbox" permission for this.
So I advice you to check my post here on how to use facebook and python/django together, and how to login to facebook from python.
And then I would recommend you to read the facebook doc about the messages/inbox.
Basically you need an access_token then you can do http://graph.facebook.com/me/inbox/?access_token=XXX
You can also ask for the "offline_access" permission so you'll need only to get an access token once and you will be able to use it "forever"
And the you can do http://graph.facebook.com/MESSAGE_ID?access_token=XXX to get the details about a particular message.
Or using the api I use in the other thread :
f = Facebook()
res = f.get_object("me/inbox")
...
Feel free to comment if you have any question about this ?

Categories