내가 이것을 넣었을 때
nc -l 12345 >nc_out
쉘 스크립트에서 이를 실행한 다음 텔넷을 사용하여 다른 쉘에서 연결하고 일부 텍스트를 입력하면 종료됩니다.CNC 출력.
하지만 백그라운드에서 nc를 시작하면(나중에 동일한 스크립트에서 telnet을 시작하고 싶습니다):
nc -l 12345 >nc_out &
연결이 즉시 종료됩니다.
# telnet localhost 12345
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host
#
nc_out 파일을 비워 둡니다.
왜 그런 겁니까? nc가 연결을 정상적으로 수락하도록 하려면 어떻게 해야 합니까?
노트:
RHEL 및 Fedora에서는CNC그리고nmap-ncat하지만 데비안은NC-전통연결을 수락하고 데이터를 nc_out에 저장할 수 있습니다.
동일한 스크립트에서 텔넷을 호출하든 다른(SSH) 세션에서 호출하든 상관없습니다. 동작은 동일합니다.
또한 @Hauke Laging이 제안한 대로 strace를 사용하여 명령을 실행하고 게시했습니다.Pastebin의 strace 출력
답변1
작업 제어가 비활성화된(셸 스크립트의 경우처럼) 비대화형 셸에서 실행되는 백그라운드 명령 stdin
은 /dev/null
.
sh -c 'nc -l 12345 1>nc_out & lsof -p $!'
~에서POSIX.1-2008:
2. 쉘 명령 언어
[...]
비동기 목록
명령이 제어 연산자( '&' )에 의해 종료되면 쉘은 서브쉘에서 명령을 비동기적으로 실행해야 합니다. 이는 쉘이 다음 명령을 실행하기 전에 명령이 완료될 때까지 기다리지 않아야 함을 의미합니다.
백그라운드에서 명령을 실행하는 형식은 다음과 같습니다.
command1 & [command2 & ... ]
명시적인 리디렉션이 수행되기 전에 비동기 목록의 표준 입력은 동일한 속성을 가진 파일에 할당된 것처럼 처리되어야 합니다./dev/비어 있음. 대화형 셸이라면 이런 일이 발생할 필요가 없습니다. 모든 경우에 표준 입력의 명시적인 리디렉션이 이 활동을 재정의해야 합니다.
클라이언트가 포트를 통해 이미 실행 중인 명령에 대한 연결을 설정하면 telnet
백그라운드 명령은 표준 입력에서 EOF를 감지하고 /dev/null에서 강제로 읽혀지므로 종료 프로세스를 시작하는 것으로 보입니다. command()의 반환 값 0은 파일의 끝을 나타냅니다.localhost
nc
12345
nc
read
man 2 read
# strace output (from http://pastebin.com/YZHW31ef)
14:32:26 read(0, "", 2048) = 0
14:32:26 shutdown(4, 1 /* send */) = 0
telnet
계속해서 실행하고 통신할 수 있는 몇 가지 솔루션은 다음과 같습니다 nc
.
sh -c 'nc -l 12345 0<&0 1>nc_out &'
sh -c 'nc -l 12345 0<&- 1>nc_out &'
sh -c 'tail -f /dev/null | nc -l 12345 1>nc_out &'
sh -c 'rm -f fifo; mkfifo fifo; exec 3<>fifo; nc -l 12345 0<fifo 1>nc_out &'
답변2
nc -ld host port >> logfile &
-d 표준 입력에서 읽으려고 시도하지 않습니다.
이는 백그라운드에서 "nc"에 의해 실행됩니다.
왜냐하면 'nc'가 백그라운드에서 실행되면 stdin stdout stderr을 읽어오기 때문입니다.
표준 입력 읽기가 비활성화되어 있지 않으면 중단됩니다.
예:
nc -ld 12345 > nc_out
nc 127.0.0.1 12345
#enter something
데이터는 다음 위치에 저장됩니다.CNC 출력문서.