Introduction
When a super hacker is logged in on the server and is doing something, I want to hack the terminal, and you maybe want to hack the terminal also.
Other purpose of looking at the terminal is to visually check that commands are typed correctly on the server by several people. But, when there is a physical distance, it is difficult to project the screen on the monitor.
One way to do this is to ask to see the terminal, but it's smart to have a little tool to reference it. So, I made a ttycopy that runs in a shell.
https://github.com/d-tsuji/ttycopy
It runs in the Bash, so you can copy and paste a ttycopy implementation to make it work casually.
Sample
ttycopy works as follows. In fact, there are two terminals, and after ttycopy, the operation of the other terminal is shown.
Detail
I would like to tell you how this is being processing. The basic flow of the process is as follows.
- Check the PID of the tty's login process
- Peering into a system call using the strace command against PID
- Print a formatted string of the read system call output by strace
Implementation with Bash
1.Check the PID of the tty's login process
The shell implementation is as follows.
pid=`ps fauwwx | grep sshd.*${tty} | grep -v grep | sed -e 's/^[a-zA-Z0-9]\+[ \n\r\f\t]\+\([0-9]\+\).*/\1/'`
This captures the PID using a regular expression with a string of the following process tree that can be retrieved when grep is done. You can use regular expressions to make it look neat.
[tsuji@localhost ~]$ ps fauwwx | grep sshd.
root 1531 0.0 0.1 82568 6236 ? Ss 15:29 0:00 /usr/sbin/sshd -D
root 2830 0.0 0.2 149824 8916 ? Ss 15:29 0:01 \_ sshd: root@pts/0
root 13315 0.0 0.2 158980 10280 ? Ss 18:58 0:00 \_ sshd: root@notty
root 14956 0.0 0.2 154512 9352 ? Ss 20:10 0:00 \_ sshd: tsuji [priv]
tsuji 14959 0.0 0.1 154512 4092 ? S 20:10 0:00 \_ sshd: tsuji@pts/1
tsuji 15012 0.0 0.0 112672 2268 pts/1 S+ 20:11 0:00 \_ grep --color=auto sshd.
2.Peering into a system call using the strace command against PID
The shell implementation is as follows.
strace -e read -s16384 -q -xx -p ${pid} 2>&1
What we are doing is using strace to retrieve the read system call issued by the PID associated with the tty we just retrieved, and since various other system calls are called besides the read system call, only the read system call is extracted using the -e read
option of strace.
The read system call was the system call defined below, and the results that can be obtained with starce are also as follows.
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
For example, suppose the following command is issued in the referring terminal
- fetched terminal
[tsuji@localhost gomi]$ hoge
bash: hoge: コマンドが見つかりませんでした...
[tsuji@localhost gomi]$
If you refer to the read system call with strace -p ${PID} -e read
, the output is as follows.
- straing terminal
[root@localhost ttycopy]# strace -p 14959 -e read
strace: Process 14959 attached
read(3, "\0\0\0\20\356\202\375C&&\357q\276\210pZ)\300\26M\357T\313\303k\6p\232\351\263\32\224"..., 16384) = 36
read(11, "h", 16384) = 1
read(3, "\0\0\0\20\235\230\204Ud\36)\370\266\233\362\305\2219\253g\335M\23\212\374h\250i@\235/\216"..., 16384) = 36
read(11, "o", 16384) = 1
read(3, "\0\0\0\20\324\357\304\vn\357BbW\241m\220yS\236\362\301\337\337\237c\203\245\223\221\253;,"..., 16384) = 36
read(11, "g", 16384) = 1
read(3, "\0\0\0\20\344\215\235\300\226\236\0\323\376\r\217,\257\322\326w\323R\264\3}\266\7q\315\215\344\346"..., 16384) = 36
read(11, "e", 16384) = 1
read(3, "\0\0\0\20^``\333\263h\372Z\336\335Y2\250\203\335\221\372faj\177\260f\302Sb\35\354"..., 16384) = 36
read(11, "\r\n", 16384) = 2
read(11, "bash: hoge: \343\202\263\343\203\236\343\203\263\343\203\211\343\201\214\350\246\213\343\201"..., 16384) = 62
read(11, "\33]0;tsuji@localhost:~/gomi\7[tsuj"..., 16384) = 51
^Cstrace: Process 14959 detached
The example above shows the strings strace: Process 14959 attached
and strace: Process 14959 detached
, but the strace option -q
is used to suppress this output. Also, the string is converted to hexadecimal with the -x
option to make it easier to handle when displaying it.
3.Print a formatted string of the read system call output by strace
The goal is to display the contents of the second argument of the read system call obtained in step 2. The shell implementation is as follows.
sed -une "s/^read([0-9]\+, \"\(.*\)\".*/echo -n \$'\1'/p" | bash
First, the first part sed -une "s/^read([0-9]\+, \"\(.*\)\".*/echo -n \$'\1'/p"
. It captures the second argument of the read system call in a regular expression and gives it the strings echo -n
and $''
. Therefore, we can get the following string
- The string output to the source terminal
[tsuji@localhost gomi]$ cat hoge
hoge
[tsuji@localhost gomi]$
Strace the terminal string to be output after processing.
echo -n $'\x00\x00\x00\x10\xc6\x1e\x56\xc6\x1f\x11\x7e\x57\x11\xaf\xdb\x2a\x91\x32\x84\x8e\x6e\x5b\x12\xc1\x72\x94\x36\x17\x12\xbb\x7c\xab\x4b\xdd\x19\x33'
echo -n $'c'
echo -n $'\x00\x00\x00\x10\x5d\x68\x72\x7c\x74\xca\x3c\xd1\x57\xfc\x14\x7d\x55\x34\x66\x15\x03\xcb\x26\x7c\x17\xbc\x7f\x7a\xf5\x25\x40\xed\xa8\x21\x39\xb3'
echo -n $'a'
echo -n $'\x00\x00\x00\x10\x05\x3d\x4a\xc2\x76\x1c\xd4\x23\x2a\x17\xc6\xa1\x1c\xf2\xdb\x14\x75\x1c\x7d\xb7\x21\xfb\xfc\xcd\x2d\x5c\xef\x06\x6c\x97\x01\x28'
echo -n $'t'
echo -n $'\x00\x00\x00\x10\x66\xb0\x8c\x40\x10\xa6\xf3\x9b\x36\x75\xd5\xc1\x65\x63\x94\x4f\x77\xd9\x10\x6d\xcf\xbb\x48\xed\x8b\x43\x58\x20\x54\x08\xde\x9b'
echo -n $' '
echo -n $'\x00\x00\x00\x10\x60\x6e\xb6\x06\x43\x16\xf5\x75\x89\x90\xb6\x42\x2c\xfe\x8b\x97\xae\xad\x47\x26\xf9\x39\xfc\xd2\x84\x37\xde\x0d\xe5\x32\xbc\x80'
echo -n $'h'
echo -n $'\x00\x00\x00\x10\x00\xe4\x3d\xb7\xd9\x79\x2e\x46\x80\xd5\xa5\xc2\xa7\x9a\xc7\x0c\xe1\x58\x7b\xd5\x97\xff\x00\xab\x72\x51\xa4\xbb\xab\x7d\xd1\xaf'
echo -n $'o'
echo -n $'\x00\x00\x00\x10\xf8\x1d\xce\xe6\x7f\x1a\x43\x94\xa2\xde\x3d\x3c\xb5\xe9\xb9\x94\x39\x43\x63\xfd\xa9\x1f\x45\x83\x64\x5c\x3a\xdf\xa8\x1a\xa4\x86'
echo -n $'g'
echo -n $'\x00\x00\x00\x10\x90\x69\x42\xa9\x48\x99\x0c\x52\xe9\x49\xbd\x4e\xa5\x17\x01\xff\xac\xec\x29\x75\x2c\xc0\x2b\x7c\x07\x85\xf2\x2f\xce\x71\x8f\x46'
echo -n $'e'
echo -n $'\x00\x00\x00\x10\xd9\x91\x38\x08\x0b\x95\x78\xd4\x80\x51\xa2\xe8\xef\x20\x06\x45\xa9\x3c\xf0\xa3\x10\x7d\x06\x32\x2d\x31\x53\x57\x40\x77\x1b\x29'
echo -n $'\r\n'
echo -n $'\x68\x6f\x67\x65\x0d\x0a\x1b\x5d\x30\x3b\x74\x73\x75\x6a\x69\x40\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74\x3a\x7e\x2f\x67\x6f\x6d\x69\x07'
echo -n $'[tsuji@localhost gomi]$ '
The -n
option of echo -n
is to avoid line breaks when interpreting. the $''
form of Bash has the following effect. excerpt from the Man page
Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Backslash escape sequences, if present, are decoded as follows:
ref: https://linux.die.net/man/1/bash
This can be used to expand to the meaning that the string holds.
All that's left to do is to let the shell interpret the echo
string with the | bash
to display the string.
Summary
I was able to casually share the terminal by retrieving a string of arguments for the read system call in strace and restoring them in real time. I think it's an educational tool because you can see other people's work in real time. If you want to hack the terminal, you should try it.
If you like, you can add a star to ttycopy to increase my motivation of development.
Thank you!
Top comments (0)