CodeQL analyzes functions in Python code 3-python

preface

We have learned the basic syntax of QL and can simply query the problem. But for a specific language, we still can't clearly describe its project code on our current basis.

For example, we want to get the possible SSTI vulnerabilities in the flash web application written in python

from flask import Flask
from flask import request
from flask import config
from flask import render_template_string
app = Flask(__name__)

app.config['SECRET_KEY'] = "flag{SSTI_123456}"
@app.route('/')
def hello_world():
    return 'Hello World!'

@app.errorhandler(404)
def page_not_found(e):
    template = '''
{%% block body %%}
    <div class="center-content error">
        <h1>Oops! That page doesn't exist.</h1>
        <h3>%s</h3>
    </div> 
{%% endblock %%}
''' % (request.args.get('404_url'))
    return render_template_string(template), 404

if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)

As you can see here, we need to check whether there is a request in the code args. Get () and track the parameters 404 obtained in this way_ Whether the URL has been filtered in the subsequent process, or whether there is an equation 405_test=404_url+"test code", resulting in 405_ The test parameter is actually contaminated. Finally, see whether these parameters echo render_template_string() to the page.

The whole process needs to consider the running process of parameters in the code, so the traditional regular expression matching sensitive characters is stretched in this case.

Therefore, we also need to learn the relevant basic knowledge of codeql querying python code, such as python expressions, parameters, functions, etc., so that we can draw inferences from one instance in our independent audit.

Official tutorial link: https://codeql.github.com/docs/codeql-language-guides/codeql-for-python/

Of course, codeql also supports queries in other languages. The link is:
https://codeql.github.com/docs/codeql-language-guides/

Functions in python

We can use the syntax classes in the CodeQL standard library to find python functions and identify calls to them

Find all named "get..." Function of

In this example, we look for all getter accessors in a project. When we migrate from java to python, we usually write a large number of getter accessors and setter generator methods instead of using their class properties. Sometimes we need to find these methods. At this time, we should use the member predicate function Getname() to find all getter functions in the QL database

Many times, you can type the code by yourself instead of directly copying and querying to deepen your memory.

import python 
from Function f 
where f.getName().matches("get%")
select f,"this is a func called get..."

Here, it is similar to match ing the regular expression in the re library. The rule get% represents the string starting with get, and% represents wildcard here, representing other characters

You can see the matching results as follows

Find all named "get..." Method of

But obviously, in this example

The result is not a class method, but a simple function. Since we are only interested in methods, we can use function Ismethod() predicate to improve query

import python 
from Function f 
where f.getName().matches("get%") and f.isMethod()
select f,"this is a method called get..."

Now the matching result is the method starting with get

Found a file named "get..." One line method

We can further modify the query so that there is only one line in the function returned (why there is only one line is determined by our needs. Find the getter accessor in the project, and the accessor will only return one line. Modify the QL query code according to this feature). Therefore, we need to count the number of code lines in each method returned to meet our needs

import python 
from Function f 
where f.getName().matches("get%") and f.isMethod() and count( f.getAStmt() )=1
select f,"This function is (probably) a getter."

Although the results have been further screened, many of them are still not the results we want, indicating that there is still room for improvement

This is the right result

This is the wrong result

Find calls to specific functions

When there is eval in the code, if the parameters are controllable, it is likely to lead to code execution vulnerabilities. The following example is used to detect the existence of eval in the code

import python
from Call call,Name name
where call.getFunc()=name and name.getId()="eval"
select call,"call to 'eval'"

In the above code, Call getFunc()=name and name. getId() = "Eval" indicates that the name of the called function is eval. In addition, the Call class indicates the Call of python program, while the predicate getfunc() is used to obtain the called expression, and the predicate getId() is used to obtain the identifier (string) of the name expression

Check the results. Here is the typical code execution and echo vulnerability Code:

@app.route('/command')
def command():
    if request.values.get('cmd'):
        sys.stdout = io.StringIO()
        cmd = request.values.get('cmd')
        return Response('<p>The value entered is:%s</p>' %str(eval(cmd)))  
    else:
        return Response('<p>Please enter cmd value</p>')

Due to the dynamic nature of python, the query will return an eval(...) All calls to the built-in function Eval, whether it is a call to the built-in function Eval or not, in the later tutorial, we will introduce how to use the type inference library to find the call to the built-in function Eval, rather than simply matching the variable name of the call

END

A WeChat safety exchange group was built. Welcome to add WeChat notes to the group, chat with us, and a official account that will publish security related content. Welcome to the attention. 😃

Added by ttroutmpr on Sat, 29 Jan 2022 15:39:09 +0200