DEV Community

Tsuji Daishiro
Tsuji Daishiro

Posted on

How to hacking terminal with Bash

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.

ttycopy

Detail

I would like to tell you how this is being processing. The basic flow of the process is as follows.

  1. Check the PID of the tty's login process
  2. Peering into a system call using the strace command against PID
  3. 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)