linux命令很久没用了,最近从新温习一下,找到了一个wargames系列游戏,能够依照要求进行相干命令行操作,从而通关游戏,先从Bandit开始
Level 0~3 (ls)
按要求连贯bandit.labs.overthewire.org
,端口号2220
ssh bandit0@bandit.labs.overthewire.org -p 2220 password: bandit0
Level 1~2仅需cd
到对应文件夹,cat
查看即可,Level3须要查看暗藏文件,ls -a
找到暗藏文件即可。
明码如下:
lv1: NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjLlv2: rRGizSaX8Mk1RTb1CNQoXTcYZWU6lgzilv3: aBZ0W5EmUfAf7kHTQeOwd8bauFJ2lAiGlv4: 2EW7BBsr6aMMoJ2HjW067dm8EgX26xNe
Level 4~7 (grep + find)
Level 4 查找 human-readable文件
这里明码是/^[0-9a-zA-Z]$/
格局,因而grep过滤内容,命令如下:
grep -rE "^[0-9a-zA-Z]+$" ./inhere/
Level 5~7条件查找过滤
level5条件如下:
- human-readable
- 1033 bytes in size
- not executable
按过滤的效率,先比照size,再过滤不能执行的,最初用grep过滤内容,命令如下:
find ./inhere/ -type f -size 1033c ! -executable -exec grep -rE "^[0-9a-zA-Z]+$" {} +
level6过滤条件如下:
- owned by user bandit7
- owned by group bandit6
- 33 bytes in size
命令如下(因为是练习题,所以换成管道的写法,实际上这里用这种写法效率并不高):
find / -type f -size 33c -user bandit7 -group bandit6 | xargs -I{} grep -rE "^[0-9a-zA-Z]+$" {}
但这样又有一个问题,打印内容中大量Permission denied
,这是因为find从根目录开始找,会找到很多无权拜访的文件,因而须要将谬误重定向,写法如下:
find / -type f 2>>/dev/null -size 33c -user bandit7 -group bandit6 | xargs -I{} grep -rE "^[0-9a-zA-Z]+$" {}
这里2>>/dev/null
是一种重定向操作符,它将规范谬误(stderr)输入重定向到 /dev/null
设施。 /dev/null
是一个非凡设施文件,它会将所有写入它的数据抛弃掉,不做任何解决,如果指向的是具体的文件,谬误将会被写入该文件中,可用于谬误日志。
level7过滤条件如下:
- in data.txt
- next to the word millionth
间接上手,写的命令如下
grep "millionth.*" ./data.txt
但这种写法输入是millionth xxxxx
,尽管能够失去明码,但咱们其实仅须要明码局部,更精准的写法如下:
grep "millionth.*" ./data.txt | cut -f 2# orgrep -oP "millionth\s+\K.+" ./data.txt
前一种写法代表将查找后果宰割,获取第二列。后一种写法是获取正则的捕捉组,grep -E
的正则貌似没法获取捕捉内容,而-p
采纳Perl
的正则语法,\K
获取捕捉组,配合-o
输入捕捉组
lv5: lrIWWI6bB37kxfiCQZqUdOIYfr6eEeqRLv6: P4L4vucdmLnm8I7Vl7jG1ApGSfjYKqJUlv7: z7WtoNQU2XfjmMtWA8u5rN4vzqu4v99Slv8: TESKZC0XvTetK0S9xNwm25STk5iWrBvP
Level8~ 12(awk uniq sort tr..)
level8 查找不反复的行
题目要求在data.txt中找到惟一不反复的行。
因为linux命令不熟,所以一上手就想着用awk
解决问题,思路比较简单,先用一个cache
统计每行字段的呈现次数,再从cache
中找到count
为1的字段,代码如下:
awk '{ cache[$0] = cache[$0] + 1;} END { for(s in cache) { if(cache[s]==1) { print s exit } }}' ./data.txt
但看题目上面的提醒,提到了uniq
和sort
,查看uniq
文档,尽管uniq
能够统计词频,甚至间接显示仅呈现一次的行,但当反复的行并不相邻时,uniq 命令是不起作用的,这样设计很好了解,若uniq
能够解决不相邻的反复字段,那必然须要对整个文件字段进行缓存,这种操作显然是不太有利于流文件的解决,这种原子级的命令应优先思考性能,性能能够通过命令之间的组合实现。因而要先用sort
去对内容进行排序,最终代码如下:
sort ./data.txt | uniq -u
level9 在文件中明码
明码的条件:
- 明码后面有几个"="
- 明码是human readable的
不难写出如下代码:
grep -aoP "={2,}\s*\K[0-9a-zA-Z]+" ./data.txt
这里先要给grep
加上-a
指令符,因为data.txt
中有二进制内容
Level 10明码通过了base64加密
base64 -d ./data.txt
Level 11 内容解码
这里题目比拟难了解,所有字母都旋转了13个地位,但通过cat ./data.txt
查看文档,会发现文档内容如下:
Gur cnffjbeq vf WIAOOSFzMjXXBC0KoSKBbJ8puQm5lIEi
依据后面几题的后果,比拟容易猜想前三个单词是The password is
, 数字对的上,那么规定也比拟好猜了,就是将a-z造成一个环形链表,这里的旋转指的是旋转环形链表的地位,留神这里说的是字母而非数字
用awk实现,代码如下:
awk ' BEGIN { for(i=65;i<=122;i++) { ord[sprintf("%c", i)]=i } } function transform(str, offset) { cache="" len=length(str); for(i=1;i<=len;i++) { w=substr(str,i,1); word=w if(match(w,/[a-zA-Z]/)){ n=ord[w] start=97; end=122; if(n>=65 && n<=90) { start=65; end=90; } count=n - offset; if(count<start) { count=end + (count-start + 1) } word=sprintf("%c", count) } cache=sprintf("%s%s", cache, word) } return cache } { offset=13; str=$0; transStr=transform(str, offset)} END { print transStr}' ./data.txt
awk
对linux
命令不相熟的人比拟敌对,但这么实现切实太长了。。。
对于awk脚本
一开始实现这段脚本的时候,认为awk前面接的脚本字符串,被awk解释器解析完之后会转换成shell或者c语言执行,所以下意识感觉sprintf根本规定和printf相似,因而字母转ASCII码想着通过word=sprintf("%d", "a")
实现,但最初打印进去word
是0。认真一想awk
解释器之所以是解释器,而不是编译器,是因为它并不会走残缺的解析->遍历->编译的流程,应该是边解析边执行的,遇到sprintf
或者会将其解析为printf
行为,但遇到参数%d
后,下一个参数走的应该是走的整数类型的解析,或者就是这里将非整数类型的对象间接转换成0了。
tr命令
用命令的话,tr
命令可进行替换,思路差不多,先获取偏移后的字符串,再进行替换。。
cache=$(echo {a..z} | tr -d " ");printf -v cache "${cache:13}${cache:0:13}";cacheUpper=$(echo $cache | tr 'a-z' 'A-Z');tr "[a-z][A-Z]" "[$cache][$cacheUpper]" < ./data.txt;
lv9: EN632PlfYiZbn3PhVK3XOGSlNInNE00tlv10: G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6slv11: 6zPeziLdR2RKNdNYFNb6nVCKzphlXHBMlv12: JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv