php post 漏洞_AWD攻防赛之各类漏洞FIX方案

4bdb1fa75b2897342a016bfff8da9f3a.gif

0×01 Introduction

1、CTF中的线下赛又被称为AWD(Attack With Defence)。AWD对于选手的攻击能力,防御能力以及团队合作能力都有着很高的考验。比赛中有多支队伍,每个队伍维护多台服务器,服务器中存在多个漏洞,利用漏洞攻击其他队伍的服务器可以进行得分,修补漏洞可以避免被其他队伍攻击失分。

2、WEB安全中常见漏洞包括SQL注入、反序列化、文件上传、文件包含、代码执行、XXE、XXS、CSRF等。大家熟知的AWD攻防赛中常常是把某几个漏洞点结合起来进行考察。在AWD赛制中,攻与防是相对的,针对服务器上不同漏洞所采用的修补方案也不一样。

3、在这里我会将自己的经验分享给大家 —- 即将退役的CTF选手。

0×02 Sql Injection

1、常见的SQL注入漏洞主要是由于程序开发过程中不注意规范书写Sql语句以及对特殊字符的不严格过滤,从而导致客户端可以通过全局变量POST和GET提交恶意代码。

2、Fix:基于黑名单、转义、报错

黑名单

SQL Filter

load|

转义

php.ini

magic_quotes_gpc=

magic_quotes_gpc 函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”{单引号(’)、双引号(”)与 NULL(NULL 字符)等字符都会被加上反斜线。},以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。

addslashes() 函数

addslashes(string)

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是:单引号(')双引号(")反斜杠(\)NULL

PS:PHP 5.4 之前 PHP 指令 magic_quotes_gpc 默认是 on, 实际上所有的 GET、POST 和 COOKIE 数据都用被 addslashes() 了。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。

报错

控制错误信息

php代码开头添加语句:error_reporting(0);

0×03 Unserialize

PHP

PHP7 新特性 为 unserialize() 提供过滤

这个特性旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入。

<?php // 将所有的对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => false]);// 将除 MyClass 和 MyClass2 之外的所有对象都转换为 __PHP_Incomplete_Class 对象
$data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]);// 默认情况下所有的类都是可接受的,等同于省略第二个参数
$data = unserialize($foo, ["allowed_classes" => true]);?>

限制 Session 反序列化

php_serialize 在5.5版本后新加的一种规则,5.4及之前版本,如果设置成php_serialize会报错。

正确设置序列化及反序列化时使用的处理器

ini_set(‘session.serialize_handler’, ‘php_serialize’);
ini_set(‘session.serialize_handler’, ‘php’);

两者处理session的方式不同,错误使用会形成基于session的反序化漏洞

限制 phar 拓展 php 反序列化

"phar|zip|compress.bzip2|compress.zlib";

PS:如果不将 compress.bzip2 伪协议进行过滤,有时候漏洞代码仅将phar过滤,但是可以被 compress.bzip2 绕过。

下面举一个具有漏洞代码的栗子

<?php 
error_reporting(0);
highlight_file("file_contrary.php");
$filename=$_GET['filename'];if (preg_match("/\bphar\b/A", $filename)) {echo "stop hacking!\n";
}else {class comrare{public $haha = 'xxxx';function __wakeup(){eval($this->haha);
}
}
imagecreatefromjpeg($_GET['filename']);
}?>
compress.bzip2 绕过
payload:file_contrary.php?filename=compress.bzip2://phar://upload_file/shell.gif.gif/a

配置php.ini禁用特殊函数

特殊函数主要是基于魔法函数、phar拓展php利用函数、序列函数。

disable_

JAVA

类的白名单校验机制

对所有传入的反序列化对象,在反序列化过程开始前,对类型名称做一个检查,不符合白名单的类不进行反序列化操作。

禁止 JVM 执行外部命令 Runtime.exec

Java 一般来说安全性问题较少,出现的一些问题大部分是利用反射,最终用Runtime.exec(String cmd)函数来执行外部命令的。

SecurityManager originalSecurityManager = System.getSecurityManager();
if (originalSecurityManager == null) {
// 创建自己的SecurityManager
SecurityManager sm = new SecurityManager() {
private void check(Permission perm) {
// 禁止exec
if (perm instanceof java.io.FilePermission) {
String actions = perm.getActions();
if (actions != null && actions.contains("execute")) {
throw new SecurityException("execute denied!");
}
}
// 禁止设置新的SecurityManager,保护自己
if (perm instanceof java.lang.RuntimePermission) {
String name = perm.getName();
if (name != null && name.contains("setSecurityManager")) {
throw new SecurityException("System.setSecurityManager denied!");
}
}
}

@Override
public void checkPermission(Permission perm) {
check(perm);
}

@Override
public void checkPermission(Permission perm, Object context) {
check(perm);
}
};

System.setSecurityManager(sm);
}

0×04 File Upload

Upload Limit

后端代码限制上传的文件类型(类型&后缀)和大小

_FILES["Up10defile"]["type"]=="image/gif")&&(substr($_FILES[

强制给上传的文件添加后缀名

在不存在文件包含漏洞的情况下,该方法能最有效的防御攻击

者上传执行木马

if (file_exists(

0×05 File Include

LFI

本地路径包含限制

'filename'];

RFI

远程路径包含限制

'filename'];

限制环境

allow_url_fopen = 

php 伪协议

协议过滤 & 路径访问限制

'filename'];

0×06 Arbitrary File Reading

Defense

常见文件读取函数

source()、file()

读取限制

基于目录 & 伪协议

<?php 
$filename = $_GET['filename'];
$pattern = "\/|\.\.\/|\.\/|etc|var|file|http|ftp|php|zlib|data|glob|phar|ssh2|rar|ogg|expect|zip|compress|filter|input";if(preg_match("/".$pattern."/is",$filename)== 1){echo "die00000000000000000000000000000";die();
}echo file_get_contents($filename);?>

open_basedir

限定文件访问范围

open_basedir=

0×07 Code (Command) Execution

Cause

# 代码执行函数

Defense

PHP7 新特性

preg_replace() 函数不再支持 “\e” (PREG_REPLACE_EVAL). 应当使用 preg_replace_callback() 替代。

preg_replace()

修补 preg_replace() 漏洞需要将修饰符/e去掉

漏洞代码

<?php 
preg_replace("/ \[(.*)\]/e",'strtolower("\\1")',$_GET['str']);?>

调用函数过滤不严

call_user_func()和array_map()等函数具有调用其他函数的功能,多用在框架里面动态调用函数,所以比较小的程序出现这种方式的代码执行会比较少用call_user_func()函数来举例,函数的作用是调用第一个参数(函数),将第二个参数作为要调用的函数的参数call_user_func ( callable $callback [, mixed $parameter [, mixed $… ]] )

修补 call_user_func() 和 array_map() 等函数漏洞需要将其调用函数的参数进行严格过滤

漏洞代码

<?php 
$a=$_GET['a'];
$b="phpinfo()";
call_user_func($a,$b);?>
payload:a=assert

调用函数参数过滤

<?php 
$a=$_GET['cc'];
$pattern = "eval|assert|passthru|pcntl_exec|exec|system|escapeshellcmd|popen|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|ob_start";if(preg_match("/".$pattern."/is",$cc)== 1){die();
}
$bb="phpinfo()";
call_user_func($cc,$bb);?>

禁用或过滤代码执行函数

disable_
'db'];

0×08 XSS

Defense

XSS 防御基本都是对用户输入以及客户端显示进行过滤转义

HttpOnly 的使用

HttpOnly 最早是由微软提出,并在 IE6 中实现的,至今已经逐渐成为一个标准。浏览器将禁止页面的Javascript访问带有HttpOnly属性的Cookie。

HttpOnly 主要是为了解决XSS中的Cookie劫持攻击。

htmlspecialchars() 转义函数

<?php if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL )
{
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
$name = htmlspecialchars( $_GET[ 'name' ] );echo "
Hello ${name}"
;
}?>

使用htmlspecialchars函数把预定义的字符 &、”"、’、、/ 转换为 HTML 实体,防止浏览器将其作为HTML元素。

 & --> &
< --> >
> --> <
" --> "
' --> &#x27;
/ --> &#x2F;

它的语法如下:

string,flags,character-

使用htmlspecialchars函数,解决了XSS,但是要注意的是,如果htmlspecialchars函数使用不当,攻击者就可以通过编码的方式绕过函数进行XSS注入,尤其是DOM型的XSS。

JavaScript 编码

JavascriptEncode 与 HtmlEncode 的编码方式不同,它需要使用(\)对特殊字符进行转义。

PS:在对不可信数据做编码的时候,不能图方便使用反斜杠\ 对特殊字符进行简单转义,比如将双引号 ”转义成 \”,这样做是不可靠的,因为浏览器在对页面做解析的时候,会先进行HTML解析,然后才是JavaScript解析,所以双引号很可能会被当做HTML字符进行HTML解析,这时双引号就可以突破代码的值部分,使得攻击者可以继续进行XSS攻击;另外,输出的变量的时候,变量值必须在引号内部,避免安全问题;更加严格的方式,对除了数字和字母以外的所有字符,使用十六进制\xhh 的方式进行编码。

0×09 CSRF

Defense

验证 HTTP Referer 字段

在请求地址中添加 Token 并验证

在 HTTP 头中自定义属性并验证

0×10 XXE

Defense:使用开发语言提供的禁用外部实体的方法

PHP

disable_entity_loader(

JAVA

 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

dbf.setExpandEntityReferences(false);

Python  

过滤用户提交的XML数据

PUBLIC

不管是在经验方面还是在其他方面,在这个领域中都收获挺多的。特别是在这个过程中非常感谢一直陪伴我的团队。

53b7fe20dcb781233718723763cfbc36.gif

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值