在pwn简单题圈子里混了这么久,终于要第一次出题了,但是依旧有很多陌生的东西没接触过,所以这篇博客总结了一些出题过程中涉及到的点。(持续更新)
¶1. gcc编译选项
通过编译选项可以直接打开或关闭程序的四项保护,默认全开,这里记录如何关闭/打开:
- canary:-fno-stack-protector/-fstack-protector
- NX:-z execstack/-z noexecstack
- PIE: -no-pie/-pie
- RELRO:-z lazy(延迟绑定)、-z norelro(完全关闭)、-z now
在引入一些外来库时需要添加额外的选项,以下为博主遇到的例子:
- seccomp: -lseccomp
下面是其他常用的编译选项:
- 编译32位程序:-m32
- 编译优化:-O0(default)、-O1、-O2、-O3(没尝试过区别)
- 忽略警告信息:-w
- 产生调试信息,gdb调试时显示c语言源码:-g
- 使用位置无关代码(PIC):-fPIC
若想要使用高版本gcc编译出低版本GLIBC程序,则需要使用docker拉取一个旧版本Ubuntu镜像,在镜像中使用gcc编译,再将编译出的程序使用挂载卷取出。
¶2. docker的简单使用
众所周知,pwn题最需要保证无误的是依赖文件和环境,因此便需要用到docker来制作对应的镜像以保存题目环境。不得不说实践是学习技术最有效的方式了,出题前一直搞不懂docker怎么用的。在这里梳理一下关于docker的一些指南。
¶docker安装
docker在Windows和Linux平台上的安装是不同的,Windows下首先需要安装wsl,然后直接安装docker desktop即可使用。但是这种方法有一个严重的问题,博主的pwn环境一直都是在虚拟机中的ubuntu环境下进行的,而docker desktop与vmware是无法共存的,网上搜到的解决方法没有能够同时打开两者的。因此不得不在linux下安装docker。
warning: 如果同是使用vmware下的ubuntu环境,在尝试安装前请保留安装前快照,否则某些方法会导致系统崩掉(原因仍然未知)
经多次坎坷的尝试,终于找到了不会出问题的安装方法,具体教程可以参考本文,亲测能够在博主的机子上非常顺利地进行下去。
¶docker常用命令
现在假设我们拥有一道出好的pwn题,指可执行程序,以及下载好的docker环境,接下来的第一步就是编写dockerfile。dockerfile中命令的语言为专用语言,具体语法可以通过各种官方网站查询学习;另一种方法就是程序员的必备技能——使用github上的项目。这里推荐一个很好用很全面的项目>>戳这里<<。接下来只需要按照项目的要求把附件放入src文件夹即可。
那么如何玩转docker?只需记住下面几种命令
command | description |
---|---|
docker build -t {name:tag} . | 执行dockerfile,build出对应的image |
docker images | 列出当前所有镜像 |
docker rmi {name|id} | 删除对应镜像 |
docker run -d --name={name:tag} -p {port}:9999 {name} | 创建容器 |
docker kill {name} & docker rm {name} | 杀死容器以及删除容器 |
docker exec -it {name} /bin/bash | 以root权限进入交互模式 |
目前这些命令足以完成pwn题目创建的一套流程,可以检测远程环境能否如愿打通。
¶其他可能用到的命令或选项
command | description |
---|---|
docker run --rm | 容器停止后自动删除容器 |
docker run -v {host_dir:container_dir} | 为容器挂载卷 |
¶其他问题
¶解决方法1
由于docker hub的功成身退(悲),在拉取ubuntu镜像时可能会报错,我们可以使用国内的镜像网站进行替代,这里记录一下博主的配置:
首先打开以下配置文件:
在该文件中加入下方的配置,可以在浏览器中先尝试网址是否能够访问
好了,配置完了,接下来可以去尝试docker build能否正常运行了。
附上一张正常执行的图:
¶解决方法2
在一个伟大的日子10/24,我受到了群友邪恶的诅咒,导致docker又 build不出来了
通过搜索引擎最终找到了新的解决方法。
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
然后添加如下内容,即设置代理地址
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1"
其中127.0.0.1:7890需要改成梯子监听的实际代理地址和端口,以本次为例,需要修改为
此时即可正常从docker.io中拉取ubuntu镜像了。