U盘文件伪装病毒:从文件夹到快捷方式

2014-07-11 • 技术文章

今天同学拿U盘去打印店打印资料,打开一看,U盘里只有三个快捷方式,不太正常。打开cmd,切换到U盘盘符,执行dir /a来查看全部文件,果然所有正常文件都被隐藏了,有可见的与正常文件同名的快捷方式,还有一个VBS文件是病毒体。

文件夹伪装

之前比较常见的形式是隐藏正常文件夹,并拷贝文件夹图标的可执行文件进去。用户一旦不小心双击文件夹,病毒就得以运行。遇到这种病毒的解决办法是,打开cmd切换到对应盘符,用dir /a看一下U盘里一共有哪些文件,明显不是你存的而是病毒的直接执行del /a filename即可,然后执行attrib -S -H -R * /D /S来恢复正常文件的显示。总体来说,病毒作者还是比较有良心的,没有将原始文件删除,仅仅是隐藏了。

快捷方式

今天碰到的这个病毒不是可执行文件格式,而是一个快捷方式ks.lnk。通过快捷方式的属性可看到其目标如下,是利用cmd去执行对应的VBS脚本,然后再打开正常的目标文件:

1
2
C:\windows\system32\cmd.exe /c start djsiptmqou..vbs&start ks.pdf&exit
# 病毒作者也比较蠢,指定绝对路径,万一人家不是装在这里不就执行不了了?!

问题的关键就在于这个djsiptmqou..vbs,由于其中的代码经过两层加密而且很容易变种,杀毒软件也不好对付,如果之前没见过只能是依赖行为分析。

用文本编辑器打开这个脚本文件,一开始定义的一个字符串超长,根据脚本自带的解密代码先根据某符号将文本切成一个长度为78540的字符串数组并一一使用base64解码然后连接,连接后发现是另一串字符,后面利用executeGlobal来执行。这解密出的字符再根据其尾部自带的解密方法再切分为一个很长的数组并对数组元素一一执行chr()得到对应字符,这样就得到了最终的明文。明文的脚本会遍历文件系统,修改注册表,并远程下载一个可执行文件的病毒,可惜这个病毒的下载地址(域名指向阿尔及利亚的某个IP地址)早就不存在了,可见是个老毒,所以用户也不会受到实质性侵害了。

总结

无论形式如何变化,不管是如何伪装,甚至也不管是何种病毒,总体上来讲病毒发展到2008年前后就已经达到顶峰了,已经深入ring0层,不太可能再有什么大的进步了。现在的杀毒软件也基本上都熟悉了病毒的套路,所以用户也不用太挑三拣四,主流的杀毒软件都可以保护系统安全的。操作系统也越来越安全了,病毒开发者的成本越来越高。所以,我认为病毒接下来会走下坡路,未来网络犯罪会向更高端的漏洞和钓鱼诈骗发展,另外移动端和物联网将成为骇客新的重点攻击对象。

在32位CentOS 6.5下安装Oracle 11g R2

2014-06-27 • 技术文章

准备

按照Oracle官方的安装文档,Oracle数据库的安装过程真是繁琐。但这种繁琐也保证了在各种系统和参数下,数据库能够正常运行。

首先,应当确保系统有2GB以上内存可用,另外还要有X Window图形环境和root权限以及足够的硬盘空间。

第一步应该以root权限建立oinstall、dba两个用户组(如果需要还可以建立oper组,其实这些组都不是限定死的,可以根据自己的需要来调整),然后添加oracle用户。

1
2
3
4
5
groupadd oinstall
groupadd dba
# optional: groupadd oper
useradd -g oinstall -G dba oracle
passwd oracle  # Set the password

第二步是安装依赖,下面这些依赖有的是系统已经包含了,有些需要我们自己安装。可以通过图形化安装器或者yum来安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
binutils
compat-libstdc++-33
elfutils-libelf
elfutils-libelf-devel
gcc
gcc-c++
glibc
glibc-common
glibc-devel
glibc-headers
ksh
libaio
libaio-devel
libgcc
libstdc++
libstdc++-devel
make
sysstat
unixODBC
unixODBC-devel

第三,是要检查内核参数,不满足要求的要修改。下面这些量的值可以通过sysctl -a | grep x(x代表对应量的名称)来查看,如果小于下面的数值,则要在/etc/sysctl.conf中追加下面对应的行来限制,大于的可以不考虑。使用sysctl -p使之立即生效。

1
2
3
4
5
6
7
8
9
10
11
fs.file-max = 6815744
fs.aio-max-nr=1048576
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576

第四,要检查资源限制。使用ulimit -x来检查,这里的x分别指定为Sn、Hn、Su、Hu、Ss、Hs,他们的最小值分别是2014、65536、2047、16384、10240、10240。如果有哪项不满足,可以在/etc/security/limits.conf追加以下内容来解决。

1
2
3
4
5
6
oracle soft nproc 2047    # Sn
oracle hard nproc 16384   # Hn
oracle soft nofile 1024   # Su
oracle hard nofile 65536  # Hu
oracle soft stack 10240   # Ss
oracle soft stack 32768   # Hs

第五步,关闭SELINUX,在/etc/selinux/config中修改为disabled,并使用setenforce 0立即生效。

第六步,添加Oracle和Inventory目录。

1
2
3
4
5
6
mkdir /opt/oracle
chown oracle:oinstall /opt/oracle
chmod 755 /opt/oracle
mkdir /opt/oraInventory
chown oracle:oinstall /opt/oraInventory
chmod 755 /opt/oraInventory

第七步,解压安装包。unzip后可跟-d参数指定解压到哪里,以解压到/home/oracle/database为例。然后将权限赋予oracle用户。

1
2
3
4
unzip linux_11gR2_database_1of2.zip -d /home/oracle/
unzip linux_11gR2_database_2of2.zip -d /home/oracle/
chmod -R 700 /home/oracle/database
chown -R oracle:oinstall /home/oracle/database

第八步,切换到oracle用户。修改/home/oracle/.bash_profile添加以下几行,然后使用source /home/oracle/.bash_profile使之立即生效。

1
2
3
4
5
6
ORACLE_BASE=/opt/oracle # 安装目录
ORACLE_HOME=$ORACLE_BASE/11g # oracle家目录
ORACLE_SID=orcl # 实例名
LD_LIBRARY_PATH=$ORACLE_HOME/lib
PATH=$PATH:$ORACLE_HOME/bin:$HOME/bin
export ORACLE_BASE ORACLE_HOME ORACLE_SID LD_LIBRARY_PATH PATH

安装

以oracle用户运行/home/oracle/database/runInstaller。在第一步输入电子邮件并点击下一步,如果提示联网失败,勾选提示框上的复选框并继续。之后则根据自己的需要来一步步,如字符集等等都是要考虑的内容。如果过程中提示pdKsh找不到,直接勾选ignore忽略即可,这个包并不必要,由于其不遵循POSIX标准,新系统中不再提供该包。一直到最后,可看到安装完毕,弹窗提示以root用户运行两个脚本,按照提示运行即可完成安装。

最终完成操作,则可以通过https://localhost:1158/em进入OEM了。Oracle并不会自己启动,如果需要请执行以下命令。需要自启动和关闭的请修改系统配置文件。执行前将/etc/oratab中的对应实例调整为Y。

1
2
lsnrctl start  # 启动监听器
emctl start dbconsole  # 启动OEM

配置随机自启动

如果有自启动的必要的话,首先要修改dbstart和dbshut脚本,将其中的ORACLE_HOME_LISTNER=$1修改为ORACLE_HOME_LISTNER=$ORACLE_HOME,然后vim新建/etc/init.d/oracle,具体文件名可以随便写,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/sh
# chkconfig: 345 61 61
# description: Oracle 11g R2 AutoRun Services
# /etc/init.d/oracle
#
# Run-level Startup script for the Oracle Instance, Listener, and
# Web Interface
 
export ORACLE_BASE=/opt/oracle # 安装目录,根据实际情况写
export ORACLE_HOME=$ORACLE_BASE/11g # 根据实际情况写
export ORACLE_SID=orcl
export PATH=$PATH:$ORACLE_HOME/bin
 
ORA_OWNR="oracle"
 
# if the executables do not exist -- display error
if [ ! -f $ORACLE_HOME/bin/dbstart -o ! -d $ORACLE_HOME ] then
	echo "Oracle startup: cannot start"
	exit 1
fi
 
# depending on parameter -- startup, shutdown, restart
# of the instance and listener or usage display
case "$1" in
start)
	# Oracle listener and instance startup
	su $ORA_OWNR -lc $ORACLE_HOME/bin/dbstart
	echo "Oracle Start Succesful!OK."
	;;
stop)
	# Oracle listener and instance shutdown
	su $ORA_OWNR -lc $ORACLE_HOME/bin/dbshut
	echo "Oracle Stop Succesful!OK."
	;;
reload|restart)
	$0 stop
	$0 start
	;;
*)
	echo $"Usage: `basename $0` {start|stop|reload|reload}"
	exit 1
esac
exit 0

配置启动项:

1
2
3
4
5
6
7
# 赋予启动脚本执行权限并链接
chmod 750 /etc/init.d/oracle
ln -s /etc/init.d/oracle /etc/rc1.d/K61oracle
ln -s /etc/init.d/oracle /etc/rc3.d/S61oracle
# 把oracle启动脚本添加到系统服务里并设置自启动
chkconfig --add oracle
chkconfig --level 345 oracle on

参考资料

http://blog.itrunc.com/2013/12/30/install-oracle-11g-release2-in-centos-x64/

http://www.ha97.com/4862.html

U盘安装Linux的LiveCD镜像提示No root device block:/dev/mapper/live-rw found的解决

2014-06-25 • 技术文章

今天在实验室新购置的一台新机器上通过U盘安装CentOS 6.5的LiveCD镜像遇到了kernel panic,崩溃时提示信息为“No root device "block:/dev/mapper/live-rw" found”。

由于屏幕最上方还有Haswell HDMI Audio不支持的提示,对分析原因造成了一定的干扰。其实和HDMI的支持没什么关系,panic的根本原因在于没有找到root device。/dev/sda被视为了内置的系统硬盘,而U盘找不到了,在/dev/mapper中没有live-rw。分析isolinux.cfg文件发现其中有root=live:CDLABEL=CentOS-6.5-i386-LiveCD,而U盘并不符合这个CDLABEL,可能正是这个原因造成了无法识别U盘。

因此解决办法有两种:一是找到U盘中的isolinux.cfg,把U盘的卷标和CDLABEL统一;二是使用U盘的UUID来识别root,如修改指定root位置的部分为root=UUID=B4FE-5315,这里的UUID根据系统确定。

qsort排序的使用

2014-06-17 • 技术文章

在C语言中使用stdlib.h中的qsort函数可以对数组进行排序,免去自己写排序算法的麻烦,下面简单介绍其用法。

可比较大小的基本数据类型排序

我们需要编写一个comp()函数,使用qsort()调用它既可。如下所示,comp()的参数类型是void*,即无类型指针,可以指向任意数据类型。以int为例,(int *)将参数转换为实际的数据类型指针,再来一个*得到值。把int换成char、double等则变成了对应类型的比较实现。qsort()并不一定是快排,在qsort()的实现中,如果数组长度小于CUTOFF(宏定义为8),则调用shortsort()来排序,因为测试表明这样处理更快。qsort()个最后一个参数是comp,即比较函数的实现,在排序函数中会调用它,但其实现必须有我们来完成。

1
2
3
4
5
6
int comp(const void *a, const void *b) {
	return *(int *)a > *(int *)b ? 1 : -1;
}
......
int arr[9] = {8,7,1,2,3,9,6,5,4};
qsort(arr, 9, sizeof(arr[0]), comp);

结构体排序

在结构体中,将comp()函数中的比较左右的量右括号抱起来然后用点运算取得对应项即可,qosrt()对应改动类型名即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct item {
	int index;
	char ch;
};
......
int comp(const void *a, const void *b) {
	return (*(item *)a).index > (*(item *)b).index ? 1 : -1;
}
......
struct item x[9];
int arr[9] = {8,7,1,2,3,9,6,5,4};
int i;
for(i=0; i<9 ; ++i) {
	x[i].index = arr[i];
}
qsort(x, 9, sizeof(x[0]), comp);

假如排序时要依据多个参考量,如首先考察上面结构体x中的index,相同时还要继续考虑ch,这需要略微更改comp()。

1
2
3
4
5
int comp(const void *a, const void *b) {
	struct item *aa = (item *)a, *bb = (item *)b;
	if(aa->index == bb->index) return aa->ch > bb->ch ? 1 : -1;
	else return aa->index > bb->index ? 1 : -1;
}

另外需要特别注意的是如果比较的是字符串,比较大小要使用strcmp()。

PAT-1002. A+B for Polynomials题解

2014-04-17 • 技术文章

Input

Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N1 aN1 N2 aN2 ... NK aNK, where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1, 2, ..., K) are the exponents and coefficients, respectively. It is given that 1 <= K <= 10,0 <= NK < ... < N2 < N1 <=1000.

Output

For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.

Sample Input

2 1 2.4 0 3.2

2 2 1.5 1 0.5

Sample Output

3 2 1.5 1 2.9 0 3.2

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
 
typedef struct In{
	int a; // exp
	double _a; //coef
}In;
 
In x[20]; 
 
int sum1;
 
int cmp(const void *aa ,const void *bb) { 
	return (*(In *)aa).a >= (*(In *)bb).a ? -1 : 1; 
}
 
int main()
{
    int i,j,m,sum2;
    double n;
    scanf("%d",&sum1);
    for(i=0;i<sum1;i++) {
    	scanf("%d%lf", &x[i].a, &x[i]._a);
    }
    scanf("%d",&sum2);
    for(j=0;j<sum2;j++) {
    	scanf("%d%lf", &m, &n);
    	for(i=0;i<sum1;i++) {
    		if(x[i].a==m) {
    			x[i]._a += n;
    			break;
    		}
    	}
    	if(i==sum1) { // diff one
    		x[sum1].a = m;
    		x[sum1]._a = n;
    		sum1++;
    	}
    }
    qsort(x,sum1,sizeof(x[0]),cmp);
    j = sum1; // count
    for(i=0;i<sum1;i++) { 
    	if(x[i]._a == 0.0)
    		j--;
    }
    printf("%d", j);
    for(i=0;i<sum1;i++) {
    	if(x[i]._a)
    		printf(" %d %.1lf", x[i].a, x[i]._a);
    }
    return 0;
}