Skip to content

Commit

Permalink
Merge pull request #146 from LoRexxar/develop
Browse files Browse the repository at this point in the history
update 2.3.0
  • Loading branch information
LoRexxar authored Jun 21, 2021
2 parents 34765ff + cac445e commit f131a27
Show file tree
Hide file tree
Showing 28 changed files with 569 additions and 51 deletions.
6 changes: 5 additions & 1 deletion Kunlun_M/settings.py.bak
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'web.index',
'web.dashboard',
'web.backend'
'web.backend',
'web.api',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -191,3 +192,6 @@ elif "Linux" in platform_pack.system():
PLATFORM = "linux"
elif "Darwin" in platform_pack.system():
PLATFORM = "mac"

# api profile
API_TOKEN = "secret_api_token"
3 changes: 2 additions & 1 deletion Kunlun_M/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

urlpatterns = [
path('', include('web.index.urls')),
path('api/', include('web.api.urls')),
path('dashboard/', include('web.dashboard.urls')),
path('backend/', include('web.backend.urls')),
] + static(settings.STATIC_URL,document_root=settings.STATICFILES_DIRS[0])
] + static(settings.STATIC_URL, document_root=settings.STATICFILES_DIRS[0])
53 changes: 39 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ cp Kunlun_M/settings.py.bak Kunlun_M/settings.py
python kunlun.py init
```

### docker安装

通过docker安装,默认启动web模式

```
sudo docker build -t kunlun-m -f ./docker/Dockerfile .
```

配合链接同Mysql可以实现本地扫描,web端查看结果。

## Usage

### cli mode
Expand Down Expand Up @@ -165,6 +175,35 @@ python3 kunlun.py show tamper # 展示所有的tamper

使用不同子模式的-h可以查看详细的帮助文档。


### web mode
KunLun-M Dashbroad,并且允许通过apitoken来访问api获取数据

默认9999端口
```
python3 .\kunlun.py web 9999
```

![](docs/web.png)

修改`KunLun-M/settings.py`中的api-token,通过?token={api_token}访问api获取数据
```
# api profile
API_TOKEN = "secret_api_token"
```

Api List
```
task/list 查看task列表
task/<int:task_id> 查看task详细信息
task/<int:task_id>/result 查看task扫描结果
task/<int:task_id>/resultflow 查看task扫描结果流
task/<int:task_id>/newevilfunc 查看task扫描后生成的新恶意函数
rule/list 查看规则列表
rule/<int:rule_id> 查看规则细节
```

### console mode

**建议使用console模式**
Expand Down Expand Up @@ -208,20 +247,6 @@ KunLun-M (root) >

[![asciicast](https://asciinema.org/a/360845.svg)](https://asciinema.org/a/360845)

### web mode
KunLun-M Dashbroad

删除了相关的动态操作,仅保留了查看扫描结果日志等功能(不建议使用

默认9999端口
```
python3 .\kunlun.py web 9999
```


![](docs/web.png)


### plugin mode

#### phpunserializechain
Expand Down
30 changes: 22 additions & 8 deletions core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import traceback

from django.core.management import call_command
from utils.log import log, logger, log_add
from utils.log import log, logger, log_add, log_rm
from utils.utils import get_mainstr_from_filename, get_scan_id
from utils.file import load_kunlunmignore

Expand Down Expand Up @@ -68,8 +68,16 @@ def main():
parser_group_scan.add_argument('-lan', '--language', dest='language', action='store', default=None, help='set target language')
parser_group_scan.add_argument('-b', '--blackpath', dest='black_path', action='store', default=None, help='black path list')

# for api
parser_group_scan.add_argument('-a', '--api', dest='api', action='store_true', default=False,
help='without any output for shell')
parser_group_scan.add_argument('-y', '--yes', dest='yes', action='store_true', default=False,
help='without any output for shell')

# for log
parser_group_scan.add_argument('-d', '--debug', dest='debug', action='store_true', default=False, help='open debug mode')

# for scan profile
parser_group_scan.add_argument('-uc', '--unconfirm', dest='unconfirm', action='store_true', default=False, help='show unconfirmed vuls')
parser_group_scan.add_argument('-upc', '--unprecom', dest='unprecom', action='store_true', default=False, help='without Precompiled')

Expand Down Expand Up @@ -124,7 +132,6 @@ def main():

if hasattr(args, "debug") and args.debug:
logger.setLevel(logging.DEBUG)
logger.debug('[INIT] set logging level: debug')

if hasattr(args, "init"):
logger.info('Init Database for KunLun-M.')
Expand Down Expand Up @@ -199,19 +206,30 @@ def main():
parser.print_help()
exit()

# for api colse log
if hasattr(args, "api") and args.api:
log_rm()

logger.debug('[INIT] start Scan Task...')
logger.debug('[INIT] set logging level: {}'.format(logger.level))

# new scan task
task_name = get_mainstr_from_filename(args.target)
s = cli.check_scantask(task_name=task_name, target_path=args.target, parameter_config=sys.argv)
s = cli.check_scantask(task_name=task_name, target_path=args.target, parameter_config=sys.argv, auto_yes=args.yes)

if s.is_finished:
logger.info("[INIT] Finished Task.")
exit()

# 标识任务id
sid = str(s.id)
get_scan_id()
task_id = get_scan_id()

# for api
if hasattr(args, "api") and args.api:
print("TaskID: {}".format(task_id))
else:
logger.info("TaskID: {}".format(task_id))

if hasattr(args, "log") and args.log:
logger.info("[INIT] New Log file {}.log .".format(args.log))
Expand All @@ -220,10 +238,6 @@ def main():
logger.info("[INIT] New Log file ScanTask_{}.log .".format(sid))
log_add(logging.INFO, "ScanTask_{}".format(sid))

if hasattr(args, "debug") and args.debug:
logger.setLevel(logging.DEBUG)
logger.debug('[INIT] set logging level: debug')

data = {
'status': 'running',
'report': ''
Expand Down
2 changes: 1 addition & 1 deletion core/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__issue_page__ = 'https://github.com/LoRexxar/Kunlun-M/issues/new'
__python_version__ = sys.version.split()[0]
__platform__ = platform.platform()
__version__ = '2.1'
__version__ = '2.3.0'
__author__ = 'LoRexxar'
__author_email__ = 'LoRexxar@gmail.com'
__license__ = 'MIT License'
Expand Down
4 changes: 2 additions & 2 deletions core/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ def get_sid(target, is_a_sid=False):
return sid.lower()


def check_scantask(task_name, target_path, parameter_config):
def check_scantask(task_name, target_path, parameter_config, auto_yes=False):
s = ScanTask.objects.filter(task_name=task_name, target_path=target_path, parameter_config=parameter_config, is_finished=1).order_by("-id").first()

if s:
if s and not auto_yes:
logger.warning("[INIT] ScanTask for {} has been executed.".format(task_name))
logger.warning("[INIT] whether rescan Task {}?(Y/N) (Default N)".format(task_name))

Expand Down
5 changes: 4 additions & 1 deletion core/plugins/phpunserializechain/dataflowgenerate.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,12 @@ def get_node_nodes(self, node):
if type(node) is list:
return node

if isinstance(node, php.Block):
elif isinstance(node, php.Block):
result_nodes = node.nodes

else:
result_nodes = [node]

return result_nodes

def get_binaryop_name(self, node, base_locate, now_sort):
Expand Down
23 changes: 18 additions & 5 deletions core/plugins/phpunserializechain/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def __init__(self, *args, **kwargs):
def main(self):

self.get_destruct()
# self.get_any_methodcall("YvGvAn", (), isnew=True)

def get_destruct(self):

Expand Down Expand Up @@ -257,7 +258,7 @@ def get___callStatic(self, var_name, call_params, unserchain=[], define_param=()

return False

def get_any_methodcall(self, method_name, call_params, unserchain=[], define_param=(), deepth=0):
def get_any_methodcall(self, method_name, call_params, unserchain=[], define_param=(), deepth=0, isnew=False):
"""
可以调用任意类的某个方法,跟踪分析
:param method_name:
Expand Down Expand Up @@ -291,8 +292,19 @@ def get_any_methodcall(self, method_name, call_params, unserchain=[], define_par
deepth=deepth)

if status:
unserchain.extend(newunserchain)
return True
if isnew:
logger.info(
"[PhpUnSerChain] New Source {}{} in {}".format(method_node_name, node.sink_node, node.node_locate))

for unsernode in unserchain:
logger.info("{}".format(unsernode.node_locate.ljust(100, ' ')))
logger_console.warn(
"{} {}{}".format(unsernode.node_type.ljust(30, ' '), unsernode.source_node,
self.deep_get_node_name(unsernode.sink_node)))
logger.info("[PhpUnSerChain] UnSerChain is available.")
else:
unserchain.extend(newunserchain)
return True

return False

Expand Down Expand Up @@ -409,9 +421,10 @@ def check_danger_sink(self, node):
}

if node.node_type == 'FunctionCall' and node.source_node in self.danger_function:
sink_node = eval(node.sink_node)
sink_node = eval(node.sink_node) if node.sink_node.startswith('(') else (node.sink_node)

if len(sink_node) >= len(self.danger_function[node.source_node]):

# 必须有更多参数
for i in self.danger_function[node.source_node]:
if self.check_param_controllable(sink_node[i], node):
Expand Down Expand Up @@ -656,7 +669,7 @@ def deep_search_chain(self, nodes, class_locate, unserchain=[], define_param=(),
:return:
"""

if deepth > 10:
if deepth > 40:
logger.warn("[PhpUnSerChain] Too much deepth. return.")
return False

Expand Down
48 changes: 48 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
FROM ubuntu:20.04

LABEL maintainer="LoRexxar <guoyinqi@xiaomi.com>"

RUN sed -i "s/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list && sed -i "s/archive.ubuntu.com/ubuntu/g" /etc/apt/sources.list

# Set the locale
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

RUN apt-get update \
&& apt-get install -y vim inetutils-ping curl ssh zip python3 python3-pip gunicorn

# python换源
RUN mkdir /root/.pip
RUN /bin/bash -c "echo -e '[global]\nindex-url = https://pypi.tuna.tsinghua.edu.cn/simple' > /root/.pip/pip.conf"
RUN cat /root/.pip/pip.conf

# mysql
RUN apt-get install -y libmysqlclient-dev

# nginx
RUN apt-get install -y nginx

# install
COPY ./ /home/kunlun-m
WORKDIR /home/kunlun-m

RUN python3 -m pip install -r requirements.txt
RUN cp Kunlun_M/settings.py.bak Kunlun_M/settings.py

RUN python3 kunlun.py init

# nginx config
COPY /docker/nginx.conf /etc/nginx/
RUN mkdir /data && mkdir /data/log
RUN /etc/init.d/nginx start

RUN python3 -m pip install supervisor

COPY /docker/supervisord.conf /etc/
RUN /usr/local/bin/supervisord && /usr/local/bin/supervisorctl start all

ENTRYPOINT ["/usr/local/bin/supervisord", "-n", "&&", "/usr/local/bin/supervisorctl", "start", "all"]

EXPOSE 80
64 changes: 64 additions & 0 deletions docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
worker_connections 1024;
}


http {
include mime.types;
default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#gzip on;

server {
listen 80;
server_name localhost ;

access_log /data/log/nginx-access.log;
error_log /data/log/nginx-error.log;

keepalive_timeout 3600;
client_max_body_size 5120M;

location /static/ {
alias /home/kunlun-m/static;
}

location / {
include uwsgi_params;
add_header Access-Control-Allow-Origin *;
proxy_set_header Host $http_host;
proxy_set_header X-Forward-HOST $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_connect_timeout 3800s;
proxy_read_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://127.0.0.1:8000;
}
}

}
Loading

0 comments on commit f131a27

Please sign in to comment.