不敢想象学会Syntax-flow的人能有多快乐
2024-10-18 01:30:0 Author: mp.weixin.qq.com(查看原文) 阅读量:2 收藏

syntax-flow zero to hero中,已经介绍了一部分syntax-flow 语法的编写规则以及关于基础的一些使用,比如#->#>-->等,当然,在之前的公众号中也介绍了一部分config的使用。

https://github.com/yaklang/syntaxflow

g4部分片段如下,在syntax-flow中,支持以多种方式来进行开头,其中,可以指定.开头,指定变量名开头,指定nativeCall开头,支持常量搜索。
filterItemFirst    : constSearchPrefix?(QuotedStringLiteral|hereDoc) # ConstFilter    | nameFilter                                      # NamedFilter    | '.' lines? nameFilter                           # FieldCallFilter    | nativeCall                                      # NativeCallFilter    ....    ....

filterItem : filterItemFirst # First | '...' lines? nameFilter # DeepChainFilter | '(' lines? actualParam? ')' # FunctionCallFilter | '[' sliceCallItem ']' # FieldIndexFilter | '?{' conditionExpression '}' # OptionalFilter | '->' # NextFilter | '#>' # DefFilter | '-->' # DeepNextFilter | '-{' (config)? '}->' # DeepNextConfigFilter | '#->' # TopDefFilter | '#{' (config)? '}->' # TopDefConfigFilter | '+' refVariable # MergeRefFilter | '-' refVariable # RemoveRefFilter | '&' refVariable # IntersectionRefFilter .... ....
在之前的syntax-flow中,学习到了#->是来进行搜索顶级定义的。那么,可以在之前的基础上进行一些横向拓展,在eval的过程中,我们可能会遇到匹配函数,或者匹配字段等问题。

过滤条件:

conditionExpression    : '(' conditionExpression ')'                                                # ParenCondition    | filterExpr                                                                 # FilterCondition        // filter dot(.)Member and fields    |  Opcode ':' opcodesCondition (',' opcodesCondition) * ','?                      # OpcodeTypeCondition    // something like .(call, phi)    |  Have  ':' stringLiteralWithoutStarGroup       # StringContainHaveCondition // something like .(have: 'a', 'b')    |  HaveAny ':' stringLiteralWithoutStarGroup       # StringContainAnyCondition // something like .(have: 'a', 'b')    | negativeCondition conditionExpression                                                    # NotCondition    | op = (        '>' | '<' | '=' | '==' | '>='         | '<=' | '!='        ) (            numberLiteral | identifier | boolLiteral        ) # FilterExpressionCompare    | op = ( '=~' | '!~') (stringLiteral | regexpLiteral) # FilterExpressionRegexpMatch    | conditionExpression '&&' conditionExpression      # FilterExpressionAnd    | conditionExpression '||' conditionExpression      # FilterExpressionOr    ....
过滤条件通常是在变量中进行,用?{}来进行过滤。
have: 全部包含某个值,可以用,来进行分割。比如 ?{have: a,b}any: 包含某一个值,?{any: a,b}opcode: 过滤某些指令的类型为call或者const。比如?{opcode: call}!: 对过滤条件进行取反多条件过滤:?{opcode: call && have: filter}

案例1:

<?php
$b = new A();$a = $b->autoload()->bb($dd);$c = $b->cc($dd);
//sf
.autoload?{<getObject>?{have: b}} as $vuln

相交运算 & :

在向上寻找的过程中,可能希望某些函数是否参数可控,路径上是否经过某个点,就可以使用&语法来做。如案例2:在寻找exec参数顶级定义和$_GET超全局变量进行相交的点。

案例2:

<?php
$a = $_GET[1];$b = str_replace($a);$c = handler($b);exec($c);
//
_GET.* as $param;exec(* #{until: `* & $param`}-> as $sink)

常量搜索:

在上面的g4中,可以看到是支持常量搜索,常量搜索常常以模式来进行开头。支持stringheredoc进行衔接。适用于在代码中进行硬编码,想要快速匹配代码中的内容,比如,ip地址,密码等常见内容。
常量搜索支持,rge三种匹配模式,分别为正则匹配通配符匹配精确匹配。支持:
r"" 
r<<<CODE
CODE

案例3:

搜索Ip地址
这是IP地址的一个正则通配,当在代码中写死一个IP地址的时候,可以通过正则来进行IP地址的搜索。比如。
r"^((0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])$"

r<<<CODE^((0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])$CODE

常用的nativeCall详解:

syntax-flow中,还适配了一些"内置方法",这里去简单的介绍一些nativeCall的使用,方便syntax-flow的编写。
通用:
  • <getCaller>:获取值中是函数调用的值。
<?php$b = $_GET[a];if($c){$b = filter($b);}eval($b);
/*
//这里会hook到eval参数在向上寻找顶级定义中的所有值存到$infoeval(* #{hook: `* as $info`}->)

//然后将$info中所有是call的存入到$param$info<getCaller> as $param
*/
  • <name>:获取名称
  • <slice>:获取第几位之后的变量,从0开始,一般常用于函数调用获取参数。
注意⚠️:该内置方法只是获取到之后的所有变量,并不是固定到某个变量,如果需要指定获取某个变量可以通过f(,,* as $param)来进行获取(此次例子f(,,* as $param)获取的是第三个参数)
f(*<slice(start=1)> as $query) //获取第二个参数及其之后的所有变量
obj相关:
  • <getObject>
在数据流分析过程中,可能提前确定了一个obj中有"操作空间",可以尝试从所有的sink点开始反推,反推到obj为某个类。
比如:
<?phpclass A{    public $a;    public $b;    public function getA(){       return $this->a;    }}$a = new A();eval($a->a);
//.a<getObject><name>?{have: A} as $param
  • <getMembers>
获取一个类中,所有的成员。
<?phpclass A{    public $a;    public $b;    public function getA(){       return $this->a;    }}//A<getMembers> as $param
  • <fullTypeName>
获取一个类的全类名。
package com.example.demo1;
import java.io.File;import java.io.IOException;
import java.io.FileOutputStream;
class A { public int a = 0;
public static void test() throws IOException { FileOutputStream fileOutputStream = new FileOutputStream(new File("xxx.xx")); }}
//fileOutputStream<fullTypeName>?{have: FileoutputStream} as $param
在syntax-flow中,大部分还是关于rule规则的编写,但其实还有多个部分,比如descalertcheck等多个部分。等到后续开放导入自定义规则后,再进行详细讲解。
END

  YAK官方资源 

Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit

https://github.com/yaklang/yaklang

Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ


文章来源: https://mp.weixin.qq.com/s?__biz=Mzk0MTM4NzIxMQ==&mid=2247522950&idx=1&sn=614d62895c561759f0290122867d1ff9&chksm=c2d1e622f5a66f34a628cd2e717a7f9b7cae239044ab6285cc3fee4e27d9c0f680131048ff8b&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh