Пример #1
0
    def test_override_var(self):
        code = '''
        <?php
            $var1 = $_GET['param'];
            $var1 = 'blah';
            $var2 = escapeshellarg($_GET['param2']);
            $var3 = 'blah';
            if ($x){
                $var3 = $_POST['param2'];
            }
            else{
                $var3 = 'blah'.'blah';
            }
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)

        # 'var1' is safe
        var1 = vars[0]
        self.assertFalse(var1.controlled_by_user)

        # 'var2' is controlled by the user but is safe for OS-Commanding
        var2 = vars[1]
        self.assertTrue(var2.controlled_by_user)
        self.assertFalse(var2.is_tainted_for('OS_COMMANDING'))

        # 'var3' must still be controllable by user
        var3 = vars[2]
        self.assertTrue(var3.controlled_by_user)
Пример #2
0
    def test_override_var(self):
        code = '''
        <?php
            $var1 = $_GET['param'];
            $var1 = 'blah';
            $var2 = escapeshellarg($_GET['param2']);
            $var3 = 'blah';
            if ($x){
                $var3 = $_POST['param2'];
            }
            else{
                $var3 = 'blah'.'blah';
            }
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)

        # 'var1' is safe
        var1 = vars[0]
        self.assertFalse(var1.controlled_by_user)

        # 'var2' is controlled by the user but is safe for OS-Commanding
        var2 = vars[1]
        self.assertTrue(var2.controlled_by_user)
        self.assertFalse(var2.is_tainted_for('OS_COMMANDING'))

        # 'var3' must still be controllable by user
        var3 = vars[2]
        self.assertTrue(var3.controlled_by_user)
Пример #3
0
 def test_vars(self):
     code = '''
         <?
           $foo = $_GET['bar'];
           $spam = $_POST['blah'];
           $eggs = 'blah' . 'blah';
           if ($eggs){
               $xx = 'waka-waka';
               $yy = $foo;
           }
         ?>
         '''
     analyzer = PhpSCA(code)
     # Get all vars
     vars = analyzer.get_vars(usr_controlled=False)
     self.assertEquals(5, len(vars))
     # Get user controlled vars
     usr_cont_vars = analyzer.get_vars(usr_controlled=True)
     self.assertEquals(3, len(usr_cont_vars))
     # Test $foo
     foovar = usr_cont_vars[0]
     self.assertEquals('$foo', foovar.name)
     self.assertTrue(foovar.controlled_by_user)
     self.assertFalse(foovar.is_root)
     self.assertTrue(foovar.parent)
     # Test $spam
     spamvar = usr_cont_vars[1]
     self.assertEquals('$spam', spamvar.name)
     # Test $spam
     yyvar = usr_cont_vars[2]
     self.assertEquals('$yy', yyvar.name)
Пример #4
0
 def test_vars(self):
     code = '''
         <?
           $foo = $_GET['bar'];
           $spam = $_POST['blah'];
           $eggs = 'blah' . 'blah';
           if ($eggs){
               $xx = 'waka-waka';
               $yy = $foo;
           }
         ?>
         '''
     analyzer = PhpSCA(code)
     # Get all vars
     vars = analyzer.get_vars(usr_controlled=False)
     self.assertEquals(5, len(vars))
     # Get user controlled vars
     usr_cont_vars = analyzer.get_vars(usr_controlled=True)
     self.assertEquals(3, len(usr_cont_vars))
     # Test $foo
     foovar = usr_cont_vars[0]
     self.assertEquals('$foo', foovar.name)
     self.assertTrue(foovar.controlled_by_user)
     self.assertFalse(foovar.is_root)
     self.assertTrue(foovar.parent)
     # Test $spam
     spamvar = usr_cont_vars[1]
     self.assertEquals('$spam', spamvar.name)
     # Test $spam
     yyvar = usr_cont_vars[2]
     self.assertEquals('$yy', yyvar.name)
Пример #5
0
    def api_read(self, localtmpdir=None):
        '''
        :param localtmpdir: Local temporary directory where to save
                            the remote code.
        '''
        def write_vuln_to_kb(vulnty, url, funcs):
            vulndata = php_sca.KB_DATA[vulnty]
            for f in funcs:
                vuln_sev = vulndata['severity']
                desc = name = vulndata['name']

                v = Vuln(name, desc, vuln_sev, 1, 'PHP Static Code Analyzer')
                v.set_uri(url)
                v.set_var(f.vulnsources[0])

                args = list(vulndata['kb_key']) + [v]

                # TODO: Extract the method from the PHP code
                #     $_GET == GET
                #     $_POST == POST
                #     $_REQUEST == GET
                v.set_method('GET')

                # TODO: Extract all the other variables that are
                # present in the PHP file using the SCA
                v.set_dc(DataContainer())

                #
                # TODO: This needs to be checked! OS Commanding specific
                #       attributes.
                v['os'] = 'unix'
                v['separator'] = ''

                kb.kb.append(*args)

        if not localtmpdir:
            localtmpdir = tempfile.mkdtemp()

        res = {}
        files = self.exec_payload('get_source_code', args=(localtmpdir, ))

        for url, file in files.iteritems():
            sca = PhpSCA(file=file[1])
            for vulnty, funcs in sca.get_vulns().iteritems():
                # Write to KB
                write_vuln_to_kb(vulnty, url, funcs)
                # Fill res dict
                res.setdefault(vulnty, []).extend([{
                    'loc':
                    url,
                    'lineno':
                    fc.lineno,
                    'funcname':
                    fc.name,
                    'vulnsrc':
                    str(fc.vulnsources[0])
                } for fc in funcs])
        return res
Пример #6
0
 def test_vuln_func_get_sources_1(self):
     code = '''
     <?
         $eggs = $_GET['bar'];
         $foo = func($eggs);
         $a = 'ls ' . $foo;
         exec($a);
     ?>
     '''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'bar' in execfunc.vulnsources)
Пример #7
0
 def test_vuln_func_get_sources_1(self):
     code = '''
     <?
         $eggs = $_GET['bar'];
         $foo = func($eggs);
         $a = 'ls ' . $foo;
         exec($a);
     ?>
     '''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'bar' in execfunc.vulnsources)
Пример #8
0
    def api_read(self, localtmpdir=None):
        '''
        :param localtmpdir: Local temporary directory where to save
                            the remote code.
        '''
        def write_vuln_to_kb(vulnty, url, funcs):
            vulndata = php_sca.KB_DATA[vulnty]
            for f in funcs:
                vuln_sev = vulndata['severity']
                desc = name = vulndata['name']
                
                v = Vuln(name, desc, vuln_sev, 1, 'PHP Static Code Analyzer')
                v.set_uri(url)
                v.set_var(f.vulnsources[0])

                args = list(vulndata['kb_key']) + [v]

                # TODO: Extract the method from the PHP code
                #     $_GET == GET
                #     $_POST == POST
                #     $_REQUEST == GET
                v.set_method('GET')

                # TODO: Extract all the other variables that are
                # present in the PHP file using the SCA
                v.set_dc(DataContainer())

                #
                # TODO: This needs to be checked! OS Commanding specific
                #       attributes.
                v['os'] = 'unix'
                v['separator'] = ''

                kb.kb.append(*args)

        if not localtmpdir:
            localtmpdir = tempfile.mkdtemp()

        res = {}
        files = self.exec_payload('get_source_code', args=(localtmpdir,))

        for url, file in files.iteritems():
            sca = PhpSCA(file=file[1])
            for vulnty, funcs in sca.get_vulns().iteritems():
                # Write to KB
                write_vuln_to_kb(vulnty, url, funcs)
                # Fill res dict
                res.setdefault(vulnty, []).extend(
                    [{'loc': url, 'lineno': fc.lineno, 'funcname': fc.name,
                      'vulnsrc': str(fc.vulnsources[0])} for fc in funcs])
        return res
Пример #9
0
 def test_vuln_functions_3(self):
     code = '''
     <?php
       $var1 = escapeshellarg($_GET['param']);
       system($var1);
       system(escapeshellarg($_GET['param']));
       system(myfunc(escapeshellarg($_GET['param'])));
     ?>
     '''
     analyzer = PhpSCA(code)
     syscall1, syscall2, syscall3 = analyzer.get_func_calls()
     # Both must be SAFE!
     self.assertEquals(0, len(syscall1.vulntypes))
     self.assertEquals(0, len(syscall2.vulntypes))
     self.assertEquals(0, len(syscall3.vulntypes))
Пример #10
0
 def test_vuln_functions_3(self):
     code = '''
     <?php
       $var1 = escapeshellarg($_GET['param']);
       system($var1);
       system(escapeshellarg($_GET['param']));
       system(myfunc(escapeshellarg($_GET['param'])));
     ?>
     '''
     analyzer = PhpSCA(code)
     syscall1, syscall2, syscall3 = analyzer.get_func_calls()
     # Both must be SAFE!
     self.assertEquals(0, len(syscall1.vulntypes))
     self.assertEquals(0, len(syscall2.vulntypes))
     self.assertEquals(0, len(syscall3.vulntypes))
Пример #11
0
    def test_vuln_functions_2(self):
        code = '''
        <?
          $foo = $_GET['bar'];
          system('ls ' . $foo);
          echo file_get_contents($foo);
        ?>
        '''
        analyzer = PhpSCA(code)
        syscall, echocall = analyzer.get_func_calls()
        self.assertTrue('OS_COMMANDING' in syscall.vulntypes)
        self.assertTrue('XSS' in echocall.vulntypes)

        #
        # FIXME: Not sure why this is failing... not important at the moment
        #
        raise SkipTest('FIXME')
        self.assertTrue('FILE_DISCLOSURE' in echocall.vulntypes)
Пример #12
0
    def test_vuln_functions_2(self):
        code = '''
        <?
          $foo = $_GET['bar'];
          system('ls ' . $foo);
          echo file_get_contents($foo);
        ?>
        '''
        analyzer = PhpSCA(code)
        syscall, echocall = analyzer.get_func_calls()
        self.assertTrue('OS_COMMANDING' in syscall.vulntypes)
        self.assertTrue('XSS' in echocall.vulntypes)

        #
        # FIXME: Not sure why this is failing... not important at the moment
        #
        raise SkipTest('FIXME')
        self.assertTrue('FILE_DISCLOSURE' in echocall.vulntypes)
Пример #13
0
 def test_vuln_functions_4(self):
     code = '''
     <?
     $foo = $_GET['foo'];
     if ( $spam == $eggs ){
          $foo = 'ls';
          system($foo);
     }
     else{
          echo $foo;
          system($foo);
     }
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, echo, sys2 = analyzer.get_func_calls()
     self.assertEquals([], sys1.vulntypes)
     self.assertTrue('XSS' in echo.vulntypes)
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
Пример #14
0
 def test_vuln_functions_4(self):
     code = '''
     <?
     $foo = $_GET['foo'];
     if ( $spam == $eggs ){
          $foo = 'ls';
          system($foo);
     }
     else{
          echo $foo;
          system($foo);
     }
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, echo, sys2 = analyzer.get_func_calls()
     self.assertEquals([], sys1.vulntypes)
     self.assertTrue('XSS' in echo.vulntypes)
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
Пример #15
0
 def test_vuln_functions_1(self):
     code = '''
     <?php
       $var = $_GET['bleh'];
       if ($x){
           $var = 2;
           // not vuln!
           system($var);
       }
       // vuln for OS COMMANDING!
       system($var);
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, sys2 = analyzer.get_func_calls()
     # First system call
     self.assertEquals(0, len(sys1.vulntypes))
     # Second system call
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
Пример #16
0
 def test_vuln_functions_1(self):
     code = '''
     <?php
       $var = $_GET['bleh'];
       if ($x){
           $var = 2;
           // not vuln!
           system($var);
       }
       // vuln for OS COMMANDING!
       system($var);
     ?>
     '''
     analyzer = PhpSCA(code)
     sys1, sys2 = analyzer.get_func_calls()
     # First system call
     self.assertEquals(0, len(sys1.vulntypes))
     # Second system call
     self.assertTrue('OS_COMMANDING' in sys2.vulntypes)
Пример #17
0
    def test_var_comp_operators(self):
        code = '''
        <?php
            $var0 = 'bleh';
            $var1 = $_GET['param'];
            $var2 = 'blah';
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)

        code2 = '''
        <?php
            $var0 = 'bleh';

            $var1 = 'blah';
            if ($x){
                $var2 = $_POST['param2'];
            }
            else{
                $var2 = 'blah'.'blah';
            }
        ?>
        '''
        analyzer = PhpSCA(code2)
        vars2 = analyzer.get_vars(usr_controlled=False)

        c1_var0 = vars[0]
        c2_var0 = vars2[0]
        c1_var0._scope = c2_var0._scope
        self.assertTrue(c2_var0 == c1_var0)

        c1_var1 = vars[1]
        c2_var1 = vars2[1]
        c2_var1._scope = c1_var1._scope
        self.assertTrue(c2_var1 > c1_var1)

        c1_var2 = vars[2]
        c2_var2 = vars2[2]
        self.assertTrue(c2_var2 > c1_var2)
Пример #18
0
 def test_vuln_functions_5(self):
     code = '''<?
     $foo = 1;
     if ( $spam == $eggs ){
          $foo = $_GET['foo'];
     }
     else{
          $foo = 1;
     }
     include($foo);
     ?>'''
     inccall = PhpSCA(code).get_func_calls()[0]
     self.assertTrue('FILE_INCLUDE' in inccall.vulntypes)
Пример #19
0
    def test_vars_dependencies(self):
        code = '''
        <?
          $x1 = 'waca-waka';
          $x2 = '#!~?#*' + $x1;
          $x3 = func($x2);
          $y = $_COOKIES['1'];
          $y2 = 'ls ' . $y;
          $z = $x2 + $x3;
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)
        vars.sort(cmp=lambda x, y: cmp(x.lineno, y.lineno))
        x1deps, x2deps, x3deps, ydeps, y2deps, zdeps = \
            [[vd.name for vd in v.deps()] for v in vars]

        self.assertEquals([], x1deps)
        self.assertEquals(['$x1'], x2deps)
        self.assertEquals(['$x2', '$x1'], x3deps)
        self.assertEquals(['$_COOKIES'], ydeps)
        self.assertEquals(['$y', '$_COOKIES'], y2deps)
        self.assertEquals(['$x2', '$x1'], zdeps)
Пример #20
0
    def test_vars_dependencies(self):
        code = '''
        <?
          $x1 = 'waca-waka';
          $x2 = '#!~?#*' + $x1;
          $x3 = func($x2);
          $y = $_COOKIES['1'];
          $y2 = 'ls ' . $y;
          $z = $x2 + $x3;
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)
        vars.sort(cmp=lambda x, y: cmp(x.lineno, y.lineno))
        x1deps, x2deps, x3deps, ydeps, y2deps, zdeps = \
            [[vd.name for vd in v.deps()] for v in vars]

        self.assertEquals([], x1deps)
        self.assertEquals(['$x1'], x2deps)
        self.assertEquals(['$x2', '$x1'], x3deps)
        self.assertEquals(['$_COOKIES'], ydeps)
        self.assertEquals(['$y', '$_COOKIES'], y2deps)
        self.assertEquals(['$x2', '$x1'], zdeps)
Пример #21
0
    def test_var_comp_operators(self):
        code = '''
        <?php
            $var0 = 'bleh';
            $var1 = $_GET['param'];
            $var2 = 'blah';
        ?>
        '''
        analyzer = PhpSCA(code)
        vars = analyzer.get_vars(usr_controlled=False)

        code2 = '''
        <?php
            $var0 = 'bleh';

            $var1 = 'blah';
            if ($x){
                $var2 = $_POST['param2'];
            }
            else{
                $var2 = 'blah'.'blah';
            }
        ?>
        '''
        analyzer = PhpSCA(code2)
        vars2 = analyzer.get_vars(usr_controlled=False)

        c1_var0 = vars[0]
        c2_var0 = vars2[0]
        c1_var0._scope = c2_var0._scope
        self.assertTrue(c2_var0 == c1_var0)

        c1_var1 = vars[1]
        c2_var1 = vars2[1]
        c2_var1._scope = c1_var1._scope
        self.assertTrue(c2_var1 > c1_var1)

        c1_var2 = vars[2]
        c2_var2 = vars2[2]
        self.assertTrue(c2_var2 > c1_var2)
Пример #22
0
 def test_vuln_func_get_sources_2(self):
     code = '''<? echo file_get_contents($_REQUEST['file']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'file' in execfunc.vulnsources)
Пример #23
0
 def test_vuln_func_get_sources_3(self):
     code = '''<? system($_GET['foo']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'foo' in execfunc.vulnsources)
Пример #24
0
 def test_vuln_func_get_sources_2(self):
     code = '''<? echo file_get_contents($_REQUEST['file']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'file' in execfunc.vulnsources)
Пример #25
0
 def test_vuln_func_get_sources_3(self):
     code = '''<? system($_GET['foo']); ?>'''
     analyzer = PhpSCA(code)
     execfunc = analyzer.get_func_calls(vuln=True)[0]
     self.assertTrue(
         len(execfunc.vulnsources) == 1 and 'foo' in execfunc.vulnsources)