Skip to content

Instantly share code, notes, and snippets.

@richinseattle
Created March 30, 2024 12:14
Show Gist options
  • Save richinseattle/bd5d5e1da499aa207ff50e91444ec8d0 to your computer and use it in GitHub Desktop.
Save richinseattle/bd5d5e1da499aa207ff50e91444ec8d0 to your computer and use it in GitHub Desktop.
Run all raptor's weggli rules on current directory from cmd.exe
REM buffer overflows
REM call to unbounded copy functions (CWE-120, CWE-242, CWE-676)
weggli.exe -R "func=^gets$" "{$func();}" .
weggli.exe -R "func=st(r|p)(cpy|cat)$" "{$func();}" .
weggli.exe -R "func=wc(s|p)(cpy|cat)$" "{$func();}" .
weggli.exe -R "func=sprintf$" "{$func();}" .
weggli.exe -R "func=scanf$" "{$func();}" .
REM incorrect use of strncat (CWE-193, CWE-787)
weggli.exe "{strncat(_,_,sizeof(_));}" .
weggli.exe "{strncat(_,_,strlen(_));}" .
weggli.exe "{strncat($dst,$src,sizeof($dst)-strlen($dst));}" .
weggli.exe "{_ $buf[$len]; strncat($buf,_,$len);}" .
REM The last pattern won"t work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59).
REM destination buffer access using size of source buffer (CWE-806)
weggli.exe -R "func=cpy$" "{$func(_,$src,_($src));}" .
weggli.exe -R "func=cpy$" "{$len=_($src); $func(_,$src,$len);}" .
weggli.exe -R "func=cpy$" "{_ $src[$len]; $func($dst,$src,$len);}" .
REM The last pattern won"t work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59).
REM use of sizeof() on a pointer type (CWE-467)
weggli.exe "{_* $ptr; sizeof($ptr);}" .
weggli.exe "{_* $ptr=_; sizeof($ptr);}" .
weggli.exe "_ $func(_* $ptr) {sizeof($ptr);}" .
REM Apparently, global variables are not supported so this won"t work:
weggli.exe "_* $ptr=_; _ $func(_) {sizeof($ptr);}" .
REM use of sizeof() on a character constant
weggli.exe "sizeof("_")" .
REM In C (but not in C++) character constants have type int.
REM lack of explicit NUL-termination after strncpy(), etc. (CWE-170)
weggli.exe -R "func=ncpy$" "{$func($buf,_); not:$buf[_]=_;}" .
REM Some possible variants: memcpy, read, readlink, fread, etc.
REM off-by-one error (CWE-193)
weggli.exe "{$buf[sizeof($buf)];}" .
weggli.exe "{_ $buf[$len]; $buf[$len]=_;}" .
weggli.exe "{strlen($src)>sizeof($dst);}" .
weggli.exe "{strlen($src)<=sizeof($dst);}" .
weggli.exe "{sizeof($dst)<strlen($src);}" .
weggli.exe "{sizeof($dst)>=strlen($src);}" .
weggli.exe "{$buf[strlen($buf)-1];}" .
weggli.exe -R "func=allocf?$" "{$func(strlen($buf));}" .
weggli.exe -R "func=allocf?$" "{$len=strlen(_); $ptr=$func($len);}" .
weggli.exe -R "func=allocf?$" "{$len=snprintf(_); $ptr=$func($len);}" .
REM The second pattern won"t work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59).
REM `<` should also cover `>` and `<=` should also cover `>=`; however, let"s keep all variants just to be sure.
REM use of pointer subtraction to determine size (CWE-469)
weggli.exe "{_* $ptr1; $ptr1-$ptr2;}" .
weggli.exe "{_* $ptr2; $ptr1-$ptr2;}" .
weggli.exe "{_* $ptr1=_; $ptr1-$ptr2;}" .
weggli.exe "{_* $ptr2=_; $ptr1-$ptr2;}" .
weggli.exe "_ $func(_* $ptr1) {$ptr1-$ptr2;}" .
weggli.exe "_ $func(_* $ptr2) {$ptr1-$ptr2;}" .
REM potentially unsafe use of the return value of snprintf(), etc. (CWE-787)
weggli.exe -R "func=(nprintf|lcpy|lcat)$" "{$ret=$func();}" .
REM direct write into buffer allocated on the stack (CWE-121)
weggli.exe -R "func=(cpy|cat|memmove|memset|sn?printf)$" "{_ $buf[_]; $func($buf,_);}" .
weggli.exe "{_ $buf[_]; $buf[_]=_;}" .
REM Some possible variants: bcopy, gets, fgets, getwd, getcwd, fread, read, pread, recv, recvfrom, etc.
REM integer overflows
REM incorrect unsigned comparison (CWE-697)
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var; $var<0;}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var; $var<=0;}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var; $var>=0;}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var=_; $var<0;}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var=_; $var<=0;}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var=_; $var>=0;}" .
REM `<` should also cover `>` and `<=` should also cover `>=`; however, let"s keep all variants just to be sure.
REM signed/unsigned conversion (CWE-195, CWE-196)
weggli.exe -R "$copy=(cpy|ncat)$" "{int $len; $copy(_,_,$len);}" .
weggli.exe -R "$copy=(cpy|ncat)$" "{int $len=_; $copy(_,_,$len);}" .
weggli.exe -R "$copy=(cpy|ncat)$" "_ $func(int $len) {$copy(_,_,$len);}" .
weggli.exe -R "$copy=nprintf$" "{int $len; $copy(_,$len);}" .
weggli.exe -R "$copy=nprintf$" "{int $len=_; $copy(_,$len);}" .
weggli.exe -R "$copy=nprintf$" "_ $func(int $len) {$copy(_,$len);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var1; int $var2; $var2=_($var1);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var1; int $var2; $var1=_($var2);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{$type $var1; int $var2=_($var1);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{int $var1; $type $var2; $var2=_($var1);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{int $var1; $type $var2; $var1=_($var2);}" .
weggli.exe -R "$type=(unsigned|size_t)" "{int $var1=_; $type $var2=_($var1);}" .
weggli.exe -R "$type=(unsigned|size_t)" "_ $func(int $var2) {$type $var1; $var1=_($var2);}" .
weggli.exe -R "$type=(unsigned|size_t)" "_ $func(int $var2) {$type $var1=_($var2);}" .
weggli.exe -R "$type=(unsigned|size_t)" "$type $func(_) {int $var; return $var;}" .
weggli.exe -R "$type=(unsigned|size_t)" "int $func(_) {$type $var; return $var;}" .
REM There are many possible variants of these patterns...
REM integer truncation (CWE-197)
weggli.exe -R "type=(short|int|long)" "{$type $large; char $narrow; $narrow = $large; }" .
weggli.exe -R "type=(short|int|long)" "{$type $large; char $narrow = $large; }" .
weggli.exe -R "type=(int|long)" "{$type $large; short $narrow; $narrow = $large; }" .
weggli.exe -R "type=(int|long)" "{$type $large; short $narrow = $large; }" .
weggli.exe "{long $large; int $narrow; $narrow = $large; }" .
weggli.exe "{long $large; int $narrow = $large; }" .
weggli.exe -R "type=(short|int|long)" "_ $func($type $large) {char $narrow; $narrow = $large; }" .
weggli.exe -R "type=(short|int|long)" "_ $func($type $large) {char $narrow = $large; }" .
weggli.exe -R "type=(int|long)" "_ $func($type $large) {short $narrow; $narrow = $large; }" .
weggli.exe -R "type=(int|long)" "_ $func($type $large) {short $narrow = $large; }" .
weggli.exe "_ $func(long $large) {int $narrow; $narrow = $large; }" .
weggli.exe "_ $func(long $large) {int $narrow = $large; }" .
REM There are many possible variants of these patterns...
REM use of signed or short sizes, lengths, offsets, counts (CWE-190, CWE-680)
weggli.exe "short _" .
weggli.exe "int _" .
REM Some possible variants: short int, unsigned short, unsigned short int, int.
REM cast of the return value of strlen(), wcslen() to short (CWE-190, CWE-680)
weggli.exe -R "func=(str|wcs)len$" "{short $len; $len=$func();}" .
REM Some possible variants: short int, unsigned short, unsigned short int, even signed int.
REM integer wraparound (CWE-128, CWE-131, CWE-190, CWE-680)
weggli.exe -R "func=allocf?$" "{$func(_*_);}" .
weggli.exe -R "func=allocf?$" "{$func(_+_);}" .
weggli.exe -R "func=allocf?$" "{$n=_*_; $func($n);}" .
weggli.exe -R "func=allocf?$" "{$n=_+_; $func($n);}" .
weggli.exe -R "alloc=allocf?$" -R "copy=cpy$" "{$alloc($x*_); $copy(_,_,$x);}" .
weggli.exe -R "alloc=allocf?$" -R "copy=cpy$" "{$alloc($x+_); $copy(_,_,$x);}" .
weggli.exe -u -R "alloc=allocf?$" -R "copy=cpy$" "{$n=_*_; $alloc($n); $copy(_,_,$x);}" .
weggli.exe -u -R "alloc=allocf?$" -R "copy=cpy$" "{$n=_+_; $alloc($n); $copy(_,_,$x);}" .
weggli.exe "{$x>_||($x+$y)>_;}" .
weggli.exe "{$x>=_||($x+$y)>_;}" .
weggli.exe "{$x>_||($x+$y)>=_;}" .
weggli.exe "{$x>=_||($x+$y)>=_;}" .
weggli.exe "{$x<_&&($x+$y)<_;}" .
weggli.exe "{$x<=_&&($x+$y)<_;}" .
weggli.exe "{$x<_&&($x+$y)<=_;}" .
weggli.exe "{$x<=_&&($x+$y)<=_;}" .
weggli.exe "{$x>_||($x*$y)>_;}" .
weggli.exe "{$x>=_||($x*$y)>_;}" .
weggli.exe "{$x>_||($x*$y)>=_;}" .
weggli.exe "{$x>=_||($x*$y)>=_;}" .
weggli.exe "{$x<_&&($x*$y)<_;}" .
weggli.exe "{$x<=_&&($x*$y)<_;}" .
weggli.exe "{$x<_&&($x*$y)<=_;}" .
weggli.exe "{$x<=_&&($x*$y)<=_;}" .
REM `<` should also cover `>` and `<=` should also cover `>=`; however, let"s keep all variants just to be sure.
REM format strings
REM call to printf(), scanf(), syslog() family functions (CWE-134)
weggli.exe -R "func=(printf|scanf|syslog)$" "{$func();}" .
REM Some possible variants: printk, warn, vwarn, warnx, vwarnx, err, verr, errx, verrx, warnc, vwarnc, errc, verrc, etc.
REM memory management
REM call to alloca() (CWE-676, CWE-1325)
weggli.exe -R "func=alloca$" "{$func();}" .
REM use after free (CWE-416)
weggli.exe "{free($ptr); not:$ptr=_; not:free($ptr); _($ptr);}" .
REM double free (CWE-415)
weggli.exe "{free($ptr); not:$ptr=_; free($ptr);}" .
REM calling free() on memory not allocated in the heap (CWE-590)
weggli.exe "{_ $ptr[]; free($ptr);}" .
weggli.exe "{_ $ptr[]=_; free($ptr);}" .
weggli.exe "{_ $ptr[]; $ptr2=$ptr; free($ptr2);}" .
weggli.exe "{_ $ptr[]=_; $ptr2=$ptr; free($ptr2);}" .
weggli.exe "{_ $var; free(&$var);}" .
weggli.exe "{_ $var=_; free(&$var);}" .
weggli.exe "{_ $var[]; free(&$var);}" .
weggli.exe "{_ $var[]=_; free(&$var);}" .
weggli.exe "{_ *$var; free(&$var);}" .
weggli.exe "{_ *$var=_; free(&$var);}" .
weggli.exe "{$ptr=alloca(_); free($ptr);}" .
REM returning the address of a stack-allocated variable (CWE-562)
weggli.exe "{_ $ptr[]; return $ptr;}" .
weggli.exe "{_ $ptr[]=_; return $ptr;}" .
weggli.exe "{_ $ptr[]; $ptr2=$ptr; return $ptr2;}" .
weggli.exe "{_ $ptr[]=_; $ptr2=$ptr; return $ptr2;}" .
weggli.exe "{_ $var; return &$var;}" .
weggli.exe "{_ $var=_; return &$var;}" .
weggli.exe "{_ $var[]; return &$var;}" .
weggli.exe "{_ $var[]=_; return &$var;}" .
weggli.exe "{_ *$var; return &$var;}" .
weggli.exe "{_ *$var=_; return &$var;}" .
REM unchecked return code of malloc(), etc. (CWE-252, CWE-690)
weggli.exe -R "func=allocf?$" "{$ret=$func(); not:if(_($ret)){};}" .
REM call to putenv() with a stack-allocated variable (CWE-686)
weggli.exe "{_ $ptr[]; putenv($ptr);}" .
weggli.exe "{_ $ptr[]=_; putenv($ptr);}" .
weggli.exe "{_ $ptr[]; $ptr2=$ptr; putenv($ptr2);}" .
weggli.exe "{_ $ptr[]=_; $ptr2=$ptr; putenv($ptr2);}" .
REM exposure of underlying memory addresses (CWE-200, CWE-209, CWE-497)
weggli.exe -R "func=printf$" -R "fmt=(.*%\w*x.*|.*%\w*X.*|.*%\w*p.*)" "{$func("$fmt");}" .
REM mismatched memory management routines (CWE-762)
weggli.exe -R "func=allocf?$|strdn?up$" "{not:$ptr=$func(); free($ptr);}" .
weggli.exe --cpp -R "func=allocf?$|strn?dup$" "{not:$ptr=$func(); free($ptr);}" .
weggli.exe --cpp "{not:$ptr=new $obj; delete $ptr;}" .
REM Apparently, delete[] is not supported so this won"t work properly:
weggli.exe --cpp "{not:$ptr=new $obj[$len]; delete[] $ptr;}" .
REM use of uninitialized pointers (CWE-457, CWE-824, CWE-908)
weggli.exe "{_* $ptr; not:$ptr=_; not:_(&$ptr); $func($ptr);}" .
weggli.exe "{_* $ptr; not:$ptr=_; not:_(&$ptr); _($ptr);}" .
REM These patterns might generate many false positives that should be manually investigated.
REM command injection
REM call to system(), popen() (CWE-78, CWE-88, CWE-676)
weggli.exe -R "func=(system|popen)$" "{$func();}" .
weggli.exe -R "func=(system|popen)$" "{$func($arg);}" .
REM The second pattern is meant to filter out string literals, but it might cause some false negatives.
REM race conditions
REM call to access(), stat(), lstat() (CWE-367)
weggli.exe -R "func=(access|l?stat)$" "{$func();}" .
REM call to mktemp(), tmpnam(), tempnam() (CWE-377)
weggli.exe -R "func=(mktemp|te?mpnam)$" "{$func();}" .
REM call to signal() (CWE-364, CWE-479, CWE-828)
weggli.exe -R "func=signal$" "{$func();}" .
REM privilege management
REM privilege management functions called in the wrong order (CWE-696)
weggli.exe "{not:setuid(0); setuid(); setgid();}" .
weggli.exe "{not:seteuid(0); seteuid(); not:seteuid(0); setegid();}" .
weggli.exe "{not:seteuid(0); seteuid(); not:seteuid(0); setuid();}" .
weggli.exe "{not:seteuid(0); seteuid(); not:seteuid(0); seteuid();}" .
REM unchecked return code of setuid(), seteuid() (CWE-252)
weggli.exe -R "func=sete?uid$" "{strict:$func();}" .
REM miscellaneous
REM wrong order of arguments in call to memset()
weggli.exe -R "func=memset(_explicit)?$" "{$func(_,_,0);}" .
weggli.exe -R "func=memset(_explicit)?$" "{$func(_,sizeof(_),_);}" .
REM call to rand(), srand() (CWE-330, CWE-338)
weggli.exe -R "func=s?rand$" "{$func();}" .
REM source and destination overlap in sprintf(), snprintf()
weggli.exe -R "func=^sn?printf$" "{$func($dst,_,$dst);}" .
weggli.exe -R "func=^sn?printf$" "{$func($dst,_,_,$dst);}" .
weggli.exe -R "func=^sn?printf$" "{$func($dst,_,_,_,$dst);}" .
REM And so on...
REM size check implemented with an assertion macro
weggli.exe -R "assert=(?i)^\w*assert\w*\s*$" "{$assert(_<_);}" .
weggli.exe -R "assert=(?i)^\w*assert\w*\s*$" "{$assert(_<=_);}" .
weggli.exe -R "assert=(?i)^\w*assert\w*\s*$" "{$assert(_>_);}" .
weggli.exe -R "assert=(?i)^\w*assert\w*\s*$" "{$assert(_>=_);}" .
REM `<` should also cover `>` and `<=` should also cover `>=`; however, let"s keep all variants just to be sure.
REM unchecked return code of scanf(), etc. (CWE-252)
weggli.exe -R "func=scanf$" "{strict:$func();}" .
REM call to atoi(), atol(), atof(), atoll()
weggli.exe -R "func=ato(i|ll?|f)$" "{$func();}" .
REM command-line argument or environment variable access
weggli.exe -R "var=argv|envp" "{$var[_];}" .
REM missing default case in a switch construct (CWE-478)
weggli.exe -l "switch(_) {_; not:default:_; _;}" .
REM `-l` might be overkill and lead to missing additional matches in the same function.
REM missing break or equivalent statement in a switch construct (CWE-484)
weggli.exe -l "switch(_) {case _: not:break; not:exit; not:return; not:goto _; case _:_;}" .
REM `-l` might be overkill and lead to missing additional matches in the same function.
REM missing return statement in a non-void function (CWE-393, CWE-394)
weggli.exe -R "type!=void" "$type $func(_) {_; not:return;}" .
REM typos with security implications (CWE-480, CWE-481, CWE-482, CWE-483)
weggli.exe "{for (_==_;_;_) {}}" .
weggli.exe "if (_=_) {}" .
weggli.exe "if (_&_) {}" .
weggli.exe "if (_|_) {}" .
weggli.exe "{_=+_;}" .
weggli.exe "{_=-_;}" .
weggli.exe -R "func=strn?cpy$" "if ($func()==_) {}" .
REM There are many possible additional patterns in this category...
REM keywords that suggest the presence of bugs
weggli.exe -R "pattern=(?i)(unsafe|insecure|dangerous|warning|overflow)" "$pattern" .
weggli.exe -R "func=(?i)(encode|decode|convert|interpret|compress|fragment|reassemble)" "_ $func(_) {}" .
weggli.exe -R "func=(?i)(mutex|lock|toctou|parallelism|semaphore|retain|release|garbage|mutual)" "_ $func(_) {}" .
REM There are many possible additional patterns in this category...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment