Keirsgieter, W. y Visser, W. (2020). Injerto: análisis estático del bytecodo Java con bases de datos de gráficos. Conferencia del Instituto Sudáfrica de Científicos y Tecnólogos de la Información 2020.
El injerto es una herramienta de análisis estático para programas Java, basada en la teoría de los gráficos de propiedades de código (CPGS).
El CPG se genera a partir de Java Bytecode y se almacena en una base de datos de gráficos local. El gráfico se puede atravesar para encontrar varias vulnerabilidades de seguridad comunes, incluidas las vulnerabilidades relacionadas con la contaminación.
También se proporciona un shell de línea de comando que permite al usuario realizar transversales ad-hoc en el CPG de manera interactiva.
Puede usar este proyecto para fines de investigación, pero recuerde citarnos.
@article{Keirsgieter2020GraftSA,
title={Graft: Static Analysis of Java Bytecode with Graph Databases},
author={Wim Keirsgieter and Willem Visser},
journal={Conference of the South African Institute of Computer Scientists and Information Technologists 2020},
year={2020}
}
Graft es un proyecto de Gradle, y se puede construir simplemente ejecutando gradle build (o ./gradlew build ).
Durante la compilación, se generan dos scripts ejecutables: graft y graft-shell . Todas las referencias al graft en la sección de uso se refieren al ejecutable graft . graft-shell abre una cáscara maravillosa en la clase de injerto (ver la sección de graft-shell en uso).
El injerto debe inicializarse dentro del proyecto ejecutando graft init antes de que el CPG pueda ser construido y analizado.
graft init Este comando inicializa el proyecto de injerto creando una carpeta .graft en el directorio raíz del proyecto. Esta carpeta contiene un archivo de propiedades con la configuración del proyecto y una carpeta db que almacena la base de datos de gráficos.
El usuario proporciona un nombre para el proyecto, el directorio de destino del proyecto (donde se encuentran las clases de Java) y classpath, y selecciona la implementación de la base de datos de gráficos.
Después de la inicialización, la base de datos contiene solo un nodo raíz: el CPG se puede construir con graft build .
graft buildEste comando realiza la construcción inicial del CPG. Si la base de datos ya contiene un CPG, el usuario tiene la opción de sobrescribirla.
La construcción del CPG lleva algo de tiempo, y debe ejecutarse solo una vez después de ejecutar graft init por primera vez. Si el programa ha cambiado y el CPG debe actualizarse, el usuario debe ejecutar graft update .
graft statusImprima el estado del CpG - número de nodos y bordes, así como las clases cambiadas desde la última actualización.
graft updateEste comando verifica los cambios en el programa de destino que aún no se reflejan en el CPG al comparar los valores hash de los archivos de clase. Si se han cambiado algunas clases, se actualizarán en el CPG sin afectar el resto del gráfico.
Este procedimiento es mucho más rápido que reconstruir el gráfico completo cada vez, y probablemente debería ejecutarse después de cada cambio incremental en el programa.
graft run <analysis> Este comando se puede usar para ejecutar un análisis predefinido en el gráfico. Se incorporan dos análisis de este tipo ( TaintAnalysis y AliasAnalysis ) y se pueden ejecutar con alias de graft run taint graft run alias respectivamente.
graft dot <dotfile>Este comando imprime el CPG en el archivo dado en formato DOT para la visualización. No se recomienda nada que no sean programas trivialmente pequeños (este comando es más útil para la depuración realmente).
graft dump <dumpfile>Este comando arroja el CPG al archivo dado para la portabilidad. Nuevamente no se recomienda para gráficos más grandes.
graft-shellEste comando abre la carcasa del injerto. Desde aquí, el usuario puede inspeccionar interactivamente el CPG y ejecutar los recorridos en él.
Ejemplo de flujo de trabajo:
import graft . cpg . structure . CodePropertyGraph
import static graft . traversal . __ .*
import static graft . Const .*
cpg = CodePropertyGraph . fromFile ( '<db_filename>' )
// get a list of all method entry nodes in the CPG
entries = cpg . traversal (). entries (). toList ()
// get a list of all assignments to the variable 'x'
assigns = cpg . traversal (). getAssignStmts (). where ( getTgt (). has ( NAME , 'x' )). toList ()
// dump the current CPG to a file
cpg . dump ( '<filename>' )
// write the current CPG to a dotfile
cpg . toDot ( '<filename>' )