初始代码审计

初始代码审计

一、安全的本质

  1. 安全的本质就是信任
  2. 信任导致的安全问题
    • 是否该信任普通用户的输入—>前台漏洞
    • 是否该信任管理员用户的输入—>后台漏洞
    • 是否该信任升级包、离线升级、在线升级、自动化升级—>供应链攻击
    • 不信任任何输入—>对输入进行检测
  3. 实际上就是把信任关系绑定到了对输入检测逻辑上,一旦输入检测逻辑出现了问题,信任关系就被打破,就出现了漏洞

二、安全问题模型化

  1. 将复杂的安全问题抽象成简单的模型,整体的流程就是输入—>检测是否有安全风险—>输出

  2. 举例

    输入检测输出
    NDR(网络检测与响应)流量、pcap包等waf、正则、流量解析、文件分析、威胁情报等等正常流量无动作,恶意流量阻断
    EDR(终端检测与响应)进程事件、文件事件、主机API调用父子进程关系异常、非常规API调用、敏感文件读取异常阻断杀死进程
    WAF(web应用防火墙)api调用是否包含xss、sql注入等关键字(包括AI检测)中断该次异常连接
    WEBSHELL查杀文本文件含恶意关键字、数据进入敏感函数隔离、删除
  3. 我们能掌控的只有输入,挖掘漏洞最好的入口点,也是也只能从输入去入手,结合不同语言的特点,跟踪传播链条是否有漏洞

三、控制和数据

  1. 我们要搞清楚程序希望用户输入什么

  2. 我们将程序员的代码分割为两个部分

    <html>
    <script>
    	console.log("my name is :" + "<?php echo $_GET['glc'];?>")
    </script>
    </html>
    
    对于内部php语言来说,glc为数据流,echo $_GET['glc']为控制流
    对于外部的JS语言my name is :" + "<?php echo $_GET['glc'];?>是数据流,console.log为控制
    
    • 一部分是控制代码走向的控制流代码
    • 一部分是用来被展示、被存储、被流转的数据流(包括输入数据,和程序员本来就硬编码的数据)

    由此可得程序员希望用户输入的一定是数据流,而不是控制流

  3. 所以一旦我们输入的数据能够以某种方式侵入到控制流时,漏洞就产生了

四、简单分析漏洞产生原因

1.SQL注入
<?php
	$db = init_db();
	$username = $_GET['username'];     //input: glc' and 1=1#
	$db->query("select * from table where username = '$glc'");
?>
  • 输入流转:输入—>php字符串变量—>sql语句—>数据库

  • 其实这里与php语言无关了,编程语言只是我们用来表述这件事情的,我们要考虑的是数据库层面。在数据库层面控制流是sql语句,整个控制流程程序员的原意是这样的

    action(动作): select
    object(对象): table
    subject(目标客体): *
    condition(条件):
    	key: username
    	value: $glc   // 用户输入
    

    在这里程序员应该通过编程保证用户的输入只能影响结构中的value位置。如果不能保障,就会出现漏洞

    action(动作): select
    object(对象): table
    subject(目标客体): *
    condition(条件):
    expression: and(逻辑与)
    	key1: username
    	value1: $glc // 用户输入 glc
    	key2: 1
    	value2: 1
    
  • 我们在代码层(php)的输入,导致了数据库(mysql)层的数据流入侵到了控制流

2.SSTI
  • 服务端模板注入(Server-Side Template Injection)也可以用相同的方式来理解
  • Twig是php的一套模板渲染的组件,但是不规范的渲染参数输入方式,可能导致模板注入
<?php
	require_once dirname(__FILE__).'\twig\lib\Twig\Autoloader.php';
	Twig_Autoloader::register(true);
	$twig = new Twig_Environment(new Twig_Loader_String());
	$output = $twig->render("Hello {{name}}", array("name" => $_GET["glc"])); // 将用户输入作为模版变量的值
	echo $output;
?>
  • 输入流转:输入—>php字符串变量$_GET[“glc”]—>Twig模板渲染—>发现变量{{name}}—>找到变量name的绑定—>解析字符串—>渲染展示

  • 错误的写法

    <?php
    	require_once dirname(__FILE__).'/../lib/Twig/Autoloader.php';
    	Twig_Autoloader::register(true);
    	$twig=newTwig_Environment(newTwig_Loader_String());
    	$output=$twig->render("Hello {$_GET['glc']}");// 将用户输入作为模版内容的一部分
    	echo $output;
    ?>
    
  • 输入流转:输入—>php字符串变量KaTeX parse error: Expected '}', got 'EOF' at end of input: …—>拼接字符串"Hello {GET[‘name’]}"作为新变量—>Twig模板渲染—>渲染展示

  • 我们在代码层(php)的输入,导致了Twig模板层的数据流入侵到了控制流

3.命令执行
<?php
	$domain = $_GET["domain"]; //input:baidu.com";whoami
	echo system('ping "'.$domain.'"');
?>
  • 程序员的原意,在bash程序中

    execute:
    	process:
    		exe: tracert —> /bin/tracert
    		arg: $domain
    
  • 在这里程序员应该通过编程保证用户的输入只能影响结构中的arg位置。如果不能保障,就会出现漏洞

    ping "baidu.com";whoami
    	execute:
    		process1:
    			exe: tracert
    			arg: "baidu.com"
    		or —>
    		process2:
    			exe: whoami
    			arg: -
    
  • 我们在代码层(php)的输入,导致了bash程序层的数据流入侵到了控制流

4.业务流程问题
  • 很多逻辑漏洞、越权漏洞,往往来自于此。也是现代mvc结构会出现的比较多的问题

  • 过度信任用户输入

    <?php
    	$user_id = int($_GET['user_id']);
    	$db = init_db();
    	$data = $db->query("select * from user where user_id = $user_id");
    	echo parse_user_profile($data);
    ?>
    

    这是一个典型的越权读取原型了,在业务逻辑上的校验有缺陷,信任了用户输入的user_id,导致漏洞的产生

  • 不信任用户输入但是信任检测逻辑

    //login.php?password=test&user_id=123
    <?php
    	session_start();
    	$password = "test";
    	$_SESSION['is_login'] = 0;
    	if ($_GET['password'] == $password){
    		$_SESSION['is_login'] = 1;
    		$_SESSION['user_id'] = $_GET["user_id"]; // 假定管理员user_id=0
    		header("location: /user.php?is_login=1");
    		exit();
    	}else{
    		echo "密码错误";
    		exit();
    	}
    ?>
    
    //user.php
    <?php
    	header("content-type: text/html; charset=utf-8");
    	if ($_SESSION['is_login'] == $_GET['is_login']){    //NULL == NULL
    		echo "你登录了";
    		if ($_SESSION['user_id'] == 0){    //NULL == 0
    			echo "你是管理员";
    		}else{
    			echo "你不是管理员,付钱";
    			}
    		}else{
    		echo "没登陆";
    	}
    ?>
    

    可以看到整个流程里面,开发者完全没有信任用户的输入,对密码进行了校验,校验通过才存session,并且用户id也是存储于session中的,没法通过cookie伪造绕过鉴权。实际上就是把信任关系绑定到了对输入检测逻辑上,一旦输入检测逻辑出现了问题,信任关系就被打破,就出现了漏洞

  • php是弱类型的语言,在php下,NULL == false == 0 == “”;而$_SESSION的取值来自于cookie中PHPSESSION的输入,如果我们不输入cookie,这里就完全绕过这个校验

  • 业务流程检测逻辑不规范导致漏洞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果粒程1122

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值