pwn环境配置

Posted by nop on 2019-09-10
Words 2k In Total

服务器上部署pwn题环境

来源:如何安全快速地部署多道ctf pwn比赛题目

pwn_deploy_chroot介绍

特点

  • 一次可以部署多个题目到一个docker容器中
  • 自动生成flag,并备份到当前目录
  • 也是基于xinted + docker + chroot
  • 利用python脚本根据pwn的文件名自动化地生成3个文件:pwn.xinetd,Dockerfile和docker-compose.yml
  • 在/bin目录,利用自己编写的静态编译的catflag程序作为/bin/sh,这样的话,system(“/bin/sh”)实际执行的只是读取flag文件的内容,完全不给搅屎棍任何操作的余地
  • 默认从10000端口监听,多一个程序就+1,起始的监听端口可以在config.py配置,或者生成pwn.xinetd和docker-compose.yml后自己修改这两个文件

服务器环境配置

1
2
3
4
5
6
# 安装docker
curl -s https://get.docker.com/ | sh
# 安装 docker compose 和git
apt install docker-compose git
# 下载
git clone https://github.com/giantbranch/pwn_deploy_chroot.git

使用

  1. 将要部署的pwn题目放到~/pwn_deploy_chroot/bin目录下,注意文件名不要含有特殊字符,文件名建议使用字母,下划线,短横线和数字;
  2. 运行initialize.py,运行脚本后会输出每个pwn的监听端口,文件与端口信息,还有随机生成的flag默认备份到flags.txt;
  3. 启动环境,root用户执行命令:docker-compose up --build -d,执行前确认docker已开启服务。
  4. 键入命令查看是否已经成功启动:netstat -antp | grep docker.

Docker

Ubuntu安装Docker(菜鸟教程)

Docker要求Ubuntu系统的内核版本高于3.10,可以通过命令uname -r查系统的内核版本

  • Docker安装
    Docker安装使用脚本安装,输入命令:wget -qO- https://get.docker.com/ | sh,中途可能会安装失败,可尝试命令sudo apt-get update后再进行安装。
    安装完成后,如果要以为root用户可以直接运行dockers,需要执行命令sudo usermod -aG docker username,然后重新登录,否则会报错。

  • 启动Docker后台服务
    键入命令sudo service docker start

  • 测试运行hello-world
    键入命令docker run hello-world,(docker run,创建一个新的容器并运行一个命令)
    Alt
    Alt

  • 镜像加速
    可以配置加速器来解决拉取Docker镜像十分缓慢的问题,网易的镜像地址http://hub-mirror.c.163.com
    键入命令gedit /etc/docker/daemon.json,添加内容:

    1
    2
    3
    {
    "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }
  • Ubuntu16.04
    Alt

  • Docker命令(容器生命周期管理)

    • docker run(参见3.测试运行hello-world)
    • docker start/stop/restart 命令
      Alt
    • docker kill
      Alt
    • docker rm
      Alt
    • docker pause/unpause
      Alt
    • docker create
      Alt
    • docker exec
      Alt
  • Docker命令(容器操作)

    • docker ps
      Alt
    • docker inspect
      Alt
    • docker top
      Alt
    • docker attach
      Alt
    • docekr events
      Alt
    • docker logs
      Alt
    • docker wait
      Alt
    • docker export
      Alt
    • docker port
      Alt
  • Docker命令(容器rootfs命令)

    • docker commit
      Alt
    • docker cp
      Alt
    • docker diff
      Alt
  • Docker命令(镜像仓库)

    • docker longin/logout
      Alt
    • docker pull
      Alt
    • docker push
      Alt
    • docker search
      Alt
  • Docker命令(本地镜像管理)

    • docker images
      Alt
    • docker rmi
      Alt
    • docker tag
      Alt
    • docker build
      Alt
      Alt
    • docker history
      Alt
    • docker save
      Alt
    • docker load
      Alt
    • docker import
      Alt
  • Docker命令(info|version)

    • docker info
      Alt
    • docker version
      Alt
  • Docker删除镜像
    Alt

Docker 容器的使用与简单操作

  • 导入打包好的ubuntu.17.04.amd64.tar
    将tar压缩文件拷贝到机器(Ubuntu)中后,键入命令cat ubuntu.17.04.amd64.tar | docker import - ubuntu/17.04.amd64
    回显sha1值后表示导入成功:(使用命令docker images会看到镜像仓库中出现了一个新的镜像)
    Alt
  • 以导入的镜像创建容器
    使用命令docker run -it -p 23946:23946 ubuntu/17.04.amd64 /bin/bash创建一个容器并开启一个shell,并且将IDA调试服务器监听的23946端口转发到本地的23946端口:
    Alt
    Alt
  • 更改容器名
    打开新的bash窗口,键入命令docker container ls -a可以发现多了一个刚刚创建的容器(被赋予了一个随机名: hungry_neumann
    Alt
    可以通过命令docker container rename hungry_neumann ubuntu.17.04.amd64把容器名更改为ubuntu.17.04.amd64或者其他名字
    Alt
  • 打开目标容器(进入容器)
    键入命令docker exec -it ubuntu.17.04.amd64 /bin/bash,打开目标容器的一个新的bash shell,可以在容器中启动IDA调试服务器并用socat部署Pwn题目(socat部署pwn题目,命令:socat tcp-listen:100001,reuseaddr,fork EXEC:./hello,pty,raw即将名为hello的elf文件的IO转发到10001端口上)
    Alt

    运行容器使用命令docker start ubuntu.17.04.amd64
    Alt
    注意:docker run ...是用于新建一个容器并运行,而运行已存在的容器使用命名docker start ...

  • 其他
    可以使用docker container cp命令在docker容器内外双向传输文件等等。需要注意的是,对容器的各种操作需要在容器运行时进行,若容器尚未运行(运行docker container ls未显示对应容器),需使用命令docker start运行对应容器。此外,若同时运行多个容器,为了避免端口冲突,在启动容器时,可以将命令docker run -it -p 23946:23946 ubuntu/17.04.amd64 /bin/bash 中的第一个端口号23946改为其他数字。

IDA的简单使用及远程调试配置

成功搭建Docker环境后,搭建IDA远程调试环境,在IDA安装目录下的dbgsrv目录下找到需要的调试服务器Linux_server(32位)Linux_serverx64(64位)并复制到虚拟机中。
键入命令(64位容器与此一致)docker container cp linux_server ubuntu.17.04.i386:/root/linux_serverlinux_server复制到32位容器(需要重新创建,过程和64位完全一致,即导入镜像、创建容器、映射端口等,此处我的32位容器映射端口号为23945

Alt

接着在IDA(32位)中载入调试测试程序heapTest_x86,定位到main函数后F2下断。然后启用Linux Debuuger通过Debugger->Process options...打开选项窗口设置远程调试选项

Alt

在弹出的选项窗口中配置Hostname为kali的ip地址,Port为容器映射到kali中的端口:

Alt

IDA会将被调试的文件复制到服务器所在目录下,然后汇编代码所在窗口背景会变成浅蓝色并且窗口布局发生变化。之后开始调试,F9运行程序,调试器常用快捷键:下断点/取消断点F2,运行程序F9,单步跨过函数F8,单步进入函数F7,运行到选中位置F4等。在调试模式下主要使用到的窗口有汇编窗口IDA View-EIP,寄存器窗口General registers,栈窗口Stack view,内存窗口Hex View,系统日志窗口Output window等。

Tips:当IDA中的程序执行完call ___isoc99_scanf或者类似的等待输入的指令后会陷入阻塞状态,F4,F7,F8,F9等和运行相关的快捷键都不生效。此时可以在shell中输入内容,IDA中的程序即可恢复执行。

使用pwntools和IDA调试程序

在这之前,确保linux_server开启

Alt

在调试过程中遇到一些特殊需求,如自动化完成一些操作或向程序传递一些包含不可见字符的地址(\x50\x83\x04\x08(0x08048350))。就需要使用脚本来完成这些工作。可以利用python的pwntools配合IDA调试程序。
首先,进入python,导入pwntools库

Alt

新开一个32位容器的bash shell,打开调试程序所在目录(heapTest),键入socat tcp-listen:10001,reuseaddr,fork EXEC:./heapTest,pty,raw,echo=0将heapTest的IO端口转发到10001端口上

Alt

此时回到python中,和172.17.0.2(docker地址)建立连接

Alt

需要注意的是,此时heapTest已经运行,需要在IDA中附加到程序调试,Debugger->Attach to process...,附加到程序调试(断点下在call __isoc99_scanf处)

Alt

开始调试后,EIP指向vdso中的pop ebp指令上

Alt

这几行指令实际是执行完sys_read后的指令,不用理会,直接F9,选中的标志会消失

Alt,此时IDA被挂起,等待输入。

回到python中,通过send(或sendline)函数向程序传递输入

Alt

此时IDA窗口停在程序领空

Alt

其中,io.recv()是读取输出,与程序交互,send和sendline的区别在于send不会在字符串末尾追加换行符


You are welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them.