2019xman-shellmaster wp

  1. Write up
  2. 题目源码
  3. 分析
    1. $0 Get Shell

题挺有意思的,写这篇主要目的是记录一下探索的过程(扶一下眼镜)

好像有点装了hhhhhhh

Write up

$0 起一个shell

发现cat不能用 进/usr/bin里看看能用什么

所以用head读flag

题目源码

虽然拿到shell之后可以查看源码 但赛方目前还没有公开源码

所以这里贴出自己写的一段跟题目逻辑类似的代码:

import os 
import sys
while True:
    a = raw_input("Input something:").upper()
    sys.stdout.flush()
    if a != "":
        print "Res: {}".format(os.system(a + " 2>&1"))

题目原本对输入进行了黑名单过滤,但是不知道为啥被注释掉了。。。

分析

$0 Get Shell

$0含义

首先来看一个例子

可以看到$0可以返回执行该语句的文件的文件名

在python中使用$0调出命令行

再来看个例子:

可以看到 在往os.system()方法中传入$0是可以获取到shell的

对os.system的分析

看看官方文档对os.system的解释:

简单来说就是python里的os.system是通过调用c里的system函数来实现功能的

那么就看看C源码里是怎么写system函数的(这里分析的是glibc,也就是linux里用的c)

C源码官方下载: http://ftp.gnu.org/gnu/libc/

定义system的c文件在glibc/sysdeps/posix/system.c

也可以在https://code.woboq.org/userspace/glibc/sysdeps/posix/system.c.html在线查看

注意下面的内容(glibc版本:2.29 单行注释是我加的):

postix_spawn的解释

关于postix_spawn()的用法可以看:https://blog.csdn.net/linux_ever/article/details/50295105

示例demo如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>

extern char **environ;

void run_cmd(char *cmd)
{
    pid_t pid;
    char *argv[] = {"sh", "-c", cmd, NULL};
    int status;
    printf("Run command: %s\n", cmd);
    status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
    if (status == 0) {
        printf("Child pid: %i\n", pid);
        if (waitpid(pid, &status, 0) != -1) {
            printf("Child exited with status %i\n", status);
        } else {
            perror("waitpid");
        }
    } else {
        printf("posix_spawn: %s\n", strerror(status));
    }
}

int main(int argc, char* argv[])
{
    run_cmd(argv[1]);
    return 0;
}

运行结果如下:

posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ)

/bin/sh的效果就类似于sh脚本中开头的#!/bin/sh

argv就类似于shell脚本中要执行的代码,比如这里执行sh -c cmd,而cmd由用户输入

总结

所以python里os.system的执行过程就相当于(这里使用相同功能的代码做演示):

1.先执行python代码

import os
os.system('$0')

2.之后是C

#include <stdio.h>
int main()
{
    system('$0');
    return 0;
}

3.最后执行系统命令

sh -c $0

这样就成功逃逸了


如果我的文章能帮到您的话我会很开心.如需转载记得注明出处:)
目录