def test_normal(scan_plugin_fixture):

    plugin_ins = scan_plugin_fixture

    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1", 
            "port": 8005
        }, 
        "context": {
            "requestId": "vuln", 
            "json": { }, 
            "server": {
                "language": "php", 
                "name": "PHP", 
                "version": "7.2.19", 
                "os": "Linux"
            }, 
            "body": "", 
            "appBasePath": "/var/www/html", 
            "remoteAddr": "172.17.0.1", 
            "protocol": "http", 
            "method": "get", 
            "querystring": "test=<?xml", 
            "path": "/011-ssrf-curl.php", 
            "parameter": {
                "test": [
                    "<?xml"
                ]
            }, 
            "header": {
                "host": "localburp.com:8005", 
                "connection": "keep-alive", 
                "upgrade-insecure-requests": "1", 
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36", 
                "dnt": "1", 
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
                "accept-encoding": "gzip, deflate", 
                "accept-language": "zh-CN,zh;q=0.9"
            }, 
            "url": "http://localburp.com:8005/011-ssrf-curl.php?test=xml", 
            "nic": [
                {
                    "name": "eth0", 
                    "ip": "172.17.0.2"
                }
            ], 
            "hostname": "server_host_name"
        }, 
        "hook_info": [
            
        ]
    }
    """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    plugin_ins.has_report = False
    asyncio.run(plugin_ins._scan(rasp_result_ins))
    assert plugin_ins.has_report == True
Example #2
0
 async def post(self):
     """
     处理POST请求
     """
     try:
         data = self.request.body
         headers = self.request.headers
         content_type = self.request.headers.get("Content-Type", "None")
         if not content_type.startswith("application/json"):
             raise exceptions.ContentTypeInvalid
         Logger().info("Received request data: " + data.decode('utf-8'))
         rasp_result_ins = rasp_result.RaspResult(data)
         if rasp_result_ins.is_scan_result():
             self.send_data(rasp_result_ins)
         else:
             await self.dedup_data(rasp_result_ins)
         self.write('{"status": 0, "msg":"ok"}\n')
     except exceptions.OriExpectedException as e:
         self.write('{"status": 1, "msg":"data invalid"}\n')
         Communicator().increase_value("invalid_data")
         Logger().warning(
             "Invalid data: {} posted to http server, rejected!".format(
                 data))
     except Exception as e:
         Logger().error(
             "Unexpected error occured when process data:{}".format(data),
             exc_info=e)
         self.send_error(500)
     return
Example #3
0
def get_normal_response():
    response = {"status": "200", "headers": {"host": "localhost"}, "body": b""}
    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1", 
            "port": 8005
        }, 
        "context": {
            "requestId": "php2", 
            "json": { }, 
            "server": {
                "language": "php", 
                "name": "PHP", 
                "version": "7.2.19", 
                "os": "Linux"
            }, 
            "body": "", 
            "appBasePath": "/var/www/html", 
            "remoteAddr": "172.17.0.1", 
            "protocol": "http", 
            "method": "get", 
            "querystring": "test_param=../../../../etc", 
            "path": "/test-file.php", 
            "parameter": {
                "test_param": [
                    "../../../../etc"
                ]
            }, 
            "header": {
                "host": "localburp.com:8005", 
                "connection": "keep-alive", 
                "upgrade-insecure-requests": "1", 
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36", 
                "dnt": "1", 
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
                "accept-encoding": "gzip, deflate", 
                "accept-language": "zh-CN,zh;q=0.9"
            }, 
            "url": "http://localburp.com:8005/test-file.php?test_param=../../../../etc", 
            "nic": [
                {
                    "name": "eth0", 
                    "ip": "172.17.0.2"
                }
            ], 
            "hostname": "server_host_name"
        }, 
        "hook_info": [ ]
    }
     """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    result = {
        "scan_req_id": "0-a71e0906-88f6-412a-8bbe-efa94737e5c9",
        "response": response,
        "rasp_result": rasp_result_ins
    }
    return result
    async def get_new_scan(self, count=1):
        """
        获取多条未扫描的请求数据

        Parameters:
            count - 最大获取条数,默认为1

        Returns:
            获取的数据组成的list,每个item为一个dict, [{id:数据id, data:请求数据的json字符串} ... ]

        Raises:
            exceptions.DatabaseError - 数据库错误引发此异常
        """
        result = []
        try:
            # 获取未扫描的最小id
            query = self.ResultList.select(peewee.fn.MIN(
                self.ResultList.id)).where((self.ResultList.id > self.start_id)
                                           &
                                           (self.ResultList.scan_status == 0))
            fetch_star_id = await peewee_async.scalar(query)
            if fetch_star_id is None:
                return []

            # 将要获取的记录标记为扫描中
            query = self.ResultList.update({
                self.ResultList.scan_status: 2
            }).where((self.ResultList.scan_status == 0)
                     & (self.ResultList.id > self.start_id)).order_by(
                         self.ResultList.id).limit(count)

            row_count = await peewee_async.execute(query)
            if (row_count == 0):
                return result

            # 获取标记的记录
            query = self.ResultList.select().where(
                (self.ResultList.id >= fetch_star_id)
                & (self.ResultList.scan_status == 2)).order_by(
                    self.ResultList.id).limit(row_count)

            data = await peewee_async.execute(query)

            for line in data:
                result.append({
                    "id": line.id,
                    "data": rasp_result.RaspResult(line.data)
                })
            return result

        except asyncio.CancelledError as e:
            raise e
        except Exception as e:
            Logger().critical("Database error in get_new_scan method!",
                              exc_info=e)
            raise exceptions.DatabaseError
    async def get_urls(self, page=1, status=0):
        """
        获取指定状态的的url列表

        Parameters:
            page - int, 获取的页数,每页10条
            status - int, url的状态 未扫描:0, 已扫描:1, 正在扫描:2, 扫描中出现错误: 3

        Returns:
            total, urls - total为数据总数, int类型,urls为已扫描的url, list类型, item形式为tuple (url对应id, url字符串)

        Raises:
            exceptions.DatabaseError - 数据库错误引发此异常
        """
        if page <= 0:
            page = 1
        try:
            query = self.ResultList.select(peewee.fn.COUNT(
                self.ResultList.id)).where(
                    self.ResultList.scan_status == status)

            result = await peewee_async.scalar(query)
            if result is None:
                total = 0
            else:
                total = result

            query = self.ResultList.select().where(
                self.ResultList.scan_status == status).order_by(
                    self.ResultList.id).offset((page - 1) * 10).limit(10)

            data = await peewee_async.execute(query)
            urls = []

            for line in data:
                url_id = line.id
                rasp_result_ins = rasp_result.RaspResult(line.data)
                url = rasp_result_ins.get_url()
                urls.append((url_id, url))
            return total, urls

        except asyncio.CancelledError as e:
            raise e
        except Exception as e:
            Logger().critical("Database error in mark_result method!",
                              exc_info=e)
            raise exceptions.DatabaseError
def get_vuln_response():
    response = {
        "status": "200",
        "headers": {"host": "localhost"},
        "body": b""
    }

    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1", 
            "port": 8005
        }, 
        "context": {
           "requestId": "vuln", 
            "json": { }, 
            "server": {
                "language": "php", 
                "name": "PHP", 
                "version": "7.2.19", 
                "os": "Linux"
            }, 
            "body": "", 
            "appBasePath": "/var/www/html", 
            "remoteAddr": "172.17.0.1", 
            "protocol": "http", 
            "method": "get", 
            "querystring": "test_param=123456", 
            "path": "/test-file.php", 
            "parameter": {
                "test_param": [
                    "1'openrasp"
                ]
            }, 
            "header": {
                "host": "localburp.com:8005", 
                "connection": "keep-alive", 
                "upgrade-insecure-requests": "1", 
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36", 
                "dnt": "1", 
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
                "accept-encoding": "gzip, deflate", 
                "accept-language": "zh-CN,zh;q=0.9"
            }, 
            "url": "http://localburp.com:8005/test-file.php?test_param=123456", 
            "nic": [
                {
                    "name": "eth0", 
                    "ip": "172.17.0.2"
                }
            ], 
            "hostname": "server_host_name"
        }, 
        "hook_info": [
            {
                "query": "SELECT id, name FROM vuln WHERE id = 1'openrasp", 
                "server": "mysql", 
                "tokens": [
                    {
                        "start": 0, 
                        "stop": 6, 
                        "text": "SELECT"
                    }, 
                    {
                        "start": 7, 
                        "stop": 9, 
                        "text": "id"
                    }, 
                    {
                        "start": 9, 
                        "stop": 10, 
                        "text": ","
                    }, 
                    {
                        "start": 11, 
                        "stop": 15, 
                        "text": "name"
                    }, 
                    {
                        "start": 16, 
                        "stop": 20, 
                        "text": "FROM"
                    }, 
                    {
                        "start": 21, 
                        "stop": 25, 
                        "text": "vuln"
                    }, 
                    {
                        "start": 26, 
                        "stop": 31, 
                        "text": "WHERE"
                    }, 
                    {
                        "start": 32, 
                        "stop": 34, 
                        "text": "id"
                    }, 
                    {
                        "start": 35, 
                        "stop": 36, 
                        "text": "="
                    }, 
                    {
                        "start": 37, 
                        "stop": 38, 
                        "text": "1"
                    }, 
                    {
                        "start": 38, 
                        "stop": 39, 
                        "text": "'"
                    }, 
                    {
                        "start": 39, 
                        "stop": 47, 
                        "text": "openrasp"
                    }
                ], 
                "hook_type": "sql"
            }
        ]
    }
    """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    result = {
        "response": response,
        "rasp_result": rasp_result_ins
    }
    return result
def test_normal(scan_plugin_fixture):

    plugin_ins = scan_plugin_fixture

    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1",
            "port": 8005
        },
        "context": {
            "requestId": "php1",
            "json": { },
            "server": {
                "language": "php",
                "name": "PHP",
                "version": "7.2.19",
                "os": "Linux"
            },
            "body": "",
            "appBasePath": "/var/www/html",
            "remoteAddr": "172.17.0.1",
            "protocol": "http",
            "method": "post",
            "querystring": "",
            "path": "/upload/upload.php",
            "parameter": {
                "submit": [
                    "Submit"
                ]
            },
            "header": {
                "host": "127.0.0.1:8005",
                "connection": "keep-alive",
                "content-length": "5566",
                "cache-control": "max-age=0",
                "origin": "http://127.0.0.1:8005",
                "upgrade-insecure-requests": "1",
                "dnt": "1",
                "content-type": "multipart/form-data; boundary=----WebKitFormBoundary484mhkVOXGBTS5jZ",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
                "referer": "http://127.0.0.1:8005/upload/upload.html",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "zh-CN,zh;q=0.9"
            },
            "url": "http://127.0.0.1:8005/upload/upload.php",
            "nic": [
                {
                    "name": "eth0",
                    "ip": "172.17.0.2"
                }
            ],
            "hostname": "server_host_name"
        },
        "hook_info": [
            {
                "name": "file",
                "filename": "test.txt",
                "content": "12345",
                "dest_path":     "/var/www/html/upload/openrasp.php",
                "dest_realpath": "/var/www/html/upload/openrasp.php",
                "hook_type": "fileUpload"
            },
            {
                "path": "/write/file",
                "realpath": "/write/file",
                "stack": [
                    "/var/www/html/writeFile.php@system"
                ],
                "hook_type": "writeFile"
            }
        ]
    }
    """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    plugin_ins.has_report = False
    asyncio.run(plugin_ins._scan(0, rasp_result_ins))
    assert plugin_ins.has_report is True
Example #8
0
def get_vuln_response():
    response = {"status": "200", "headers": {"host": "localhost"}, "body": b""}

    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1",
            "port": 8005
        },
        "context": {
            "requestId": "vuln",
            "json": { },
            "server": {
                "language": "php",
                "name": "PHP",
                "version": "7.2.19",
                "os": "Linux"
            },
            "body": "",
            "appBasePath": "/var/www/html",
            "remoteAddr": "172.17.0.1",
            "protocol": "http",
            "method": "get",
            "querystring": "test_param='\\"openrasp' cmd",
            "path": "/test-file.php",
            "parameter": {
                "test_param": [
                    "'\\"openrasp' cmd"
                ]
            },
            "header": {
                "host": "localburp.com:8005",
                "connection": "keep-alive",
                "upgrade-insecure-requests": "1",
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
                "dnt": "1",
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
                "accept-encoding": "gzip, deflate",
                "accept-language": "zh-CN,zh;q=0.9"
            },
            "url": "http://localburp.com:8005/test-file.php?test_param='\\"openrasp' cmd",
            "nic": [
                {
                    "name": "eth0",
                    "ip": "172.17.0.2"
                }
            ],
            "hostname": "server_host_name"
        },
        "hook_info": [
            {
                "command": "/bin/sh -c ''\\"openrasp' cmd'",
                "stack": [
                    "/var/www/html/004-command-2.php@system"
                ],
                "tokens": [
                    { "start": 0, "stop": 7, "text": "/bin/sh" },
                    { "start": 8, "stop": 10, "text": "-c" },
                    { "start": 11, "stop": 13, "text": "''" },
                    { "start": 13, "stop": 14, "text": "\\"" },
                    { "start": 14, "stop": 28, "text": "openrasp' cmd'" }
                ],
                "hook_type": "command"
            }
        ]
    }
    """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    result = {"response": response, "rasp_result": rasp_result_ins}
    return result
Example #9
0
    def _send_report_data(self, data_list):
        headers = {
            "X-OpenRASP-AppSecret": self.app_secret,
            "X-OpenRASP-AppID": self.app_id
        }
        send_data = []
        try:
            for plugin_name, description, data, message, scan_time in data_list:
                # 尚未支持请求序列类型上报
                data = json.loads(data)
                rasp_result_ins = rasp_result.RaspResult(data[0])
                server_info = rasp_result_ins.get_server_info()
                vuln_hook = rasp_result_ins.get_vuln_hook()
                url = rasp_result_ins.get_url()
                if vuln_hook is not None:
                    hook_info = vuln_hook["hook_info"]
                    attack_type = vuln_hook["hook_info"]["hook_type"]
                    stack = vuln_hook.get("stack", [])
                    stack_trace = "\n".join(stack)
                    server_type = server_info.get(
                        "name", server_info.get("server", "None"))

                    req_and_resp = "HTTP Request:\n{}\n\n\nHTTP Response:\n{}".format(
                        rasp_result_ins.get_request(),
                        rasp_result_ins.get_response())
                    if len(req_and_resp) > 2 * 1024 * 1024:
                        req_and_resp = req_and_resp[:2 * 1024 *
                                                    1024] + "\n... {} more chars ...".format(
                                                        len(req_and_resp) -
                                                        2 * 1024 * 1024)
                else:
                    Logger().warning(
                        "Report data with no vuln hook detect, skip upload!")
                    continue
                cloud_format_data = {
                    "rasp_id":
                    "IAST",
                    "app_id":
                    self.app_id,
                    "event_type":
                    "attack",
                    "event_time":
                    time.strftime("%Y-%m-%dT%H:%M:%S%z",
                                  time.localtime(scan_time)),
                    "request_id":
                    rasp_result_ins.get_request_id(),
                    "request_method":
                    rasp_result_ins.get_method(),
                    "intercept_state":
                    "log",
                    "target":
                    rasp_result_ins.get_attack_target(),
                    "server_hostname":
                    rasp_result_ins.get_server_hostname(),
                    "server_ip":
                    rasp_result_ins.get_attack_source(),
                    "server_type":
                    server_type,
                    "server_version":
                    server_info["version"],
                    "server_nic":
                    rasp_result_ins.get_server_nic(),
                    "path":
                    rasp_result_ins.get_path(),
                    "url":
                    url,
                    "attack_type":
                    attack_type,
                    "attack_params":
                    hook_info,
                    "attack_source":
                    rasp_result_ins.get_attack_source(),
                    "client_ip":
                    rasp_result_ins.get_client_ip(),
                    "plugin_name":
                    plugin_name,
                    "plugin_confidence":
                    90,
                    "plugin_message":
                    message,
                    "plugin_algorithm":
                    description,
                    "header":
                    rasp_result_ins.get_headers(),
                    "stack_trace":
                    stack_trace,
                    # "body": base64.b64encode(rasp_result_ins.get_body()).decode("ascii"),
                    "body":
                    req_and_resp
                }
                send_data.append(cloud_format_data)

            send_data = json.dumps(send_data)
            r = requests.post(url=self.server_url,
                              headers=headers,
                              data=send_data)
            response = json.loads(r.text)
            if response["status"] != 0:
                Logger().warning(
                    "Upload report to cloud failed with response: {}".format(
                        r.text))
                return False
            else:
                Logger().debug("Upload report {}!".format(send_data))
                Logger().info("Upload report to cloud success!")
                return True
        except Exception as e:
            Logger().warning("Upload report to cloud failed!", exc_info=e)
            return False
Example #10
0
def get_vuln_response():
    response = {
        "status": "200",
        "headers": {"host": "localhost"},
        "body": b""
    }

    rasp_result_json = """
    {
        "web_server": {
            "host": "127.0.0.1", 
            "port": 8005
        }, 
        "context": {
            "requestId": "vuln", 
            "json": { }, 
            "server": {
                "language": "php", 
                "name": "PHP", 
                "version": "7.2.19", 
                "os": "Linux"
            }, 
            "body": "", 
            "appBasePath": "/var/www/html", 
            "remoteAddr": "172.17.0.1", 
            "protocol": "http", 
            "method": "get", 
            "querystring": "test=xml", 
            "path": "/011-ssrf-curl.php", 
            "parameter": {
                "test": [
                    "test"
                ]
            }, 
            "header": {
                "host": "localburp.com:8005", 
                "connection": "keep-alive", 
                "upgrade-insecure-requests": "1", 
                "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36", 
                "dnt": "1", 
                "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
                "accept-encoding": "gzip, deflate", 
                "accept-language": "zh-CN,zh;q=0.9", 
                "content-length":"",
                "content-type": "application/x-www-form-urlencoded"
            }, 
            "url": "http://localburp.com:8005/011-ssrf-curl.php?test=xml", 
            "nic": [
                {
                    "name": "eth0", 
                    "ip": "172.17.0.2"
                }
            ], 
            "hostname": "server_host_name"
        }, 
        "hook_info": [
            {
                "entity": "file:///etc/passwd", 
                "hook_type": "xxe"
            }
        ]
    }
    """
    rasp_result_ins = rasp_result.RaspResult(rasp_result_json)

    result = {
        "response": response,
        "rasp_result": rasp_result_ins
    }
    return result