首先呢,这个平台有两种做题方式:一种是在网页上用vscode在线玩,一种是用ssh远程连接到做题平台玩。当然,远程连上去的话环境基本没问题,就是文件down下来比较费劲(可以用这个cat 文件名 | base64
),MobaXterm毕竟可以直接拖下来2333
第一题 执行就好
第二题 将文件拖下来直接逆向 尝试后得到flag
第三题 执行程序的时候可以看到有提示,程序会检查命令行输入,并且检查的值也给了,冲就行了
第四题 看提示需要设置一个环境变量,export xxx=xxx
直接设置就行
第五题 怎么说呢,做法我第一时间想到了,但是没做出来,还放了好久,为什么呢?因为他丫的tmp下没有那个文件啊,我当时还不知道怎么操作的,创建文件没创建出来,就离谱
这个做法感觉可能不是它要求的做法,按他的要求感觉是要用py脚本? 输入可以用这个方法
第六题 和上一题一样的方法,很简单,但还是感觉可能不对,先留着
第七题 加个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); if (fd < 0 ) { perror ("open" ); return EXIT_FAILURE; } if ((pid = fork()) < 0 ) { perror ("fork" ); return EXIT_FAILURE; } else if (! pid) { dup2 (fd, STDIN_FILENO); close (fd); execlp ("/challenge/embryoio_level33" , "embryoio_level33" , NULL ); perror ("exec" ); return EXIT_FAILURE; } else { 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); if (fd < 0 ) { perror ("open" ); return EXIT_FAILURE; } if ((pid = fork()) < 0 ) { perror ("fork" ); return EXIT_FAILURE; } else if (! pid) { close (fd); char * env[] = {NULL }; char * argv1[] = {"embryoio_level35" , NULL }; execve ("/challenge/embryoio_level35" , argv1, env); perror ("exec" ); return EXIT_FAILURE; } else { 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 subprocessp1 = 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 subprocessp2 = 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 import subprocessp2 = subprocess.Popen(['cat' ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, 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 import subprocessp2 = 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 import subprocess p2 = subprocess.Popen(['rev' , 'aaa' ], stdout=subprocess.PIPE, shell=False ) p3 = subprocess.Popen(['/challenge/embryoio_level59' ], stdin=p2.stdout, shell=False ) print (p3.communicate())
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" ); 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 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" ) 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) r.sendline(cal) else : if "flag" in text: text += r.recvall().decode("utf-8" ) 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 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 )