首先呢,这个平台有两种做题方式:一种是在网页上用vscode在线玩,一种是用ssh远程连接到做题平台玩。当然,远程连上去的话环境基本没问题,就是文件down下来比较费劲(可以用这个cat 文件名 | base64),MobaXterm毕竟可以直接拖下来2333

第一题

执行就好

第二题

将文件拖下来直接逆向
image.png
尝试后得到flag

第三题

执行程序的时候可以看到有提示,程序会检查命令行输入,并且检查的值也给了,冲就行了

第四题

看提示需要设置一个环境变量,export xxx=xxx直接设置就行

第五题

怎么说呢,做法我第一时间想到了,但是没做出来,还放了好久,为什么呢?因为他丫的tmp下没有那个文件啊,我当时还不知道怎么操作的,创建文件没创建出来,就离谱

这个做法感觉可能不是它要求的做法,按他的要求感觉是要用py脚本?
输入可以用这个方法

./xxxx < /xxxx

第六题

和上一题一样的方法,很简单,但还是感觉可能不对,先留着

第七题

加个env -i前缀

第八题

写个sh脚本启动即可

第九题

同上,多了个输入而已

第十题

没啥大区别嗷

第十一题

和在命令行里操作一样,无非是写到文件里了

第十二题

一样一样的

13

简单+1

14

简单+1

15

ipython中一步一步敲之前在py文件中写的exp脚本就行

16

同上

17

还是得多看看官方文档,确实啥都有
放几个
image.png

18

注意env参数的传入类型是“dict”

19

stdin参数要求传入的是一个int值,我是用open打开了文件在传入,不知道还有其他方法么

20

没啥好说的,和上面一样

重复的太多了,碰到有意思的再开始记录吧...

29

emmm,c脚本,确实费了些功夫

#include<iostream>
#include<cstdlib>
#include <unistd.h>
#include<sys/wait.h>
using namespace std;

void pwncollege()
{
    return;
}

int main()
{
    int pid = fork();

    if(pid < 0)
    {
        cout <<"error in fork";
        exit(1);
    }
    else if(pid == 0)
    {
        int test;
        cout << "ecexl被调用\n";
        if(execl("/challenge/embryoio_level29",NULL) == -1)
        { 
            cout <<"error in execl\n";
            exit(1);
        }
    }
    else
    {
        wait(NULL);
        cout <<"is complete\n";
        exit(0);
    }

    return 0;
}

32

用execve执行,改动如下

    else if(pid == 0)
    {
        int test;
        cout << "ecexl被调用" << endl;
        char* env[] = {"rcatch=qztpuehxzz", NULL};
        char* argv1[] = {"embryoio_level32", NULL};
        if(execve("/challenge/embryoio_level32", argv1, env) == -1)
        { 
            cout <<"error in execl" << endl;
            exit(1);
        }
    }

33

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

void pwncollege()
{
    return;
}


int main(void)
{
    pid_t pid;
    int fd;

    fd = open("/tmp/yxvcxs", O_RDWR);
    // write(fd, "mrqhmacp\n", 9);

    if (fd < 0) 
    {
        perror("open");
        return EXIT_FAILURE;
    }

    if ((pid = fork()) < 0) 
    {
        perror("fork");
        return EXIT_FAILURE;
    } 
    else if (! pid) 
    { 
        /* child */
        dup2(fd, STDIN_FILENO);
        close(fd);
        execlp("/challenge/embryoio_level33", "embryoio_level33", NULL);
        perror("exec");
        return EXIT_FAILURE;
    } 
    else 
    { 
        /* parent */
        close(fd);
        printf("Parent waiting\n");
        getchar();
    }

    return EXIT_SUCCESS;
}

35

目前的c脚本

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

void pwncollege()
{
    return;
}


int main(void)
{
    pid_t pid;
    int fd;

    fd = open("a.py", O_RDWR);
    // write(fd, "mrqhmacp\n", 9);

    if (fd < 0) 
    {
        perror("open");
        return EXIT_FAILURE;
    }

    if ((pid = fork()) < 0) 
    {
        perror("fork");
        return EXIT_FAILURE;
    } 
    else if (! pid) 
    { 
        /* child */
        // dup2(fd, STDOUT_FILENO);
        close(fd);
        char* env[] = {NULL};
        char* argv1[] = {"embryoio_level35", NULL};
        execve("/challenge/embryoio_level35", argv1, env);
        perror("exec");
        return EXIT_FAILURE;
    } 
    else 
    { 
        /* parent */
        close(fd);
        printf("Parent waiting\n");
        getchar();
    }

    return EXIT_SUCCESS;
}

36

管道开始了,加个“|”即可

40

直接cat | xxx

41

经群里师傅提醒,写了个大文件,每行一个密码的倒序,然后就可以通过检查

46

写文件

48

卧槽折磨,研究了有一天左右,最后找到一篇文章
python中的subprocess.Popen()使用
用到的核心内容如下
image.png
所以最后的脚本其实只有几行

import subprocess

p1 = subprocess.Popen(["/challenge/embryoio_level48"], stdout=PIPE, shell=False)
p2 = subprocess.Popen(["cat"], stdin=p1.stdout, stdout=PIPE, shell=False)

print(p2.communicate()[0])

ipython中用%run a.py来运行脚本
晚上可以睡个好觉了,真好(PS:发现subprocess确实好用)

53

艹哦,这个题按之前的做法一直不合适,服了,半个早上就又过去了,最终用rev大文件完成的,但这又是为什么呢

p2 = subprocess.Popen(['rev'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
p1 = subprocess.Popen(['echo', 'dfa'], stdout=p2.stdin, shell=False)
p3 = subprocess.Popen(['/challenge/embryoio_level53'], stdin=p2.stdout, shell=False)

这个为什么不行呢???

额。。。时隔不到半分钟,搞出来了?

import subprocess

p2 = subprocess.Popen(['rev'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
p1 = subprocess.Popen(['echo', 'ooafrssy'], stdout=p2.stdin, shell=False)
p3 = subprocess.Popen(['/challenge/embryoio_level53'], stdin=p2.stdout, shell=False)

还是这个脚本,但是在运行结束后需要退出才能显示出结果?如图
image.png

emmmm.....?

54

开始python脚本系列,因为上一个ipython就是用脚本来做的,所以差不多无压力过

# -*- coding:utf-8 -*-
import subprocess

p2 = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
# p1 = subprocess.Popen(['echo', 'ooafrssy'], stdout=p2.stdin, shell=False)
p3 = subprocess.Popen(['/challenge/embryoio_level54'], stdout=p2.stdin, shell=False)

print(p2.communicate())

58

#-*- coding:utf-8 -*-
import subprocess

p2 = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
p1 = subprocess.Popen(['echo', 'vuyjywwm'], stdout=p2.stdin, shell=False)
p3 = subprocess.Popen(['/challenge/embryoio_level58'], stdin=p2.stdout, stdout=subprocess.PIPE, shell=False)


print(p3.communicate())

59

很烦,没有用想用的方式做出来

#-*- coding:utf-8 -*-
import subprocess
 
p2 = subprocess.Popen(['rev', 'aaa'], stdout=subprocess.PIPE, shell=False)
# p1 = subprocess.Popen(['echo', 'vuyjywwm'], stdout=p2.stdin, shell=False)
p3 = subprocess.Popen(['/challenge/embryoio_level59'], stdin=p2.stdout, shell=False)

# p2.stdin.close()
# p2.stdout.close()
print(p3.communicate())
# print(p3.stdout.readlines())

60

好家伙折磨死,这个题卡了有些日子了
代码

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <iostream>
using namespace std;
 
void pwncollege()
{
    return;
}
 
int main()
{
    int fd[2];
    if( pipe(fd)==-1 )
    {
        perror("pipe");
        exit(1);
    }

    int pid = fork();
    if(pid < 0)
        perror("fork");
    else if(pid == 0)
    {   
        printf("in child 1, pid = %d\n", getpid()); 
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);
        if(execl("/usr/bin/cat", "cat", NULL) == -1)
        { 
            perror("exec");
            exit(1);
        }
    }
    else
    {
        int pid2 = fork();
        if(pid2 < 0)
            perror("fork");
        else if(pid2 == 0)
        {
            printf("in child 2, pid = %d\n", getpid()); 
            close(fd[0]);
            dup2(fd[1], STDOUT_FILENO);
            if(execl("/challenge/embryoio_level60", "embryoio_level60", NULL) == -1)
                perror("exec");
        }
        else
            wait(NULL);
    }

    return 0;
}

参考文献:
- https://book.itheima.net/course/223/1277519158031949826/1277528240394608641
- https://blog.csdn.net/nyist327/article/details/35782015

66

去搜find命令参数可以发现存在这么一参数
image.png

find /challenge/ -name embryoio_level66 -exec {} ;

69

昨晚睡觉的时候突然想到这道题该怎么做,挺离谱的
69-71,规定只能用shell执行,但是又需要设置argv和env,但是有个问题他需要让argc等于0,也就是说argv一个都不能有,但是从shell执行就肯定会有argv[0]
然后昨晚突然想到,c语言中execve并不会新开进程,会继承pid,也就是说如果在shell中执行c,c中写一个execve调用程序执行,程序只会检测到shell执行,那这不就好了么,直接写c冲即可。

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <iostream>
using namespace std;
 
void pwncollege()
{
    return;
}

int main(void)
{
    
    char* env[] = {"88=tnhtuzljpg", NULL};
    char* argv1[152] = {"embryoio_level71", NULL};
    for(int i=1; i<150; i++)
        argv1[i]="shaqbgubju";
    execve("/challenge/embryoio_level71", argv1, env);
    perror("execve");
    // perror("exec");

    return EXIT_SUCCESS;
}

74

from pwn import *

argv1 = ['/challenge/embryoio_level74']

for i in range(220):
    argv1.append("fsddiocatb")

r = process(argv1)

r.interactive()

79

from pwn import *
r = process("/challenge/embryoio_level79", stdin=open("ncoifg", "w"), shell=False, cwd='/tmp/mdzobq')
r.interactive()

84

chdir("/tmp/gktqco"); // 需要目录已存在,不然转换失败

88

创建一个链接文件再继续
ln -s /challenge/xxx /tmp/xxx

89

export PATH=./:PATH

90

mkfifo参考
image.png

92

输入输出同时重定向
image.png

94

需要传入一个文件描述符
想了好久传不进去
突然想到文件描述符也是一个int参数啊,那既然这样直接命令行参数写一个数字呢?试了下可以的

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <iostream>
using namespace std;
 
 
int main()
{
    int fd;
    fd = open("./file/0", O_RDWR);
    fd = open("./file/1", O_RDWR);
    fd = open("./file/2", O_RDWR);
    fd = open("./file/3", O_RDWR);
    fd = open("./file/4", O_RDWR);
    fd = open("./file/5", O_RDWR);
    fd = open("./file/6", O_RDWR);
    fd = open("./file/7", O_RDWR);
    fd = open("./file/8", O_RDWR);
    fd = open("./file/9", O_RDWR);
    fd = open("./file/10", O_RDWR);
    fd = open("./file/11", O_RDWR);
    fd = open("./file/12", O_RDWR);
    fd = open("./file/13", O_RDWR);
    fd = open("./file/14", O_RDWR);
    fd = open("./file/15", O_RDWR);
    fd = open("./file/16", O_RDWR);
    fd = open("./file/17", O_RDWR);
    fd = open("./file/18", O_RDWR);
    fd = open("./file/19", O_RDWR);
    fd = open("./file/20", O_RDWR);
    fd = open("./file/21", O_RDWR);
    fd = open("./file/22", O_RDWR);
    fd = open("./file/23", O_RDWR);
    fd = open("./file/24", O_RDWR);
    fd = open("./file/25", O_RDWR);
    fd = open("./file/26", O_RDWR);
    fd = open("./file/27", O_RDWR);
    fd = open("./file/28", O_RDWR);
    fd = open("./file/29", O_RDWR);
    fd = open("./file/30", O_RDWR);
    fd = open("./file/31", O_RDWR);
    fd = open("./file/32", O_RDWR);
    fd = open("./file/33", O_RDWR);
    fd = open("./file/34", O_RDWR);
    fd = open("./file/35", O_RDWR);
    fd = open("./file/36", O_RDWR);
    fd = open("./file/37", O_RDWR);
    fd = open("./file/38", O_RDWR);
    fd = open("./file/39", O_RDWR);
    fd = open("./file/40", O_RDWR);
    fd = open("./file/41", O_RDWR);
    fd = open("./file/42", O_RDWR);
    fd = open("./file/43", O_RDWR);
    fd = open("./file/44", O_RDWR);
    fd = open("./file/45", O_RDWR);
    // fd = open("./file/46", O_RDWR);
    // fd = open("./file/47", O_RDWR);
    // fd = open("./file/48", O_RDWR);
    // fd = open("./file/49", O_RDWR);
    cout << fd<< endl;


    // char* env[] = {NULL};
    // char* argv1[] = {"embryoio_level94", NULL};
    execl("/challenge/embryoio_level94", "embryoio_level94", "58", NULL);
    perror("execl");
    sleep(5);
 
    return 0;
}

97

kill -l 可以看到全部的标志
找到自己需要的后
kill -数字 PID

101

ln -s

104

stdout=open("xxx", mode='w')

109

经@hurricane618师傅提醒,最终用sys强行重定向,确实牛逼

from pwn import *
context.log_level = 'info'

r = process("/challenge/embryoio_level109", stdin=sys.stdout, stdout=sys.stdin)

r.interactive()

这个东西是怎么输出出来的呢,有些离谱

120

都是前面做过的模型
代码优化了一下

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <iostream>
using namespace std;

void pwncollege(){
    return;
}

int main()
{
    int fd;
    string file="./file/";

    for(int i=0; i<314; i++){
        string filex = file + to_string(i);
        const char* filename = filex.c_str();
        open(filename, O_RDWR);
    }

    int pid;
    pid = fork();
    perror("fork");

    if(pid==0){
        execl("/challenge/embryoio_level120", "embryoio_level120", "314", NULL);
        perror("execl");
    }
    else
        wait(NULL);

    return 0;
}
file = "./file/"

for i in range(314):
    open(file+str(i), mode='w')

121

擦,c++的stderr终于搞定了,之前一直没想来
顺带改进一下脚本

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
using namespace std;

void pwncollege(){
    return;
}


int main(void)
{
    pid_t pid;
    int fd;

    fd = open("./mkfifo1", O_RDWR);
    perror("open");

    pid = fork();
    if ( pid==0 ) 
    { 
        dup2(fd, STDERR_FILENO);
        execl("/challenge/embryoio_level121", "embryoio_level121", NULL);
        perror("exec");
        return EXIT_FAILURE;
    } 
    else 
        wait(NULL);

    return EXIT_SUCCESS;
}

125

倒腾了两天倒腾了这么个玩儿,也是服了,一开始没想到的道路

from pwn import *
context.log_level='info'
r = process(['bash', './a.sh'])

r.recvuntil(b"you will need to compute responses for.\n")

try:
    while True:
        text = r.recv(10240, timeout=3).decode("utf-8")
        # log.info(text)
        if "Please send the solution for:" in text:
            exp = text[text.find(":")+2:-1]
            exp = "python -c " + "\"print(" + exp + ")\""
            log.info(exp)
            cal = subprocess.getoutput(exp)
            # log.success(cal)
            r.sendline(cal)
        else:
            if "flag" in text:
                text += r.recvall().decode("utf-8")
                # log.info(text)
                log.success(text[text.find("pwn.college{"):-1])
                break
except:
    log.error("Error")

127

pwntools真牛逼

from pwn import *
context.log_level='info'
r = process(['bash', './a.sh'])

r.recvuntil(b"[TEST] You must send me (PID ")
pid = int((r.recvuntil(")").decode("utf-8"))[:-1], 10)
log.success("pid = {}".format(str(pid)))
r.recvuntil(b"in exactly this order: ['")

signals = (r.recvuntil(b"']").decode('utf-8'))[:-2]
signal_list = signals.split("', '")
print(signal_list)

signal_all = ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGKILL', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGPIPE', 'SIGALRM', 'SIGTERM', 'SIGSTKFLT', 'SIGCHLD', 'SIGCONT', 'SIGSTOP', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU', 'SIGURG', 'SIGXCPU', 'SIGXFSZ', 'SIGVTALRM', 'SIGPROF', 'SIGWINCH', 'SIGIO', 'SIGPWR', 'SIGSYS', 'SIGRTMIN', 'SIGRTMIN+1', 'SIGRTMIN+2', 'SIGRTMIN+3', 'SIGRTMIN+4', 'SIGRTMIN+5', 'SIGRTMIN+6', 'SIGRTMIN+7', 'SIGRTMIN+8', 'SIGRTMIN+9', 'SIGRTMIN+10', 'SIGRTMIN+11', 'SIGRTMIN+12', 'SIGRTMIN+13', 'SIGRTMIN+14', 'SIGRTMIN+15', 'SIGRTMAX-14', 'SIGRTMAX-13', 'SIGRTMAX-12', 'SIGRTMAX-11', 'SIGRTMAX-10', 'SIGRTMAX-9', 'SIGRTMAX-8', 'SIGRTMAX-7', 'SIGRTMAX-6', 'SIGRTMAX-5', 'SIGRTMAX-4', 'SIGRTMAX-3', 'SIGRTMAX-2', 'SIGRTMAX-1', 'SIGRTMAX']
for signal in signal_list:
    num = signal_all.index(signal)+1
    # log.info("num=>{}".format(str(num)))
    exp = "kill -" + str(num) + " " + str(pid)
    log.info(exp)
    subprocess.getoutput(exp)
    r.recv()

text = r.recvall().decode("utf-8")
if "flag" in text:
    log.success(text[text.find("pwn.college{"):-1])
else:
    exit(1)

Q.E.D.


来都来了,点个广告再走吧(=・ω・=)