diff --git a/sarif/Makefile b/sarif/Makefile deleted file mode 100644 index 5d03c7088..000000000 --- a/sarif/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -all: - r2 -i sarif.r2.js /bin/ls - -install: - mkdir -p $(shell r2 -H R2_USER_PLUGINS) - ln -fs $(shell pwd)/sarif.r2.js $(shell r2 -H R2_USER_PLUGINS)/sarif.r2.js - -user-install: - mkdir -p $(shell r2 -H R2_USER_PLUGINS) - cp -f sarif.r2.js $(shell r2 -H R2_USER_PLUGINS) - -uninstall user-uninstall: - rm -f $(shell r2 -H R2_USER_PLUGINS)/sarif.r2.js - -indent: - cat sarif.r2.js | sed -e 's/\t/ /g' > tmp.r2.js - mv tmp.r2.js sarif.r2.js - semistandard --global r2 --fix sarif.r2.js diff --git a/sarif/README.md b/sarif/README.md deleted file mode 100644 index 5ad21713a..000000000 --- a/sarif/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# SARIF for Radare2 - -Static Analysis Results Interchange Format (SARIF) Version 2.0 - -## Description - -This plugin for radare2 adds the `sarif` command to the r2 shell which allows to import and export SARIF documents (JSON files) into the current session, allowing the analyst to report and visualize the reported vulnerabilities in a binary using a standard file format. - -## Usage - -``` -[0x00000000]> sarif? -sarif [action] [arguments] -sarif -h, help - show this help message (-h) -sarif -a, add [r] [c] - add a new sarif finding -sarif -aw,-ae,-an [r] [c] - add warning, error or note -sarif -i, import [file] - import sarif info from given file -sarif -j, json - print the spotted findings as json to stdout -sarif -r, r2|script - generate r2 script with loaded sarif info -sarif -R, reset - reset reported findings list -sarif -l, rules ([file]) - list or load rules from file -[0x00000000]> -``` - -First you need to load the rules that you plan to report as findings: - -``` -[0x00000000]> sarif -l rule.json -``` - -Those can be listed with `sarif -l` (note that there's no argument here). At this point you are ready to report your first finding! - -* Seek to the offset where the vulnerability is spotted -* Run `sarif -aw rules.mastg-android-insecure-random-use Do not use this API` - -You can now export the sarif file in json using the following command: - -``` -[0x00000000]> sarif -j > reports.json -``` - -Alternatively you can combine multiple finding documents and load that info inside r2: - -``` -[0x00000000]> sarif -i report0.json -[0x00000000]> sarif -i report1.json -[0x00000000]> .sarif -r -``` - -You will have flags prefixed with `sarif.` to spot them in the binary. `f~^sarif` - -## Links - -* https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning?learn=code_security_integration -* https://github.com/microsoft/sarif-tutorials/ -* https://docs.oasis-open.org/sarif/sarif/v2.0/sarif-v2.0.html -* https://sarifweb.azurewebsites.net/#Specification -* https://github.blog/2024-02-14-fixing-security-vulnerabilities-with-ai/ diff --git a/sarif/rules-test.json b/sarif/rules-test.json deleted file mode 100644 index 64c75b233..000000000 --- a/sarif/rules-test.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/sarif-2.1.0", - "version": "2.1.0", - "runs": [ - { - "tool": { - "driver": { - "name": "mastg", - "semanticVersion": "1.0.0", - "rules": [ - { - "id": "VULN-OVERFLOW", - "name": "vuln-overflow", - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[VULN-1] Potential Buffer Overflow" - } - }, - { - "id": "VULN-WEAK-CRYPTO", - "name": "vuln-weak-crypto", - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[VULN-1] Use of weak crypto" - } - }, - { - "id": "VULN-SQL-INJECTION", - "name": "vuln-sql-injection", - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[VULN-1] SQL Injection Vulnerability" - } - } - ] - } - } - } - ] -} diff --git a/sarif/rules.json b/sarif/rules.json deleted file mode 100644 index af4413265..000000000 --- a/sarif/rules.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/sarif-2.1.0", - "version": "2.1.0", - "runs": [ - { - "tool": { - "driver": { - "name": "mastg", - "semanticVersion": "1.0.0", - "rules": [ - { - "id": "rules.mastg-android-insecure-random-use", - "name": "rules.mastg-android-insecure-random-use", - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-CRYPTO-1] The application makes use of insecure random number generator." - }, - "help": { - "markdown": "[MASVS-CRYPTO-1] The application makes use of insecure random number generator.", - "text": "[MASVS-CRYPTO-1] The application makes use of insecure random number generator." - }, - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-insecure-random-use" - } - }, - { - "id": "rules.mastg-android-non-random-use", - "name": "rules.mastg-android-non-random-use", - "defaultConfiguration": { - "level": "warning" - }, - "fullDescription": { - "text": "[MASVS-CRYPTO-1] The application makes use of non-random sources." - }, - "help": { - "markdown": "[MASVS-CRYPTO-1] The application makes use of non-random sources.", - "text": "[MASVS-CRYPTO-1] The application makes use of non-random sources." - }, - "properties": { - "precision": "very-high", - "tags": [] - }, - "shortDescription": { - "text": "Semgrep Finding: rules.mastg-android-non-random-use" - } - } - ] - } - } - } - ] -} diff --git a/sarif/sarif.r2.js b/sarif/sarif.r2.js deleted file mode 100644 index dbf4b69af..000000000 --- a/sarif/sarif.r2.js +++ /dev/null @@ -1,314 +0,0 @@ -const sarifTemplate = { - $schema: 'http://json.schemastore.org/sarif-2.1.0', - version: '2.1.0', - runs: [ - { - tool: { - driver: { - name: 'radare2', - semanticVersion: '1.0.0', - rules: [ - ] - } - }, - results: [ - ] - } - ] -}; - -class R2Sarif { - constructor () { - this.doc = sarifTemplate; - this.rulesLoaded = {}; - } - - /* load rules from a sarif file */ - loadRules (sarifDocument) { - for (let run of sarifDocument.runs) { - for (let rule of run.tool.driver.rules) { - this.rulesLoaded[rule.id] = rule; - } - } - } - - loadResults (sarifDocument) { - for (let run of sarifDocument.runs) { - for (let res of run.results) { - const ruleId = res.ruleId; - const level = res.level; - const message = res.message.text; - const loc0 = res.locations[0]; - try { - console.log(JSON.stringify(loc0, null, 2)); - const phyloc = loc0.physicalLocation; - const artifact = phyloc.artifactLocation.uri; - const locations = [{ - va: loc0.properties.memoryAddress, - pa: phyloc.region.startByteOffset, - sz: phyloc.region.byteLength, - }]; - this.addResult (ruleId, level, message, artifact, locations); - } catch (e) { - console.error(e); - } - } - } - } - - addRule (id) { - if (this.doc.runs[0].tool.driver.rules.filter((x) => x.id === id).length !== 0) { - return true; - } - const rule = this.rulesLoaded[id]; - if (rule) { - this.doc.runs[0].tool.driver.rules.push(rule); - return true; - } - return false; - } - reset () { - this.doc.runs[0].results = []; - this.doc.runs[0].tool.driver.rules = []; - } - - addResult (ruleId, level, message, artifact, locations) { - if (!this.addRule(ruleId)) { - console.error("Invalid rule id: " + ruleId); - return false; - } - const sarifLocations = []; - const result = { - ruleId: ruleId, - level: level, - message: { - text: message - }, - locations: [] - }; - const locationTemplate = { - physicalLocation: { - artifactLocation: { - uri: 'binary://' + artifact, - uriBaseId: '%SRCROOT%' - }, - region: { - startByteOffset: locations, - byteLength: 128 - } - }, - properties: { - memoryAddress: '0x0040321A' - } - }; - for (const loc of locations) { - const myLoc = locationTemplate; - myLoc.physicalLocation.region = { - startByteOffset: loc.pa, - byteLength: loc.sz - }; - myLoc.properties = { - memoryAddress: loc.va - }; - result.locations.push(myLoc); - } - this.doc.runs[0].results.push(result); - return true; - } - - toString () { - return JSON.stringify(this.doc, null, 2) + '\n'; - } - - toScript () { - let script = '# r2sarif script\n'; - const results = this.doc.runs[0].results; - let counter = 0; - for (const res of results) { - const text = res.message.text; - for (const loc of res.locations) { - // console.log(JSON.stringify(res)); - const address = loc.properties.memoryAddress; - const size = loc.physicalLocation.region.byteLength; - const ruleId = res.ruleId; - script += `CC ${ruleId}:${text} @ ${address}\n`; - script += `f sarif.${counter} ${size} ${address}\n`; - counter++; - } - } - return script; - } -} - -function sarifTest () { - const s = new R2Sarif(); - s.addResultOverflow('/bin/ls', 'buffer overflow detected', [ - { va: 0x804804, pa: 0x804, sz: 32 } - ]); - console.log(s.toString()); - console.log(s.toScript()); -} - -function sarifRegisterPlugin () { - const sarif = new R2Sarif(); - function sarifCommand (args) { - function sarifHelp () { - console.log('sarif [action] [arguments]'); - console.log('sarif -h, help - show this help message (-h)'); - console.log('sarif -a, add [r] [c] - add a new sarif finding'); - console.log('sarif -aw,-ae,-an [r] [c] - add warning, error or note'); - console.log('sarif -i, import [file] - import sarif info from given file'); - console.log('sarif -e, export [file] - export sarif findings into given file or stdout'); - console.log('sarif -r, r2|script - generate r2 script with loaded sarif info'); - console.log('sarif -R, reset - reset reported findings list'); - console.log('sarif -l, rules ([file]) - list or load rules from file'); - } - function sarifLoadRules(fileName) { - const sarifObject = r2.cmdj(`cat ${fileName}`); - sarif.loadRules(sarifObject); - } - function sarifLoadResults(fileName) { - const sarifObject = r2.cmdj(`cat ${fileName}`); - sarif.loadRules(sarifObject); - sarif.loadResults(sarifObject); - } - function listRules() { - const res = []; - for (const ruleId of Object.keys(sarif.rulesLoaded)) { - const rule = sarif.rulesLoaded[ruleId]; - res.push(`- ${ruleId}`); - try { - const desc = rule.fullDescription.text; - res.push(` - description: ${desc}`); - } catch (e) {} - try { - const level = rule.defaultConfiguration.level; - res.push (` - level: ${level}`); - } catch (e) {} - } - return res.join("\n"); - } - function sarifImport(fileName) { - if (fileName === '') { - console.log('Usage: sarif -i [filename]'); - } else { - sarifLoadResults(fileName); - } - } - function sarifExport () { - console.log(sarif.toString()); - } - function sarifScript (fileName) { - r2.log(sarif.toScript()); - } - function sarifAdd (level, args) { - const arg = args.split(/ /); - if (arg.length === 0) { - console.error("Usage: sarif add[?] [id] [message]"); - return false; - } - const artifact = r2.cmd('o.').trim(); - const loc0 = { - va: +r2.cmd('?v $$'), - pa: r2.cmd('?p $$').trim(), - sz: 1 - }; - const locations = [loc0]; - const ruleId = arg[0]; - const rule = sarif.rulesLoaded[ruleId]; - const comment = arg.length > 1 ? arg[1] : ''; - if (level === null) { - try { - level = rule.defaultConfiguration.level; - } catch (err) { - level = "warning"; - } - } - if (!sarif.addResult(ruleId, level, comment, artifact, locations)) { - console.error("Cannot add result"); - } - } - let arg = args.substr('sarif'.length).trim(); - const space = arg.indexOf(' '); - let action = arg.trim(); - if (space !== -1) { - action = arg.substr(0, space); - arg = arg.substr(space + 1); - } else { - arg = ''; - } - switch (action) { - case '': - case '?': - case '-h': - case 'help': - sarifHelp(); - break; - case '-a': - case 'add': - sarifAdd(null, arg); - break; - case '-aw': - case 'addw': - sarifAdd("warning", arg); - break; - case '-ae': - case 'adde': - sarifAdd("error", arg); - break; - case '-an': - case 'addn': - sarifAdd("note", arg); - break; - case '-l': - case 'lr': - case 'rules': - case 'load-rules': - if (arg) { - sarifLoadRules(arg); - } else { - r2.log(listRules()); - } - break; - case '-i': - case 'import': - sarifImport(arg); - break; - case '-j': - case '-e': - case 'export': - sarifExport(arg); - break; - case '*': - case '-r': - case 'r2': - case 'script': - sarifScript(arg); - break; - case '-R': - case 'reset': - sarif.reset(); - break; - default: - console.error('Unknown action'); - break; - } - } - r2.unload('core', 'sarif'); - r2.plugin('core', function () { - function coreCall (cmd) { - if (cmd.startsWith('sarif')) { - sarifCommand(cmd); - return true; - } - return false; - } - return { - name: 'sarif', - license: 'MIT', - desc: 'support importing and exporting sarif format', - call: coreCall - }; - }); -} -sarifRegisterPlugin(); diff --git a/sarif/test2.json b/sarif/test2.json deleted file mode 100644 index a0eff4916..000000000 --- a/sarif/test2.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/sarif-2.1.0", - "version": "2.1.0", - "runs": [ - { - "tool": { - "driver": { - "name": "radare2", - "semanticVersion": "1.0.0", - "rules": [ - { - "id": "EXAMPLE-VULN-001", - "shortDescription": { - "text": "Potential buffer overflow." - }, - "helpUri": "http://example.com/vulnerability/EXAMPLE-VULN-001" - } - ] - } - }, - "results": [ - { - "ruleId": "EXAMPLE-VULN-001", - "level": "error", - "message": { - "text": "Buffer overflow vulnerability detected." - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "binary://example-binary", - "uriBaseId": "%SRCROOT%" - }, - "region": { - "startByteOffset": 1024, - "byteLength": 128 - } - }, - "properties": { - "memoryAddress": "0x0040321A" - } - } - ] - } - ] - } - ] -}