谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

C、C++和Java语言
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#1

帖子 lldonger » 2010-12-08 19:54

具体情况是这样的:
在给某银行做一个项目,环境为AIX,有个需求要求普通帐号可以清理备份IHS的日志,于是我们公司一位前辈写了一个C程序来调用清理备份IHS日志的脚本。C代码如下:

#include "stdio.h"
#include "pwd.h"

main(int argc,char *argv[])
{
struct passwd *root_pwd;
char proc_name[254];
gid_t root_gid;
uid_t root_uid;
int gg,uu;

if(1==argc)
strcpy(proc_name,"./backup_ihslog.sh");
else{
printf("Running %s",argv[1]);
strcpy(proc_name,argv[1]);
}
root_pwd=getpwnam("root");

root_gid=root_pwd->pw_gid;
root_uid=root_pwd->pw_uid;

gg=setgid(root_gid);
uu=setuid(root_uid);

gg=system(proc_name);
return 0;
}

root用户编译此C代码,并加上suid
#gcc backup_ihslog_c.c -o backup_ihslog_c
#chmod u+s backup_ihslog_c
普通用户直接运行backup_ihslog_c就可以进行IHS日志的清理备份了。我们认为这样没有问题了,但是今天银行请的一位专家说这样做有漏洞,说在运行这个C程序时后边跟上其他root的命令也是可以运行的,比如rm -rf /etc 。让我把那个if语句去掉,程序改为这样:
#include "stdio.h"
#include "pwd.h"

main(int argc,char *argv[])
{
struct passwd *root_pwd;
char proc_name[254];
gid_t root_gid;
uid_t root_uid;
int gg,uu;
strcpy(proc_name,"./backup_ihslog.sh");
printf("Running %s",argv[1]);
strcpy(proc_name,argv[1]);

root_pwd=getpwnam("root");

root_gid=root_pwd->pw_gid;
root_uid=root_pwd->pw_uid;

gg=setgid(root_gid);
uu=setuid(root_uid);

gg=system(proc_name);
return 0;
}


我想他请教,但是人家是专家根本就不鸟我这样的小菜鸟,所以只有到这里请教大家了。请大家帮我分析一下这个程序,帮我在每条加上注释,谢谢!
头像
cnkilior
论坛版主
帖子: 4981
注册时间: 2007-08-05 17:40
送出感谢: 0
接收感谢: 5 次

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#2

帖子 cnkilior » 2010-12-08 20:16

strcpy别随便用,这个函数,不做合法性检查的。
其次system没有检查参数。例如分号之类的。

我这样运行:

代码: 全选

backup_ihslog_c "kdjksdjfsh;rm -rf /"
你可以试试,系统是不是完了?

代码: 全选

#include <stdio.h>

int main()
{
    system("ls -l;echo aaaaa");
}
我的测试程序。
你可以跑跑。
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#3

帖子 lldonger » 2010-12-08 20:47

cnkilior 写了:strcpy别随便用,这个函数,不做合法性检查的。
其次system没有检查参数。例如分号之类的。

我这样运行:

代码: 全选

backup_ihslog_c "kdjksdjfsh;rm -rf /"
你可以试试,系统是不是完了?

代码: 全选

#include <stdio.h>

int main()
{
    system("ls -l;echo aaaaa");
}
多谢2楼的,请问ackup_ihslog_c "kdjksdjfsh;rm -rf /"中的kdjksdjfsh是什么意思?
谢谢
我的测试程序。
你可以跑跑。
头像
cnkilior
论坛版主
帖子: 4981
注册时间: 2007-08-05 17:40
送出感谢: 0
接收感谢: 5 次

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#4

帖子 cnkilior » 2010-12-08 20:50

kdjksdjfsh的意思是ishdajhfkjsdnjchshflksjdnf
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#5

帖子 lldonger » 2010-12-08 20:53

cnkilior 写了:kdjksdjfsh的意思是ishdajhfkjsdnjchshflksjdnf
呵呵,;前面可以随意写吗?
多谢!
头像
xhy
帖子: 3916
注册时间: 2005-12-28 1:16
系统: Ubuntu 12.10 X64
来自: 火星
送出感谢: 1 次
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#6

帖子 xhy » 2010-12-08 21:00

setuid的程序可不好写 特别是允许输入shell命令的 极其不好写
目前负债150多万
风间星魂
帖子: 490
注册时间: 2009-06-20 23:53
送出感谢: 3 次
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#7

帖子 风间星魂 » 2010-12-08 22:04

这C写的一塌糊涂。
不检查参数,极其危险。
标准库头文件不用<>反而用" "
看参数明明是ansi c风格 ,main却不写返回类型。
头像
xhy
帖子: 3916
注册时间: 2005-12-28 1:16
系统: Ubuntu 12.10 X64
来自: 火星
送出感谢: 1 次
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#8

帖子 xhy » 2010-12-08 23:51

其实这个根本就不应该自己写程序解决,既不经济又不安全,
可以给AIX装一个类似sudo的工具,赋予普通用户以root权限执行备份脚本的能力。
话说,app根本不应该以root权限运行,至少要在做完初始化之后,要drop掉权限。
开发这个系统的团队,可能没考虑这方面的事情,而那位“前辈”,连业余都算不上吧.
目前负债150多万
头像
追疯少年
帖子: 950
注册时间: 2008-03-13 23:37
送出感谢: 0
接收感谢: 1 次
联系:

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#9

帖子 追疯少年 » 2010-12-09 0:03

不懂,纯属围观
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#10

帖子 lldonger » 2010-12-12 9:11

上面的都是高人,小弟领教了!
soiamso
帖子: 418
注册时间: 2008-09-06 2:00
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#11

帖子 soiamso » 2010-12-12 22:03

这么重要的程序竟然用C写....
头像
tangboyun
帖子: 701
注册时间: 2009-07-25 1:57
送出感谢: 5 次
接收感谢: 13 次
联系:

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#12

帖子 tangboyun » 2010-12-13 11:08

这不是代码风格的问题,人家说的是你的程序如果没有加密,也就是编译后没有进行代码模糊,那么这么简单的二进制文件,是很容易被篡改的。
只要反汇编你的二进制文件,找出汇编后的strcpy(proc_name,"./backup_ihslog.sh")这句,把代码段的文本替换为rm -rf /etc,你这段代码的功能就完全变了。用if的话,更容易被人通过上下文找出你程序的逻辑,一般汇编后函数名之类都替换掉的,看不出来,但你这样就有很明显的上下文了。
还有不要直接写"./backup_ihslog.sh"这种文本串,最好用几个小函数来变换掉原来的字串,要用时再逆向解回来,因为你这玩意又不需要大量计算,所以做这点也是值得的。
对于一般的小工具来说,这么做有点吹毛求疵,但你是银行系统,那另当别论。
https://github.com/tangboyun
http://tangboyun.is-programmer.com/
提问的智慧————Eric Steven Raymond
回答的智慧————Andrew Clarke
吾尝终日而思矣,不如须臾之所学也;吾尝跂而望矣,不如登高之博见也。
急急急标题什么的,最讨厌了!
急急复急急,急急何其多,我生待急急,万事急急急。
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#13

帖子 lldonger » 2010-12-13 17:28

tangboyun 写了:这不是代码风格的问题,人家说的是你的程序如果没有加密,也就是编译后没有进行代码模糊,那么这么简单的二进制文件,是很容易被篡改的。
只要反汇编你的二进制文件,找出汇编后的strcpy(proc_name,"./backup_ihslog.sh")这句,把代码段的文本替换为rm -rf /etc,你这段代码的功能就完全变了。用if的话,更容易被人通过上下文找出你程序的逻辑,一般汇编后函数名之类都替换掉的,看不出来,但你这样就有很明显的上下文了。
还有不要直接写"./backup_ihslog.sh"这种文本串,最好用几个小函数来变换掉原来的字串,要用时再逆向解回来,因为你这玩意又不需要大量计算,所以做这点也是值得的。
对于一般的小工具来说,这么做有点吹毛求疵,但你是银行系统,那另当别论。
请指教一下怎么看到编译后程序中的代码的?我记得那位专家好像是用了

# more | ./backup_ishlog_c

这个命令就看到backup_ishlog_c里面的内容了,不是说二进制文件都是机器码吗?为什么还能看到里面的内容(类似于源代码),小弟愚笨,请指教!
头像
tangboyun
帖子: 701
注册时间: 2009-07-25 1:57
送出感谢: 5 次
接收感谢: 13 次
联系:

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#14

帖子 tangboyun » 2010-12-13 18:34

我不是逆向高手,也是个菜鸟,不过要看二进制的话,可以

objdump -d <你的二进制文件>

还有专门的工具来搞这种的,感兴趣的话,可以看看《加密与解密》这本书。
还有就是可以参考下《C安全编码》好像是这个名字,这类书。
你写的程序,危险的地方,并不是楼上几位说的问题,毕竟代码写的丑,不规范,不要给别人看到就可以了 :em06
危险的地方,是你用了system这种函数。这种函数并不会检查它的参数是否是别有用心的,就直接扔给shell去做了,如果执行你的二进制的又有合适的权限,后果就不堪设想了。
而你用了。。。还根本没考虑去加密那个字串(或者是检查一些shell meta字符,或者是一些危险语句、等等等自己去考虑对策。),或者模糊掉对system之类的调用。。。这个给人家捉住把柄被bs也就活该了。。。 :em02
尽量不要用system这种函数。用了的话,更要考虑安全,毕竟这才是你们客户第一位要考虑的。
https://github.com/tangboyun
http://tangboyun.is-programmer.com/
提问的智慧————Eric Steven Raymond
回答的智慧————Andrew Clarke
吾尝终日而思矣,不如须臾之所学也;吾尝跂而望矣,不如登高之博见也。
急急急标题什么的,最讨厌了!
急急复急急,急急何其多,我生待急急,万事急急急。
头像
lldonger
帖子: 101
注册时间: 2010-10-15 15:42
送出感谢: 0
接收感谢: 0

Re: 谁能帮我分析一下这个C代码?谢谢!一位银行的专家竟说有漏洞

#15

帖子 lldonger » 2010-12-14 22:29

都是高人,学习了
代码丑才要贴出来,请各位高人指教才能进步!
回复

回到 “C/C++/Java”