데이터를 밀어 넣는 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.bin
echo가 터미널에 주입되지 않지만 잡을 수 없습니다.
./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"'
이 접근 방식은 내 사용 사례에서는 충분히 안정적이지만 다음과 같은 명백한 문제가 있습니다.
- 종료 상태가
pusher.bin
손실됩니다. - 종료를 기다리지 않고
pusher.bin
1초 후에 완료된다고 가정합니다. - tty를 얻으려면 공유된 사용자 대면 리소스인 스크린 세션을 사용하십시오.
- 임시 파일은 조기에 연결 해제되지 않으므로 문제가 발생할 경우 임시 파일이 남겨질 수 있습니다.
그 중 일부는 수정하기 쉬운 반면 다른 일부는 더 복잡합니다.