From 03e2323d01d24458b41c3cd071e39fe2ef06bfad Mon Sep 17 00:00:00 2001 From: Riccardo Cardelli Date: Tue, 9 Jul 2024 21:21:32 +0200 Subject: [PATCH 1/5] update command-injection --- c/command-injection.c | 62 +++++++++++++++++++++++++++++++++++++++- c/command-injection.yaml | 44 ++++++++++++++++++++++++---- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/c/command-injection.c b/c/command-injection.c index a54ebe6..1c640e2 100644 --- a/c/command-injection.c +++ b/c/command-injection.c @@ -31,6 +31,66 @@ void invoke2(char *string) popen(string, "r"); } +void invoke2(char *string) +{ + // ok: raptor-command-injection + execl("/bin/ls", "ls", "-l", "/home", (char *)0); + // ruleid: raptor-command-injection + execl("/bin/ls", "ls", "-l", string, (char *)0); + + // ok: raptor-command-injection + execlp("ls", "ls", "-l", "/home", (char *)0); + // ruleid: raptor-command-injection + execlp("ls", "ls", "-l", string, (char *)0); + + char *envp[] = { "MY_VAR=42", NULL }; + // ok: raptor-command-injection + execle("/bin/ls", "ls", "-l", "/home", (char *)0, envp); + // ruleid: raptor-command-injection + execle("/bin/ls", "ls", "-l", string, (char *)0, envp); + + char *envp[] = { "MY_VAR=42", NULL }; + // ok: raptor-command-injection + execlpe("ls", "ls", "-l", "/home", (char *)0, envp); + // ruleid: raptor-command-injection + execlpe("ls", "ls", "-l", string, (char *)0, envp); + + char *argv[] = { "ls", "-l", "/home", NULL }; + // ok: raptor-command-injection + execv("/bin/ls", argv); + // ruleid: raptor-command-injection + char *argv[] = { "ls", "-l", string, NULL }; + execv("/bin/ls", argv); + + char buf[] = "/home" + // ok: raptor-command-injection + char *argv[] = { "ls", "-l", buf, NULL }; + execvp("ls", argv); + // ruleid: raptor-command-injection + char *argv[] = { "ls", "-l", string, NULL }; + execvp("ls", argv); + + char *argv[] = { "ls", "-l", "/home", NULL }; + char *envp[] = { "MY_VAR=42", NULL }; + // ok: raptor-command-injection + execve("/bin/ls", argv, envp); + + char *argv[] = { "ls", "-l", string, NULL }; + char *envp[] = { "MY_VAR=42", NULL }; + // ruleid: raptor-command-injection + execve("/bin/ls", argv, envp); + + char *argv[] = { "ls", "-l", "/home", NULL }; + char *envp[] = { "MY_VAR=42", NULL }; + // ok: raptor-command-injection + execvpe("ls", argv, envp); + + char *argv[] = { "ls", "-l", string, NULL }; + char *envp[] = { "MY_VAR=42", NULL }; + // ruleid: raptor-command-injection + execvpe("ls", argv, envp); +} + int send_mail(char *user) { char buf[1024]; @@ -42,7 +102,7 @@ int send_mail(char *user) fp = popen(buf, "w"); if (fp == NULL) - return 1; + return 1; // ... } diff --git a/c/command-injection.yaml b/c/command-injection.yaml index 68700a0..9e5bec3 100644 --- a/c/command-injection.yaml +++ b/c/command-injection.yaml @@ -18,8 +18,42 @@ rules: languages: - c - cpp - patterns: - - pattern-either: - - pattern: system(...) - - pattern: popen(...) - - pattern-not: $FUN("...", ...) + options: + symbolic_propagation: true + pattern-either: + - patterns: + - pattern-either: + - pattern: system(...) + - pattern: popen(...) + - pattern-not: $FUN("...", ...) + - patterns: + - pattern-either: + - pattern: execl(..., $P, ..., $NULL) + - pattern: execlp(..., $P, ..., $NULL) + - pattern: execle(..., $P, ..., $NULL, $ENV) + - pattern: execlpe(..., $P, ..., $NULL, $ENV) + - pattern: execv($P, ...) + - pattern: execvp($P, ...) + - pattern: execve($P, ..., $ENV) + - pattern: execvpe($P, ..., $ENV) + - metavariable-pattern: + metavariable: $P + patterns: + - pattern-not: (string $X) + - patterns: + - pattern-either: + - pattern: | + $ARGV = {..., $PP ,..., $NULL}; + ... + $FUNC(..., $ARGV); + - pattern: | + $ARGV = {..., $PP ,..., $NULL}; + ... + $FUNC(..., $ARGV, $ENV); + - metavariable-regex: + metavariable: $FUNC + regex: (execv|execvp|execve|execvpe) + - metavariable-pattern: + metavariable: $PP + patterns: + - pattern-not: (string $X) From fc988c6620b8f669cec01f35530fa0e5b6af18b3 Mon Sep 17 00:00:00 2001 From: Riccardo Cardelli Date: Tue, 9 Jul 2024 21:22:54 +0200 Subject: [PATCH 2/5] update double-free --- c/double-free.c | 26 +++++++++++++++--- c/double-free.yaml | 66 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/c/double-free.c b/c/double-free.c index ad100a7..500172b 100644 --- a/c/double-free.c +++ b/c/double-free.c @@ -29,13 +29,24 @@ void alloc_and_free2() // ok: raptor-double-free free(ptr); } +void loop_and_free() +{ + char *ptr = (char *)malloc(MEMSIZE); + int i=0; + for(i=0;i<10; i++){ + // ok: raptor-double-free + free(ptr[i]); + // ruleid: raptor-double-free + free(ptr); + } +} void alloc_and_free3() { char *ptr = (char *)malloc(MEMSIZE); free(ptr); - ptr = (char *)malloc(MEMSIZE); + ptr = malloc(MEMSIZE); // ok: raptor-double-free free(ptr); } @@ -56,6 +67,15 @@ void double_free(int argc, char **argv) free(buf1R2); } +void double_free2(){ + char *s1; + char *s2; + s1 = s2; + free(s1); + // ruleid: raptor-double-free + free(s2); +} + int Packet *getNextPacket() { Packet *y = (Packet *) malloc(1024); @@ -63,7 +83,7 @@ int Packet *getNextPacket() if(retval == OK) { return y; } else { - return NULL; + return NULL; } } @@ -72,7 +92,7 @@ int bad() free(logData); pkt = getNextPacket(); if(!pkt) { - return NULL; + return NULL; } logPktData(pkt); // ruleid: raptor-double-free diff --git a/c/double-free.yaml b/c/double-free.yaml index 06fed0b..9ae7567 100644 --- a/c/double-free.yaml +++ b/c/double-free.yaml @@ -21,18 +21,62 @@ rules: - c - cpp patterns: - - pattern: | - free($PTR); - ... - $FREE($PTR); - - pattern-not: | - free($PTR); - ... - $PTR = $EXPR; - ... - free($PTR); + - pattern-either: + - patterns: + - pattern: | + free($PTR); + ... + $FREE($PTR); + - pattern-not: | + free($PTR); + ... + $PTR = $EXPR; + ... + free($PTR); + - patterns: + - pattern: | + { ... + free($PTR1); + ... + $FREE($PTR2); + ... } + - pattern-either: + - pattern: | + {... + $PTR1 = $PTR2; + ...} + - pattern: | + {... + $PTR2 = $PTR1; + ...} + - pattern-not: | + { ... + free($PTR); + ... + $PTR = $EXPR; + ... + free($PTR); + ... } + - patterns: + - pattern-either: + - pattern: | + for(...; ...; ...){ ... + $FREE($PTR); + ... } + - pattern: | + while(...){ ... + $FREE($PTR); + ... } + - pattern: | + do{ ... + $FREE($PTR); + ... }while(...); + - metavariable-pattern: + metavariable: $PTR + patterns: + - pattern-not: ...[...] - metavariable-pattern: metavariable: $FREE pattern: free # improve output readability - - focus-metavariable: $FREE + - focus-metavariable: $FREE \ No newline at end of file From dc246f9d836741917c903e1f9b5b320e82be089f Mon Sep 17 00:00:00 2001 From: Riccardo Cardelli Date: Tue, 9 Jul 2024 21:23:47 +0200 Subject: [PATCH 3/5] update incorrect-use-of-free --- c/incorrect-use-of-free.c | 12 ++++++++++++ c/incorrect-use-of-free.yaml | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/c/incorrect-use-of-free.c b/c/incorrect-use-of-free.c index ee98e32..0665c55 100644 --- a/c/incorrect-use-of-free.c +++ b/c/incorrect-use-of-free.c @@ -47,6 +47,18 @@ int check_auth(char *login, char *passwd) return(stat); } +int free_after_return(){ + // ruleid: raptor-incorrect-use-of-free + char *s = (char*)malloc(STRING_SIZE); + int i = 0; + for(i=0;i Date: Tue, 9 Jul 2024 21:24:29 +0200 Subject: [PATCH 4/5] update incorrect-use-of-strncat --- c/incorrect-use-of-strncat.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/c/incorrect-use-of-strncat.yaml b/c/incorrect-use-of-strncat.yaml index a62ea17..ac24800 100644 --- a/c/incorrect-use-of-strncat.yaml +++ b/c/incorrect-use-of-strncat.yaml @@ -12,7 +12,7 @@ rules: quite easy to misuse. The first common mistake is supplying the size of the entire buffer instead of the size remaining in the buffer. A more subtle mistake can be made: the size parameter needs to be the amount of - space left in the buffer less one; otherwise, the NUL byte is written + space left in the buffer less one; otherwise, the NULL byte is written one byte past the end of the buffer. severity: ERROR languages: @@ -31,8 +31,10 @@ rules: ... # sizeof operator - pattern: strncat($DST, $SRC, sizeof($DST)) - # strlen function + # strlen and strnlen functions - pattern: strncat($DST, $SRC, strlen($DST)) + - pattern: strncat($DST, $SRC, strnlen($DST, ...)) # off-by-one # see also off-by-one.yaml for a slightly different pattern - pattern: strncat($DST, $SRC, sizeof($DST) - strlen($DST)) + - pattern: strncat($DST, $SRC, sizeof($DST) - strnlen($DST, ...)) From 1c3803fd0715bcf0264e0dd9688c39cdb208317c Mon Sep 17 00:00:00 2001 From: Riccardo Cardelli Date: Tue, 9 Jul 2024 21:27:12 +0200 Subject: [PATCH 5/5] new insecure-random-seed rule --- c/insecure-random-seed.c | 55 +++++++++++++++++++++++++++++++++++++ c/insecure-random-seed.yaml | 35 +++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 c/insecure-random-seed.c create mode 100644 c/insecure-random-seed.yaml diff --git a/c/insecure-random-seed.c b/c/insecure-random-seed.c new file mode 100644 index 0000000..43656cb --- /dev/null +++ b/c/insecure-random-seed.c @@ -0,0 +1,55 @@ +#include +#include +#include + +int example1() { + // ruleid: raptor-insecure-random-seed + srand(1234); + printf("Random number: %d\n", rand()); + return 0; +} + +int example2() { + time_t t; + time(&t); + // ruleid: raptor-insecure-random-seed + srand((unsigned int)t); + printf("Random number: %d\n", rand()); + return 0; +} + + +int example3() { + // ruleid: raptor-insecure-random-seed + srand((unsigned int)getpid()); + printf("Random number: %d\n", rand()); + return 0; +} + +int example4() { + // ruleid: raptor-insecure-random-seed + srand((unsigned int)time(NULL)); + for (int i = 0; i < 5; i++) { + printf("Random number: %d\n", rand()); + } + return 0; +} +int example5() { + int seed = 42 * 42; + // ruleid: raptor-insecure-random-seed + srand(seed); + printf("Random number: %d\n", rand()); + return 0; +} + +void example6(void) { + struct timespec ts; + if (timespec_get(&ts, TIME_UTC) == 0) { + /* Handle error */ + } else { + // ruleid: raptor-insecure-random-seed + srandom(ts.tv_nsec ^ ts.tv_sec); + for (unsigned int i = 0; i < 10; ++i) { + printf("%ld, ", random()); + } +} \ No newline at end of file diff --git a/c/insecure-random-seed.yaml b/c/insecure-random-seed.yaml new file mode 100644 index 0000000..2a0047f --- /dev/null +++ b/c/insecure-random-seed.yaml @@ -0,0 +1,35 @@ +rules: + - id: raptor-insecure-random-seed + metadata: + author: Riccardo Cardelli + references: + - https://cwe.mitre.org/data/definitions/335 + - https://www.sei.cmu.edu/downloads/sei-cert-c-coding-standard-2016-v01.pdf + confidence: HIGH + message: The use of a predictable or a static seed risks making the output + of the random functions easily guessable. + severity: WARNING + languages: + - c + - cpp + options: + interfile: true + mode: taint + pattern-sources: + - pattern: time(...) + - pattern: getpid(...) + - pattern: timespec_get(...) + - pattern: gettimeofday(...) + - pattern: clock_gettime(...) + - pattern: GetSystemTime(...) #Windows + - pattern: GetLocalTime(...) # Windows + - pattern: clock(...) + - pattern: (int $X) + pattern-propagators: + - pattern: <... $F(...,&$P, ...) ...> + from: $F + to: $P + pattern-sinks: + - pattern: srand(...) + - pattern: srandom(...) + - pattern: $R.seed(...)