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

第一题

执行就好

第二题

将文件拖下来直接逆向

尝试后得到flag

第三题

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

第四题

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

第五题

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

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

1
./xxxx < /xxxx

第六题

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

第七题

加个env -i前缀

第八题

写个sh脚本启动即可

第九题

同上,多了个输入而已

第十题

没啥大区别嗷

第十一题

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

第十二题

一样一样的

13

简单+1

14

简单+1

15

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

16

同上

17

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

18

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

19

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

20

没啥好说的,和上面一样

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

29

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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执行,改动如下

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#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脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#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()使用
用到的核心内容如下

所以最后的脚本其实只有几行

1
2
3
4
5
6
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大文件完成的,但这又是为什么呢

1
2
3
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)

这个为什么不行呢???

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

1
2
3
4
5
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)

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

emmmm…..?

54

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

1
2
3
4
5
6
7
8
# -*- 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

1
2
3
4
5
6
7
8
9
#-*- 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

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

1
2
3
4
5
6
7
8
9
10
11
#-*- 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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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命令参数可以发现存在这么一参数

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冲即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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

1
2
3
4
5
6
7
8
9
10
from pwn import *

argv1 = ['/challenge/embryoio_level74']

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

r = process(argv1)

r.interactive()

79

1
2
3
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参考

92

输入输出同时重定向

94

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#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强行重定向,确实牛逼

1
2
3
4
5
6
from pwn import *
context.log_level = 'info'

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

r.interactive()

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

120

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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;
}
1
2
3
4
file = "./file/"

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

121

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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真牛逼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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)