Skip to content
This repository was archived by the owner on Oct 27, 2021. It is now read-only.

Commit 702efe8

Browse files
authored
Merge pull request #107 from joernio/claudiu/ghidra-simp
Add MainArgsToStrcpy ghidra query
2 parents 1413525 + 0b7118d commit 702efe8

5 files changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.joern.scanners.ghidra
2+
3+
import io.joern.scanners._
4+
import io.shiftleft.console._
5+
import io.shiftleft.macros.QueryMacros._
6+
import io.shiftleft.semanticcpg.language._
7+
import io.shiftleft.dataflowengineoss.language._
8+
import io.shiftleft.dataflowengineoss.queryengine.EngineContext
9+
10+
object MainArgsToStrcpy extends QueryBundle {
11+
12+
implicit val resolver: ICallResolver = NoResolve
13+
14+
@q
15+
def mainArgsToStrcpy()(implicit context: EngineContext): Query =
16+
Query.make(
17+
name = "main-args-to-strcpy",
18+
author = Crew.claudiu,
19+
title = "`main` fn arguments used in strcpy source buffer",
20+
description =
21+
"""
22+
|User-input ends up in source buffer argument of strcpy, which might overflow the destination buffer.
23+
|""".stripMargin,
24+
score = 4,
25+
withStrRep({ cpg =>
26+
def source = cpg.method.fullName("main").parameter
27+
def sink = cpg.call.methodFullName("strcpy").argument
28+
sink.reachableBy(source).l
29+
}),
30+
tags = List(QueryTags.badfn)
31+
)
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
4+
// gcc -fno-stack-protector -z execstack -no-pie -o buf1 buf1.c
5+
int main(int argc, char *argv[]) {
6+
if (argc == 1) {
7+
printf("Program executed with no arguments.\n");
8+
return 0;
9+
}
10+
char c[6];
11+
strcpy(c, argv[1]);
12+
printf("First argument is: %s\n", c);
13+
return 0;
14+
}
15.5 KB
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.joern.scanners.ghidra
2+
3+
import io.joern.suites.GhidraQueryTestSuite
4+
5+
class MainArgsToStrcpyTests extends GhidraQueryTestSuite {
6+
override def queryBundle = MainArgsToStrcpy
7+
8+
"find main function with data flow between argument and strcpy" in {
9+
buildCpgForBin("buf1.exe")
10+
val query = queryBundle.mainArgsToStrcpy()
11+
val results = findMatchingMethodParam(query)
12+
results shouldBe Set("main")
13+
}
14+
}

src/test/scala/io/joern/suites/GhidraQueryTestSuite.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,22 @@ class GhidraQueryTestSuite extends DataFlowBinToCpgSuite {
1515

1616
override def beforeAll(): Unit = {
1717
semanticsFilename = argumentProvider.testSemanticsFilename
18+
super.beforeAll()
1819
}
1920

2021
def queryBundle: QueryBundle = QueryUtil.EmptyBundle
2122

2223
def allQueries = QueryUtil.allQueries(queryBundle, argumentProvider)
2324

25+
def findMatchingMethodParam(query: Query): Set[String] = {
26+
query(cpg)
27+
.flatMap(_.evidence)
28+
.collect { case methodParam: nodes.MethodParameterIn => methodParam }
29+
.method
30+
.name
31+
.toSetImmutable
32+
}
33+
2434
def findMatchingCalls(query: Query): Set[String] = {
2535
query(cpg)
2636
.flatMap(_.evidence)

0 commit comments

Comments
 (0)