Sending cookies with python request - python-3.x

I'm trying to make a post request with python's requests module.
I'm passing the headers, cookies, and data as part of the post request.
When I make the request,I get 400 bad request in the output.
I verified the payload and it looks correct to me. I'm wondering If my syntax for cookie is correct.
#!/usr/local/bin/python
import requests
session = "ASDFGHTR/=FGHYTYKSDMN="
lastmanaged = "9ycG9yYXRpb25fRGlyZWN0I"
header = {'akm-accept':'akm/cookie'}
cookie = {'SESSION': session,
'LASTMANAGED':lastmanaged}
data = {'client': '0ad3cfb66-4fa0-b94a-1bf712eae628&grant_type=password_assertion'}
url = "https://hostname-goes-here"
session = requests.Session()
response = session.post(url, headers=header, cookies=cookie, data=data,
verify=False, allow_redirects=False)
print(response.text)
print(response.status_code)
output:
{"code":"invalid_request","title":"One or more fields in request are invalid","incidentId":"f1fbba64-17e4-4d88-852f-01c137fa012e","requestId":"-5011561246754340090","solution":"none"}
400

Related

Problems automating an exploit in Python for a challenge regarding Session Cookies and CSFR tokens

I was doing an exercise on https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-bypass-using-a-brute-force-attack which had to be solved using burpsuite macros. However I decided to solve it by automating it in Python in order to learn and practice since I'm new to the field.
The problem starts by giving you the username:password of the victim and you have to bruteforce the 2FA.
Each request has to contain a session cookie and a csrf token.
To start thing off I will post my code to which I will refer later on. (I'm sorry, I know it's messy and could be shortened, I first wanted it to work and then try to shorten it using functions etc.)
import requests
import json
from bs4 import BeautifulSoup
URL = 'https://0a7a00c804fb9894c0e4dbfd001e005c.web-security-academy.net/login'
URL2 = 'https://0a7a00c804fb9894c0e4dbfd001e005c.web-security-academy.net/login2'
# GET request to /login to obtain the 'csrf' saved to 'csrf' & session token
with open('response_get1.html', 'w') as f:
#Extract the session cookie
session = requests.Session()
cookie_extract = session.get(URL)
cookie_dict = session.cookies.get_dict()
cookie = cookie_dict['session']
headers_get1 = dict(Cookie=f'session={cookie}')
#GET request
get_response = requests.get(url=URL, headers=headers_get1)
data = get_response.content
soup = BeautifulSoup(get_response.text, 'html.parser')
f.write(soup.prettify())
#Exctract the csrf
soup = BeautifulSoup(data, 'html.parser')
csrf = soup.input['value']
# POST request to /login with the csrf & session token
data = dict(csrf=csrf, username='carlos', password='montoya')
headers2= dict(Referer=URL, Cookie=f'session={cookie}')
with open('response_post1.html', 'w') as f:
post_response = requests.post(URL, data=data, headers=headers2, allow_redirects=False)
session = requests.Session()
cookie_extract = session.get(URL)
cookie_dict = session.cookies.get_dict()
#Second cookie saved to 'cookie2'
cookie2 = cookie_dict['session']
if post_response.status_code == 302:
print(f'Redirect successful, status code: {post_response.status_code}\nSecond cookie: {cookie2}')
#TRY
session = requests.Session()
cookie_extract = session.get(URL)
cookie_dict = session.cookies.get_dict()
cookie = cookie_dict['session']
headers_get1 = dict(Cookie=f'session={cookie}')
#GET request
get_response = requests.get(url=URL, headers=headers_get1)
data = get_response.content
soup = BeautifulSoup(get_response.text, 'html.parser')
f.write(soup.prettify())
#Extract the csrf
soup = BeautifulSoup(data, 'html.parser')
csrf = soup.input['value']
data = dict(csrf=csrf, username='carlos', password='montoya')
headers2= dict(Referer=URL, Cookie=f'session={cookie}')
post_response_for_csfr = requests.post(URL, data=data, headers=headers2)
data= post_response_for_csfr.content
soup = BeautifulSoup(data, 'html.parser')
csrf2 = soup.input['value']
print(f'CSFR exctracted: {csrf2}')
#END TRY (doesn't work)
#We have to extract the csrf using the same 'session cookie' but we need allow_redirects=True
#to get a response (with allow_redirects=False we extract the Set-Cookie cookie for the next POST request)
#The problem is above so I don't know whether it's important to check the code below.
headers_post2= {
'Host': '0a7a00c804fb9894c0e4dbfd001e005c.web-security-academy.net',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '51',
'Origin': 'https://0a7a00c804fb9894c0e4dbfd001e005c.web-security-academy.net',
'Connection': 'close',
'Referer': 'https://0a7a00c804fb9894c0e4dbfd001e005c.web-security-academy.net/login2',
'Cookie':f'session={cookie2}',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1'
}
data = {
'csrf':f'{csrf2}',
'mfa-code':'1234'
}
post_response_login2 = requests.post(URL2, data=data, headers=headers_post2)
data = post_response_login2.content
soap = BeautifulSoup(data, 'html.parser')
print(soap.prettify())
I start by sending the first GET request which will give me the first session cookie and the first csrf.
GET /login
Then I send the first POST request with the session cookie and the csrf. As we can see the 302 response will return a Set-Cookie needed for the next GET request.
POST /login
I send the second GET request with the Set-Cookie cookie from the previous POST request, the response will give me the csrf code needed.
GET /login2
Last, I send the last POST request with the cookie from the GET /login2, the csrf obtained in the last passage with the GET /login2 request and the mfa-code. (I will have to implement a threaded bruteforce in the future)
POST /login2
The problem is the first POST request: If I set allow_redirects=True I can easily extract the csrf but then I won't be able to extract the Set-Cookie
If I set allow_redirects=False I can easily extract the Set-Cookie but I won't be able to extract the csrf since there's no page loading with redirects being not allowed.
As you can see,
#TRY
session = requests.Session()
cookie_extract = session.get(URL)
cookie_dict = session.cookies.get_dict()
cookie = cookie_dict['session']
headers_get1 = dict(Cookie=f'session={cookie}')
#GET request
get_response = requests.get(url=URL, headers=headers_get1)
data = get_response.content
soup = BeautifulSoup(get_response.text, 'html.parser')
f.write(soup.prettify())
#Extract the csrf
soup = BeautifulSoup(data, 'html.parser')
csrf = soup.input['value']
data = dict(csrf=csrf, username='carlos', password='montoya')
headers2= dict(Referer=URL, Cookie=f'session={cookie}')
post_response_for_csfr = requests.post(URL, data=data, headers=headers2)
data= post_response_for_csfr.content
soup = BeautifulSoup(data, 'html.parser')
csrf2 = soup.input['value']
print(f'CSFR exctracted: {csrf2}')
#END TRY (doesn't work)
I tried sending another POST request with the same cookie and allow_redirects=True but the csrf is 'Invalid' because from what I suppose/remember the cookie changed or something like that (I gave up debugging at one point).
Now the questions are two:
Can I send the same POST request with allow_redirects=True and allow_redirects=False to get the csrf and the Set-Cookie with the same cookie without any problems? (Just from how it sounds I think it will be impossible)
Is there another way I can solve this problem? (I know I can do it in burp in two minutes but I want to solve it using Python)
Thank you, mass0.

Add (AWS Signature) Authorization to python requests

I am trying to make a GET request to an endpoint which uses AWS Authorization. I made request using postman, It works. But when i tried following method in python, it's giving error.
CODE
url = 'XXX'
payload = {}
amc_api_servicename = 'sts'
t = datetime.utcnow()
headers = {
'X-Amz-Date': t.strftime('%Y%m%dT%H%M%SZ'),
'Authorization': 'AWS4-HMAC-SHA256 Credential={}/{}/{}/{}/aws4_request,SignedHeaders=host;x-amz-date,Signature=3ab1067335503c5b1792b811eeb84998f3902e5fde925ec8678e0ff99373d08b'.format(amc_api_accesskey, current_date, amc_api_region, amc_api_servicename )
}
print(url, headers)
response = requests.request("GET", url, headers=headers, data=payload)
ERROR
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method.
Please point me in the right direction.
import boto3
client = boto3.client('sts')
respone=client.assume_role(RoleArn='your i am urn',RoleSessionName='PostmanNNN')

How to pass Authorization TOKEN into Python requests header

I am trying to make a http request using Python3.8.5 + requests 2.25.0. The request contains Authorization Token in the header.
When use Postman to make the request, I can get response without issue. But, when I use following python code to make the request, it returns 401. Not sure what is worng in the code.
401 {"detail":"Authentication credentials were not provided."}
Following are the python code having issues.
import requests
url = <MY_URL>
payload={}
headers = {
'Authorization': 'TOKEN <MY_TOKEN>'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
The problem resloved by adding a / at the end of the request url. :-)

How to get an user authentication token in a URL-Encoded form and receive a JWT Token using Python?

I'm trying to generate a user authentication token by posting the user name, password in a URL-encoded form, and received a JWT token.
I have tried using payload instead of header and both, but nothing works. I'm using Python 3.7.
import requests
headers = {'username':'username', 'password':'password'}
r = requests.post("https://sso.xxxxxx.com/sso-api/v1/token", headers=headers)
print (r)
I expected the output Response 200 Token generated successfully, but I'm receiving the error Response 404
I was able to to do it the the tips and help from xbound. Instead of header, I had to pass it as data. Then I confirmed that the response was ok and extracted the token.
import requests
payload = {'username':'*******#*********.com', 'password':'**********', 'grant_type':'password', 'scope':'openid'}
r = requests.post("https://***.******.com/***/**/token", data = payload)
##Confirm that reponse is OK!
r.status_code
print(r.status_code == requests.codes.ok)
##Decode json reponse - token
data = r.json()
##Select token
my_token = data['id_token']

python3 -- getting POST request text from requests.post?

I'm using python3. For debugging purposes, I'd like to get the exact text that is sent to the remote server via a requests.post command. The requests.post object seems to contain the response text, but I'm looking for the request text.
For example ...
import requests
import json
headers = {'User-Agent': 'Mozilla/5.0'}
payload = json.dumps({'abc':'def','ghi':'jkl'})
url = 'http://example.com/site.php'
r = requests.post(url, headers=headers, data=payload)
How do I get the text of the exact request that is sent to url via this POST command?

Resources