!(D:\WeChat Files\wxid_rrhexqq92cwp22\FileStorage\Temp\fd2c273244f9cb5f834f2589db860eb.png)
var name = requset.get("name") `
var cmd = "echo 'Hello " + name + "'"
RUN_CMD(cmd)`
外部输⼊,进⾏简单的拼接,最终放⼊⼀个执⾏外部命令的函数中去执⾏
但命令执⾏的函数,都⼀定存在这个rce吗? 如果不⼀定存在RCE,它们之间的差别是什么
目标系统被远程执行了未经授权的指令
⾸先做⼀个定义,由其他漏洞产⽣的外部代码(⾮预设代码)执⾏,不是我们这边所讲的 RCE
如果加上预设性代码 反序列化、远程⽂件包含、webshell上传、SSTI 也算RCE
我们平时说的rce,比如thinkPHP的rce漏洞,即算代码注入漏洞,也算rce漏洞,因为rce漏洞危害更大,优先级更高,所以直接叫rce漏洞了,如果你想利用thinkphp的rce漏洞去执行phpinfo,也是可以的,本质上就是文件包含漏洞(系统)造成代码注入,最后产生RCE的一个过程
如果一个漏洞只能造成代码注入,但没办法rce系统命令执行,这个时候我们才称之为代码注入漏洞
RCE与命令注入的 区别取决于执行的目标与权限
远程代码执行 ⽤户的输⼊被当做代码的⼀部分执⾏
远程命令执行 数据里面执行外部命令的函数没有被过滤
⼀般出现远程命令执行漏洞,是因为应⽤系统从设计上需要给⽤户提供指定的远程命令操作的接⼝。⽐ 如我们常⻅的路由器、防⽕墙、⼊侵检测(硬件设备、⼯业交付)等设备的web管理界⾯上。 仅当Web应⽤程序代码包含操作系统调⽤(外壳程序、shell)并且调⽤中使⽤了⽤户输⼊时, 才可能进⾏OS命令注⼊攻击。它们不是特定于语⾔的,命令注⼊漏洞可能会出现在所有让你 调⽤系统外壳命令的语⾔中:C,Java,PHP,Perl,Ruby,Python等。
PHP manual(开发手册) (seay代码审计工具 原理 正则表达式字符串匹配)
RCE主要是在操作系统上面执行代码,比如whoami (因为RCE涉及到对操作系统底层功能的控制,比如调试与分析)
命令注入主要是在应用程序上面执行相关代码,比如phpinfo (因为通过命令执行的函数可获取到相关信息方便程序与系统交互,但对用户提交的数据过滤不严格)
RCE与命令注入的 区别取决于执行的目标与权限
系统命令执行漏洞,当然是对操作系统进行控制和输出的
而代码注入漏洞,是对应用程序的相关代码进行注入,从而达到控制应用程序的目的
但有时候他们是交叉的 远程命令执行包含命令注入,命令注入也能RCE,需要调用应用程序的相关代码
$user_input = $_GET['input'];`
system('whoami ' . $user_input);`
如果用户能够控制 $_GET['input'] 的值 在系统上面执行任意指令 便算是通过命令注入来造成RCE,如果不是在系统上面执行 在应用程序上面执行 就只能算 命令注入
fd文件描述符 内核为了高效管理已经打开的文件所创建的索引
/proc/ 伪文件系统 所有进程相关的信息
$$liunx当前进程下的pid
反弹shell的原理 通过监听与目标建立socket后拿到shell通过伪终端与shell进行交互,将目标的命令通过socket连接导向本地,而又将结果输出给目标
bash -c
liunx的运行模式 两种形态 一种用户态 一种内核态 内核态 设置时间 liunx提供系统调用 syscall 用户态 通过syscall 软 内核态 系统 fork execve
(进程是资源分配的基本单位与程序独立运行的载体)
liunx权限 用户态(应用程序的运行模式)和内核态(操作系统内核的运行模式)
操作系统将运行模式分为了 用户态和内核态 他们中间通过系统调用syscall来进行交互,用户态可以通过syscall来对内核态发起调用系统特权指令的请求,而请求的结果内核态可以通过syscall返回给用户态,最大程度保障了操作系统的安全稳定(用户空间通过向内核空间发出Syscall,产生软中断,从而让程序陷入内核态,执行相应的操作)
系统调用 和 用户自定义函数一样 不同的是 系统调用运行在内核态 而用户自定义函数运行在用户态 由于某些指令(如设置时钟 关闭 打开 和I/O操作)只能运行在内核态 所以操作系统必须提供一种能够进入内核态的方式 系统调用便是这样的机制 他提供了用户态和内核态交互的接口
进程调用 fork(创建新的进程) execve (可以灵活的调用与管理进程)
系统调用fork是创建一个新的进程 与父进程共享资源但双方的进程任务互不影响,判断他们可以看返回值和uid。父进程返回子进程的ID 子进程返回0 ,而如果子进程被意外终结 可以等待父进程进行收回,如果不成功 则是僵死进程,但如果是父进程被终结,那么他的孤儿进程会被系统ID为1的进行收回
调查系统调用工具strace
比如:用户输入的是bash -c whoami 而内核态执行的是bash(pid:52350) --> sys_fork --> bash(pid:52796) --> sys_execve --> /bin/whoami(pid:52796)
liunx的进程设计到了很多东西 文件的创建 命令的调用,而进程又涉及到了权限的问题,权限分为用户态和内核态,所以大多数进程的调用与创建会和系统调用联合一起进行使用,从而提高系统的灵活稳定性
shell是用户与操作系统角色的接口 所以在操作进程的时候一般通过shell进行操作,直接走fork->execve流程导致RCE漏洞的原因是 大多数命令都是在通过shell来和操作系统内核进行交互的 所以fork新建一个shell进程 导致用户构造的语句被shell语法进行执行 所以产生了RCE的漏洞
RCE漏洞的原理是系统被执行了未经授权的恶意代码 但RCE漏洞执行是否成功主要是看当前的进程与函数是否会调用shell权限,如果当前的进程与函数会调用shell权限,走的fork->execve流程 会新建立一个shell进程 从而导致用户输入的数据被拼接 造成RCE漏洞,但如果走的是execve的流程,那将直接替换当前进程 加载新的程序到内存并执行,而不会单独开一个新的shell进程,也就不会使用户输入的数据被shell解释 导致RCE漏洞的产生
当我们不能执行任意进程时,意味着我们只能通过特定进程的输入来进行操作,而无法直接执行其他进程或进行其他操作。这种情况通常出现在受限的环境中,例如某些操作系统或应用程序中的沙箱环境、网络服务器的限制配置或权限受限的用户账户中。在这种情况下,我们只能使用当前进程所提供的接口、方法或命令来处理输入,并且不能直接调用其他进程或执行其他操作。我们需要依赖当前进程所提供的功能来处理输入并进行相应的操作。
当我们不能执⾏任意进程的时候(我们的输⼊只是某个特定进程的输⼊的时候),依然能找到 ⼀些撸点,但是撸点的⼤⼩,取决的使⽤的进程程序本身的参数是不是能注⼊
比如curl 文件读取
curl⽀持的协议可以看这⾥(https://www.cnblogs.com/zhanglianghhh/p/11326428.html)
比如 rpm 处理路由函数
当用户通过浏览器或其他 HTTP 客户端访问 /rpm
路径时,Flask 将调用 rpm_install
函数来处理这个请求。在 Flask 中,被装饰器 @app.route('/rpm')
修饰的函数(rpm_install
)即为处理对应路由的函数。
如果用户通过类似 http://yourdomain.com/rpm?rpm=package.rpm
的 URL 访问了 /rpm
路径,Flask 会调用 rpm_install
函数,然后通过 request.args.get("rpm")
获取到 URL 参数中的 rpm
值。接着,这个值会被用于执行相关的系统命令。造成RCE
php中⼤多数执⾏外部命令的函数,其实都是调⽤sh -c 去执⾏。
进程列表推荐
linux 看这个
windows 看这个