JSON 규칙을 통한 Java Bytecode Analyzer 사용자 정의 가능. 하나 이상의 JAR 또는 전쟁 파일을 포함하는 경로를 수신하고 제공된 규칙을 사용하여 분석하고 결과와 함께 HTML 보고서를 생성하는 명령 줄 도구입니다.
usage: java -jar cba-cli.jar [OPTIONS] -a DIRECTORY_TO_ANALYZE
-a,--analyze <pathToAnalyze> Path of the directory to run the
analysis.
-c,--checks <checks...> Space separated list of custom checks
that are going to be run in the analysis.
-f,--custom-file <customFile> Specify a file in JSON format to run
custom rules. Read more in
https://github.com/fergarrui/custom-bytecode-analyzer.
-h,--help Print this message.
-i,--items-report <maxItems> Max number of items per report. If the
number of issues found exceeds this
value, the report will be split into
different files. Useful if expecting too
many issues in the report. Default: 50.
-o,--output <outputDir> Directory to save the report. Warning -
if there are already saved reports in
this directory they will be overwritten.
Default is "report".
-v,--verbose-debug Increase verbosity to debug mode.
-vv,--verbose-trace Increase verbosity to trace mode - makes it slower, use it only when you need.
규칙 파일은 -f,--custom-file 인수를 사용하여 지정할 수 있습니다. 파일은 JSON 형식이며 다음 구조가 있습니다.
final 인 경우에만 지원됩니다. net.nandgr.cba.custom.model.Rules.java 확인하여 Java 코드의 구조를 확인할 수도 있습니다.
디렉토리 예제에는 이미 몇 가지 규칙이 있습니다. 어쨌든 아래는 모든 규칙에 대한 나열된 예입니다.
맞춤형 사막화로 수업을 찾아야한다면 아주 쉽게 할 수 있습니다. 클래스는 private void readObject(ObjectInputStream in) 구현하여 사용자 정의 사산화를 정의합니다. 따라서 해당 방법이 정의되는 모든 클래스 만 찾기 만하면됩니다. 규칙을 다음과 같이 정의하는 것만으로는 충분합니다.
{
"rules" : [{
"name" : " Custom deserialization " ,
"methods" : [{
"name" : " readObject " ,
"visibility" : " private " ,
"parameters" : [{
"type" : " java.io.ObjectInputStream "
}]
}]
}]
} private 가시성, readObject 이름 및 유형 java.io.ObjectOutputStream 의 매개 변수를 가진 메소드를보고합니다. 매개 변수는 배열이며 둘 이상이 지정되면 모두보고되도록 일치해야합니다. 하나의 규칙 만 가지고 있으므로 다음과 같은 보고서 : Custom-Deserialization-0.html이 작성됩니다.
이 경우 두 가지 방법이있는 한 가지 규칙을 정의해야합니다. 사막화에 대한 이전 예제와 동일하고 private void writeObject(ObjectOutputStream out) 일치하는 새로운 것. 위의 JSON 구조에서 볼 수 있듯이 속성 규칙 .rule.methods는 다양한 메소드이므로 이와 같은 규칙을 작성할 수 있습니다.
{
"rules" : [{
"name" : " Custom serialization and deserialization " ,
"methods" : [{
"name" : " readObject " ,
"visibility" : " private " ,
"parameters" : [{
"type" : " java.io.ObjectInputStream "
}]
},{
"name" : " writeObject " ,
"report" : " false " ,
"visibility" : " private " ,
"parameters" : [{
"type" : " java.io.ObjectOutputStream "
}]
}]
}]
} 동일한 규칙에 대해 두 번보고하지 않도록 속성 report False로 설정되었습니다. 우리는 두 번째 방법을 조건으로 사용하고 있지만,이 규칙의 목적으로 만 readObject 보고하는 데 충분해야합니다.
속성이 정의되지 않으면 항상 사실과 일치합니다. 예를 들어이 규칙은 모든 메소드 정의를 반환합니다.
{
"rules" : [{
"name" : " Method definitions " ,
"methods" : [{
}]
}]
}메소드 호출도 찾을 수 있습니다. 이 경우 JSON은 다음과 같습니다.
{
"rules" : [{
"name" : " String equals " ,
"invocations" : [{
"owner" : " java.lang.String " ,
"method" : {
"name" : " equals "
}
}]
}]
} 속성 owner 메소드가 포함 된 클래스를 지정합니다.
다른 방법 호출 예제 이전의 방법보다 조금 더 유용합니다.
{
"rules" : [{
"name" : " Method invocation by reflection " ,
"invocations" : [{
"owner" : " java.lang.reflect.Method " ,
"method" : {
"name" : " invoke "
}
}]
}]
} 메소드 호출과 동일하지만이 경우 메소드의 이름은 <init> 이어야합니다.
{
"rules" : [{
"name" : " String instantiation " ,
"invocations" : [{
"owner" : " java.lang.String " ,
"method" : {
"name" : " <init> "
}
}]
}]
}이 규칙은 다음의 발생을 찾을 것입니다.
[...]
String s = new String ( "foo" );
[...] 이 예에서는 사제화 사용법 (이전 예제에서와 같이 직렬화 동작을 정의하는 클래스가 아님)을 찾고자합니다. Desserialization은 ObjectInputStream.readObject() 호출 될 때 발생합니다. 예를 들어이 코드 스 니펫에서 :
ObjectInputStream in = new ObjectInputStream ( fileInputStream );
Object o = in . readObject (); 따라서 readObject 라는 ObjectInputStream 에서 메소드 호출을 찾아야합니다. 그러나 수업이 사용자 정의 사산화를 정의 할 때 private void readObject(ObjectInputStream in) 메소드 내 에서이 방법을 호출하고 보고서를 너무 오염시키기 때문에 연구 상황에서 많은 잘못된 양성을 발견 할 것입니다. 우리가 해당 사례를 제외하고 진정한 사제 만 유지하려면 재산을 사용 notFrom 수 있습니다.
{
"rules" : [{
"name" : " Deserialization usage " ,
"invocations" : [{
"owner" : " java.io.ObjectInputStream " ,
"method" : {
"name" : " readObject "
},
"notFrom" : {
"name" : " readObject " ,
"visibility" : " private "
}
}]
}]
} 이 파일에는 java.io.ObjectInputStream.readObject() 호출이 private void readObject(ObjectInputStream in) 메소드 내부에서 수행되지 않으면 호출을 찾을 수 있습니다.
이 코드로 편집 된 클래스는보고되지 않습니다.
private void readObject ( ObjectInputStream in ) throws IOException , ClassNotFoundException {
Object o = in . readObject ();
}그러나 이것은 다음과 같이보고 될 것입니다.
public Object deserializeObject ( ObjectInputStream in ) throws IOException , ClassNotFoundException {
Object o = in . readObject ();
return o ;
} from 속성은 notFrom 에서 정확히 같은 방식으로 호출에서 설정할 수 있지만 결과는 반대입니다. 이는 정의 된 메소드에서 호출이 이루어지는 경우에만 일치합니다.
이 경우 속성 superClass 사용할 수 있습니다. javax.servlet.http.HttpServlet 확장하는 모든 클래스를 찾으려면 다음과 같은 규칙이 될 수 있습니다.
{
"rules" : [{
"name" : " Java servlets " ,
"superClass" : " javax.servlet.http.HttpServlet "
}]
}
인터페이스 배열을 구현하는 클래스를 찾기 위해 규칙을 작성할 수 있습니다. 규칙에 둘 이상의 인터페이스가 정의되면 클래스는보고 할 모든 인터페이스를 구현해야합니다. javax.net.ssl.X509TrustManager 구현하는 클래스를 찾으려면 다음과 같습니다.
{
"rules" : [{
"name" : " X509TrustManager implementations " ,
"interfaces" : [ " javax.net.ssl.X509TrustManager " ]
}]
} interfaces 배열 이므로 정사각형 브래킷 사이에 문자열을 추가하십시오 : ["interface1", "interface2", ...] .
주석도 지원됩니다. 다중 주석 속성은 방법 O 변수 (매개 변수 또는 로컬 변수)에서 규칙 (클래스 주석 찾기)에서 정의 할 수 있습니다. 그들 모두가 분석 된 클래스에서 발견되면보고 될 것입니다. 예를 들어, 스프링 엔드 포인트를 찾으려면 org.springframework.web.bind.annotation.RequestMapping 으로 주석이 달린 클래스 또는 메소드를 검색합니다. 따라서 규칙은 다음과 같습니다.
{
"rules" : [{
"name" : " Spring endpoint - class annotation " ,
"annotations" : [{
"type" : " org.springframework.web.bind.annotation.RequestMapping "
}]
},
{
"name" : " Spring endpoint - method annotation " ,
"methods" : [{
"annotations" : [{
"type" : " org.springframework.web.bind.annotation.RequestMapping "
}]
}]
}]
} 속성 rule.fields 필드는 클래스 필드를 찾는 데 사용될 수 있습니다. 비밀번호 이름이있는 개인 문자열 필드를 찾으려면 이와 같은 규칙을 사용할 수 있습니다.
{
"rules" : [{
"name" : " Password fields " ,
"fields" : [
{
"visibility" : " private " ,
"type" : " java.lang.String " ,
"nameRegex" : " (password|pass|psswd|passwd) "
}
]
}]
} 변수를 찾으려면 rule.variables 사용할 수 있습니다. 이 속성은 로컬 변수 및 메소드 인수 변수를보고합니다. javax.servlet.http.Part 유형의 모든 변수를 찾으려면 다음과 같습니다.
{
"rules" : [{
"name" : " Servlet upload file " ,
"methods" : [{
"variables" : [{
"type" : " javax.servlet.http.Part "
}]
}]
}]
}동일한 JSON 파일로 여러 규칙을 정의 할 수 있습니다. 그들은 개별적으로 처리되고보고 될 것이며 서로 영향을 미치지 않을 것입니다. 이전 예제 규칙을 결합 할 수 있습니다.
{
"rules" : [{
"name" : " Custom deserialization " ,
"methods" : [{
"name" : " readObject " ,
"visibility" : " private " ,
"parameters" : [{
"type" : " java.io.ObjectInputStream "
}]
}]
},{
"name" : " Method invocation by reflection " ,
"invocations" : [{
"owner" : " java.lang.reflect.Method " ,
"method" : {
"name" : " invoke "
}
}]
}]
}여기에는 두 가지 규칙이 있습니다 ( "사용자 정의 사제화"및 "반사에 의한 메소드 호출"). 두 개의 분리 된 처형에서 그렇게하는 것처럼 처리됩니다. 규칙 당 보고서가 생성됩니다. 규칙에 동일한 이름이 있으면 같은 파일에보고됩니다.
이 프로젝트는 JSON 형식으로 다루지 않는 Java 코드로 더 복잡한 사용자 정의 규칙을 추가하기 위해 다운로드 및 구축 할 수 있습니다. 패키지 net.nandgr.cba.visitor.checks 에는 이미 세 가지 예가 있습니다. 그것들은 CustomDeserializationCheck, DeserializationCheck and InvokeMethodCheck 입니다. net.nandgr.cba.custom.visitor.base.CustomAbstractClassVisitor 를 확장하여 고유 한 규칙을 만들 수 있습니다.
위에서 언급했듯이 보고서는 기본적으로 report Folder에서 작성됩니다. 모든 규칙에는 이름이 같은 경우 별도의 파일이 있습니다. 보고서가 너무 커지면 -i,--items-report <maxItems> 매개 변수를 사용하여 분할 할 수 있습니다. 각각은 인수를 지정하거나 적게 보유합니다 (마지막 인 경우). 보고 된 모든 항목은 발견 된 위치, 클래스 이름 및 메소드 이름 (관련된 경우)을 지정합니다. 또한 빠른 시각적 검사를 용이하게하기 위해 클래스의 디 컴파일 버전을 보여줍니다. java.io.File 인스턴스화를 찾기위한 규칙에 대한 항목이 어떻게 표시되는지에 대한 예 :

보안 버그를 검색 할 때는 통화 그래프를 갖는 것이 매우 유용합니다. 현재, 간단한 도트 호환 파일이 report 디렉토리 아래에서 생성됩니다. 그래프에는 발견 된 문제를 호출 할 수있는 모든 흐름이 포함되어 있습니다. 예를 들어, 사막화를 찾는 규칙이 사용되는 경우, 사막화를 호출하는 방법으로 이어지는 모든 가능한 경로를 포함하는 그래프가 생성됩니다.
파일은 call-graph.dot 이며 다음과 같습니다 (이것은 매우 간단한 예입니다).
graph callGraph {
"demo.callgraph.Class1:method1" -- "demo.callgraph.Class2:method2"
"demo.callgraph.Class3:method3" -- "demo.callgraph.Class2:method2"
}
시각적으로 표시하기 위해 DOT 사용할 수 있습니다 (또는 호환 가능한 소프트웨어). 예를 들어 파일을 svg 로 변환합니다.
dot -Tsvg call-graph.dot -o call-graph.svg
시스템 경로에서 DOT가 발견되면 기본적으로 자동으로 수행됩니다. 그렇지 않은 경우 sudo apt-get install graphviz 사용하여 Debian 기반 시스템에 DOT 설치할 수 있습니다.
inkscape 또는 Just firefox 와 같은 프로그램을 사용하여 PNG로 변환하거나 시각화 할 수있는 call-graph.svg 라는 SVG 파일을 만듭니다.
위 파일의 매우 간단한 예는 다음과 같습니다.

예를 들어 검색 된 항목이 java.lang.Runnable.run() 또는 이와 유사한 메소드에있는 경우와 같은 몇 가지 제한 사항이 있습니다. 스레드가 실행되는 위치를 찾지 못합니다. 또한, 그래프는 StackOverflowError s를 피하기 위해주기를 청소하고, 약간의 보수적 인 방식으로 만들어 지므로 큰 디렉토리 분석 중에 시스템의 기억이 소진되지 않습니다.
향후 버전에는 더 많은 옵션이 추가됩니다.
java -jar cba-cli-<version>.jar -a /path/with/jars -f /path/with/json/file/rules.json
사용자 정의 Java 규칙을 사용하려면 클래스 이름을 -c 의 인수로 지정해야합니다.
java -jar cba-cli-<version>.jar -a /path/with/jars -c DeserializationCheck
공간 분리 된 목록을 허용하므로 여러 사용자 정의 규칙을 정의 할 수 있습니다 (각 규칙은 별도의 보고서를 만듭니다).
java -jar cba-cli-<version>.jar -a /path/with/jars -c DeserializationCheck InvokeMethodCheck CustomDeserializationCheck YourCustomRule
java -jar cba-cli-<version>.jar -a /path/with/jars -f /path/with/json/file/rules.json -c YourCustomRule1 YourCustomRule2
오류를 찾으려면 말도를 높일 수 있습니다. 디버그 레벨 :
java -jar cba-cli-<version>.jar -a /path/with/jars -c YourCustomRule1 -v
추적 레벨 :
java -jar cba-cli-<version>.jar -a /path/with/jars -c YourCustomRule1 -vv
현재 APK는 먼저 JAR로 변환되어 분석되어야합니다.
d2j-dex2jar.sh -f -o app_to_analyze.jar app_to_analyze.apk-a 매개 변수로 전환 된 JAR 파일을 포함하는 디렉토리로 실행하십시오. bin 수정을하거나 사용자 정의 규칙을 추가하려면 프로젝트를 구축 할 수 있습니다.
git clone https://github.com/fergarrui/custom-bytecode-analyzer.git
cd custom-bytecode-analyzer
mvn clean package
target 폴더에서 두 개의 항아리가 생성됩니다. cba-cli-<version>.jar 에는 모든 종속성이 포함되어 있으며 실행 가능합니다. java -jar cba-cli-<version>.jar 사용하여 실행할 수 있습니다