내 tty에서 프로그램을 어떻게 실행합니까?

내 tty에서 프로그램을 어떻게 실행합니까?

데이터를 밀어 넣는 TIOCSTI를 사용하고 있습니다.단말기입력 버퍼. 데이터가 셸에 도달하기 전에 캡처하거나 파일로 리디렉션할 수 있기를 원합니다.

내가하려는 일을 더 잘 설명하려면 다음을 수행하십시오.

gcc -x c -o pusher.bin - <<PUSHER
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>

int main() {
  char *c = "echo 'Catch me if you can'\n";
  while(*c) ioctl(0, TIOCSTI, c++);
}
PUSHER
./pusher.bin

내 터미널에서 실행하면 내 tty가 ./pusher.bin삽입되고 echo 'Catch me if you can'\n내 쉘이 즉시 실행됩니다. 실행하면 setsid ./pusher.binecho가 터미널에 주입되지 않지만 잡을 수 없습니다.

./pusher.bin베어 메탈을 실행하는 경우 푸셔가 내 tty 입력 버퍼에 무엇을 주입할지 확인할 수 있도록 뭔가로 마무리하고 싶습니다 .

밝히다:나는 주입된 입력이 쉘의 표준 입력에 도달한 후에 캡처될 수 있다는 것을 알고 있습니다. 이 접근 방식은 삽입된 입력을 캡처하는 데 효과적이지만 일반 사용자 입력도 캡처할 수 있습니다. 또한 stdin이 닫혀 있거나 프로세스가 tty에 연결되지 않은 경우 이 방법은 작동하지 않습니다. 이러한 단점만으로도 stdin 캡처가 일반적인 솔루션으로 실행 불가능해집니다.

답변1

AB가 언급했듯이 이것이 script해결책인 것 같습니다. -e프로그램의 반환 코드도 얻을 수 있습니다. 캐리지 리턴 과 라인 피드를 cat -vet더 명시적으로 표시합니다 .^M$

$ script -q -e out -c ./pusher.bin >/dev/null; echo $?
0
$ cat -vet out
Script started on Mon Dec 21 10:54:40 2020$
echo 'Catch me if you can'^M$

답변2

주입 후에는 터미널을 읽어야 합니다. 예를 들어, 라인의 경우:

$ ./pusher.bin;read a
$ echo "Intercepted: $a"

또는 일반적으로:

$ ./pusher.bin;cat

종료 하려면 EOF를 주입해야 할 수도 있습니다 cat.

다른 옵션을 확인하고 싶다면오직삽입된 문자:

$ stty -echo;./pusher.bin;cat;stty echo

삽입된 문자열을 캡처하여 일반 입력과 구별할 수 없습니다.

답변3

나는 실용적이지만 결함이 있는 해결책을 생각해 냈습니다.

RESULT="$(bash -c 'ID="s$(head -c 8 /dev/urandom | base64 | sed "s/[^0-9a-zA-Z]//g")"; F="$(mktemp)";  screen -d -m -S "$ID" bash -c "./escape.bin; cat >/$F"; sleep 1s; screen -S "$ID" -X quit; cat <$F; rm "$F"')"

중요한 부분을 분석하면 다음과 같습니다.

# Generate a unique session name for screen
ID="s$(head -c 8 /dev/urandom | base64 | sed "s/[^0-9a-zA-Z]//g")";

# Get a temporary file
F="$(mktemp)";  

# Run pusher in a detached (`-d -m`) screen session 
# with its own tty and read back the tty's buffer 
# using cat and write it to the temporary file
screen -d -m -S "$ID" bash -c "./pusher.bin; cat >/$F"; 

# Sleep for one second for pusher to finish (I'm a 
# aware that I can poll screen using `-list`, but 
# exec fails for some reason, help here would be 
# appreciated)
sleep 1s; 

# Kill screen session manually (again, `exec`ing 
# fails for some reason )
screen -S "$ID" -X quit; 

# Print the contents of F to stdout so that it can 
# be captured by the outermost `$(...)`
cat <$F; 

# Removes the temporary file
rm "$F"'

이 접근 방식은 내 사용 사례에서는 충분히 안정적이지만 다음과 같은 명백한 문제가 있습니다.

  1. 종료 상태가 pusher.bin손실됩니다.
  2. 종료를 기다리지 않고 pusher.bin1초 후에 완료된다고 가정합니다.
  3. tty를 얻으려면 공유된 사용자 대면 리소스인 스크린 세션을 사용하십시오.
  4. 임시 파일은 조기에 연결 해제되지 않으므로 문제가 발생할 경우 임시 파일이 남겨질 수 있습니다.

그 중 일부는 수정하기 쉬운 반면 다른 일부는 더 복잡합니다.

관련 정보