logging into a twitter using python3 and requests - python-3.x

I have a project that I am working on, and the requirements are to login to a website using a username and password. I have to do it in python, and then be able to access a part of the site only accessible to people who are logged in. I have tried a few variations of coding to do this, and haven't been able to successfully log in yet. Here is my coding:
the function to login to it:
def session2(url):
#r = requests.get(url)
#ckies = []
#print("here are the cookies for twitter:\n")
#for cky in r.cookies:
# print(cky.name, cky.value)
# ckies.append(cky)
s = requests.Session()
session = s.get(url, verify=False)
print("\nheaders from site\n")
print(session.headers)
tree = html.fromstring(session.text)
# extract the auth token needed to login along with username and password
auth_token = list(set(tree.xpath("//input[#name='authenticity_token']/#value")))[0]
uname = "username"
pword = "password"
username = 'session[username_or_email]'
password = 'session[password]'
# payload = {name of username variable : string you want, name of password variable:
# string you want, name of auth token: string gotten from session
payload = dict(username = uname, password = pword , authenticity_token = auth_token)
header = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'}
#do post request
# might have to change headers to be a header for chrome
response = s.post(
url,
data = payload,
#headers = dict(referer = url)
headers = header
)
print("\nheaders post\n")
print(response.request.headers)
session = s.get("http://www.twitter.com/username/followers", verify=False)
print("\nheaders get\n")
print(session.headers)
print("\nhtml doc\n")
print(session.text)
return session
code to call it:
url = "http://www.twitter.com/login"
sessions = session2(url)
the username on the site looks like this when you inspect it:
<input class="js-username-field email-input js-initial-focus" type="text" name="session[username_or_email]" autocomplete="on" value="" placeholder="Phone, email or username">
and the password section/token section look like this:
<input class="js-password-field" type="password" name="session[password]" placeholder="Password">
<input type="hidden" value="ef25cb09a8c7fe16c54e3df099e206e605b1170a" name="authenticity_token">
I know the auth token changes, which is why i have it get it from the function. When I try to run this, it just goes to the main page rather than the page i need.
One problem I think is that when I print out the header that I send in the post, it says:
{'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'Accept': '/', 'User-Agent': 'python-requests/2.9.1'}
which I thought I changed to chrome's header, but it doesn't seem to stick.
Also, I know there is a way if I use Oauth, but I'm not allowed to use that, i have to do it based on being able to login like I'm using a browser.
Can you tell me if there is anything wrong with what I've done, as well as any hints on how to fix it? I've tried other stack overflow problems using requests and logging in, but those didn't work either.
EDIT: ok, i did a response.request.headers, and it came out with the right header, i think, so i don't think that is the problem
header it prints:
{'Accept': '*/*', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36', 'Cookie': '_twitter_sess=some huge amount of number/letters; guest_id=v1%3A147509653977967101', 'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate'}

This will log you in:
import requests
from bs4 import BeautifulSoup
username = "uname"
password = "pass"
# login url
post = "https://twitter.com/sessions"
url = "https://twitter.com"
data = {"session[username_or_email]": username,
"session[password]": password,
"scribe_log": "",
"redirect_after_login": "/",
"remember_me": "1"}
with requests.Session() as s:
r = s.get(url)
# get auth token
soup = BeautifulSoup(r.content, "lxml")
AUTH_TOKEN = soup.select_one("input[name=authenticity_token]")["value"]
# update data, post and you are logged in.
data["authenticity_token"] = AUTH_TOKEN
r = s.post(post, data=data)
print(r.content)
You can see if we run it using my own account, we get my name from my profile:
In [30]: post = "https://twitter.com/sessions"
In [31]: url = "https://twitter.com"
In [32]: data = {"session[username_or_email]": username,
....: "session[password]": password,
....: "scribe_log": "",
....: "redirect_after_login": "/",
....: "remember_me": "1"}
In [33]: with requests.Session() as s:
....: r = s.get(url)
....: soup = BeautifulSoup(r.content, "lxml")
....: AUTH_TOKEN = soup.select_one("input[name=authenticity_token]")["value"]
....: data["authenticity_token"] = AUTH_TOKEN
....: r = s.post(post, data=data)
....: soup = BeautifulSoup(r.content, "lxml")
....: print(soup.select_one("b.fullname"))
....:
<b class="fullname">Padraic Cunningham</b>
Just be aware each time you login, you will the We noticed a recent login for your account ... email.

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.

How to do properly a facebook mobile site login

I'm trying to develop some code in order to make successful facebook logins. Now, to simplify as much as possible, i use the mbasic.facebook.com address.
My code is the following (using requests in python latest version):
if __name__ == '__main__':
base_url = 'https://mbasic.facebook.com'
with requests.session() as session:
user_agent = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/76.0.3809.87 Safari/537.36"
)
cookie = 'locale=it_IT;'
default_headers = {
'User-Agent': user_agent,
'Accept-Language': 'it-IT,en;q=0.5',
'cookie': cookie,
}
session.headers.update(default_headers)
login_form_url = '/login/device-based/regular/login/?refsrc=https%3A%2F%2Fmbasic.facebook.com%2F&lwv=100&ref' \
'=dbl '
r = session.get("https://mbasic.facebook.com/login/")
page1 = BeautifulSoup(r.text, "lxml")
form = page1.find('form')
lsd = page1.find('input', {'name': 'lsd'})['value']
jazoest = page1.find('input', {'name': 'jazoest'})['value']
mts = page1.find('input', {'name': 'm_ts'})['value']
li = page1.find('input', {'name': 'li'})['value']
try_number = page1.find('input', {'name': 'try_number'})['value']
unrecognized_tries = page1.find('input', {'name': 'unrecognized_tries'})['value']
data = {'lsd': lsd, 'jazoest': jazoest, 'm_ts': mts, 'li': li, 'try_number': try_number,
'unrecognized_tries': unrecognized_tries, 'email': credentials["email"], 'pass': credentials["pass"],
'login': 'Accedi'}
r = session.post(base_url + login_form_url, data=data, verify=False)
# now, i need to complete the second part of the login
h = open("first_login.html", "w", encoding="utf-8")
h.write(r.text)
c = BeautifulSoup(r.text, "lxml")
form = c.find('a')
action = form.get('href')
r = session.get(base_url + action, data=data, verify=False)
f = open("second_login.html", "w", encoding="utf-8")
f.write(r.text)
Now, with this code i successfully get my home feed as a logged user. However, the problem begins when i try to move for instance to one specific facebook public page, because it returns me the page as if i wasn't logged in. The same weird thing happens when i try to get a specific post, because it doesn't show me any comments, like it does in my browser.
I tried to play with session cookies but to no avail.
Help
The solution was to change the user agent to:
Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.3057 Mobile Safari/537.35+

Python3 Web-scraping cant login to the page? Timestamp?

So i just started to learn web-scraping with python3 and i want to login to this website: https://dienynas.tamo.lt/Prisijungimas/Login
The form data it requires is:
UserName: username,
Password: password,
IsMobileUser: false,
ReturnUrl: '',
RequireCaptcha: false,
Timestamp: 2020-03-31 14:11:21,
SToken: 17a48bd154307fe36dcadc6359681609f4799034ad5cade3e1b31864f25fe12f
this is my code:
from bs4 import BeautifulSoup
import requests
from lxml import html
from datetime import datetime
data = {'UserName': 'username',
'Password': 'password',
'IsMobileUser': 'false',
'ReturnUrl': '',
'RequireCaptcha': 'false'
}
login_url = 'https://dienynas.tamo.lt/Prisijungimas/Login'
url = 'https://dienynas.tamo.lt/Pranesimai'
with requests.Session() as s:
r = s.get(login_url)
soup = BeautifulSoup(r.content, "lxml")
AUTH_TOKEN = soup.select_one("input[name=SToken]")["value"]
now = datetime.now()
data['Timestamp'] = f'{now.year}-{now.month}-{now.day} {now.hour}:{now.minute}:{now.second}'
data["SToken"] = AUTH_TOKEN
r = s.post(login_url, data=data)
r = s.get(url)
print(r.text)
And I cant login to the page, I think I did Timestamp wrong? Please help :)
Edit: so today i changed my code a little bit because i found out that most data i need were in hidden inputs so:
data = {'UserName': 'username',
'Password': 'password',
}
AUTH_TOKEN = soup.find("input",{'name':"SToken"}).get("value")
Timestamp = soup.find("input",{'name':"Timestamp"}).get("value")
IsMobileUser = soup.find("input",{'name':"IsMobileUser"}).get("value")
RequireCaptcha = soup.find("input", {'name': "RequireCaptcha"}).get("value")
ReturnUrl = soup.find("input", {'name': "ReturnUrl"}).get("value")
and added this to data dictionary, i also tried to create headers:
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}
r = s.post(login_url, data=data, headers=headers)
and yeah nothing works for me.. Maybe there is a way to find out why I cant login?
I agree with you .It seems you are not sending the correct timestamp .
The website has an input for it so you can scrape it like the token and send it or you can generate the same timestamp with the same time zone the website is using
from bs4 import BeautifulSoup
import requests
from lxml import html
from datetime import datetime
from pytz import timezone
data = {'UserName': 'username',
'Password': 'password',
'IsMobileUser': 'false',
'ReturnUrl': '',
'RequireCaptcha': 'false'
}
login_url = 'https://dienynas.tamo.lt/Prisijungimas/Login'
url = 'https://dienynas.tamo.lt/Pranesimai'
with requests.Session() as s:
r = s.get(login_url)
soup = BeautifulSoup(r.content, "lxml")
AUTH_TOKEN = soup.find("input",{'name':"SToken"}).get("value")
Timestamp = soup.find("input",{'name':"Timestamp"}).get("value") #2020-03-31 15:36:37
now = datetime.now(timezone('Etc/GMT-3'))
data['Timestamp'] = now.strftime('%Y-%m-%d %H:%M:%S') #2020-03-31 15:36:36
print('Timestamp from website',Timestamp)
print('Timestamp from python',data['Timestamp'])
data["SToken"] = AUTH_TOKEN
r = s.post(login_url, data=data)
r = s.get(url)
print(r.text)

Why using cookie to login a website failed in python3?

I want to use cookie that i have got to access a website and get some information only can be seen after user login, but when me try it, the result shows the user isn't login the website, this is my code, someone can tell me how to fix the problem?
LOGIN_URL ="https://www.yaozh.com/login/"
values = {'username': 'username', 'pwd': 'password'} # , 'submit' : 'Login'
postdata = urllib.parse.urlencode(values).encode()
user_agent = r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'
headers = {'User-Agent': user_agent, 'Connection': 'keep-alive'}
cookie_filename = 'cookie.txt'
cookie = http.cookiejar.MozillaCookieJar(cookie_filename)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
request = urllib.request.Request(LOGIN_URL, postdata, headers)
try:
response = opener.open(request)
page = response.read().decode()
# print(page)
except urllib.error.URLError as e:
print(e.code, ':', e.reason)
cookie.save(ignore_discard=True, ignore_expires=True)
print(cookie)
for item in cookie:
print('Name = ' + item.name)
print('Value = ' + item.value)
get_url = 'https://db.yaozh.com/instruct?p=1&pageSize=20'
get_request = urllib.request.Request(get_url, headers=headers)
get_response = opener.open(get_request)
print(get_response.read())
bs=BeautifulSoup(get_response,"html.parser")
urls=bs.find_all(name='a',attrs={"href":re.compile("\.doc")},recursive=True)
print(len(urls))
for url in urls:
print(url["href"])
The problem has been solved, if you face same problem, i guess you should chcek the information post to server is all? Many websites need some imformation that true users can't see to judge the requester is true user. Good luck for you!

Flurry scraping using python3 requests.Session()

This seems really straight forward, but for some reason this isn't connecting to flurry correctly and I unable to scrape the data.
loginurl = "https://dev.flurry.com/secure/loginPage.do"
csvurl = "https://dev.flurry.com/eventdata"
session = requests.Session()
login = session.post(loginurl, data={'loginEmail': 'user', 'loginPassword': 'pass'})
data = session.get(csvurl)
Every time I try to use this, I get redirected back to the login screen (loginurl) without fetching the new data. Has anyone been able to connect to flurry like this successfully before?
Any and all help would be greatly appreciated, thanks.
There are two more form fields to be populated struts.token.name and the value from struts.token.name i.e token, you also have to post to loginAction.do:
You can do an initial get and parse the values using bs4 then post the data:
from bs4 import BeautifulSoup
import requests
loginurl = "https://dev.flurry.com/secure/loginAction.do"
csvurl = "https://dev.flurry.com/eventdata"#
data = {'loginEmail': 'user', 'loginPassword': 'pass'}
with requests.Session() as session:
session.headers.update({
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36"})
soup = BeautifulSoup(session.get(loginurl).content)
name = soup.select_one("input[name=struts.token.name]")["value"]
data["struts.token.name"] = name
data[name] = soup.select_one("input[name={}]".format(name))["value"]
login = session.post(loginurl, data=data)

Resources