引言:在打完一次无网环境后,觉得没网环境实在难受,查个libc都没得查。。没准备好,那时碰巧我下了ctf-challenge,在那里碰巧弄到了libc,可能有人喜欢用libc-searcher那个py版本的项目,我不怎么喜欢,用那个导入库查找感觉较慢,还是喜欢手动泄露后到网页查找,于是有了这篇文章
出错自己解决啊,那些个错误都查得到
我个人觉得,peda和pwndbg必备,gef也可以用上,随你
自己写了个脚本,很渣,自选用不用
项目地址
三个插件一起用会冲突,一部分功能失效,建议注释掉.gdbinit里的gef部分
这个项目是国防科技大学弄的,挺好用的,最主要是能加载libc
git clone https://github.com/matrix1001/welpwn
到项目目录下然后
sudo python setup.py install
用法你可以看他项目里的介绍
作为一个不是啥都熟的选手,ctf-wiki还是必备的,打比赛的时候查查exp,查查用法什么都好
这个不讲了
docker search ctf #先查找镜像,镜像名知道可以不查找 docker pull ctfwiki/ctf-wiki #pull ctfwiki镜像 docker run -d --name=ctf-wiki -p 4100:80 ctfwiki/ctf-wiki #-d参数为后台运行,--name为名称 -p为端口映射 4100是本地端口,80是docker端口
docker pull blukat29/libc
docker run -p 4101:80 -d blukat29/libc
配置文件目录/etc/nginx/conf.d/nginx.conf
启动端口在4101,这里有个小问题,就是无法下载,解决方法,替换nginx的配置文件为如下
server { location / { try_files $uri @app; } location @app { include uwsgi_params; uwsgi_param Host $host; uwsgi_param X-Real-IP $remote_addr; uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for; uwsgi_pass unix:///tmp/uwsgi.sock; } location /static { alias /app/static; } location /d { alias /libc-database/db; location ~ \.symbols$ { default_type text/plain; } } }
最主要是
location /d { alias /libc-database/db; location ~ \.symbols$ { default_type text/plain; } }
然后发觉每次重启都会他配置文件都会重置,研究下了他docker里的东西,发觉是entrypoint.sh影响了,所以修改下entrypoint.sh就行
#! /usr/bin/env bash set -e # Get the maximum upload file size for Nginx, default to 0: unlimited USE_NGINX_MAX_UPLOAD=${NGINX_MAX_UPLOAD:-0} # Generate Nginx config for maximum upload file size echo "client_max_body_size $USE_NGINX_MAX_UPLOAD;" > /etc/nginx/conf.d/upload.conf # Get the number of workers for Nginx, default to 1 USE_NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-1} # Modify the number of worker processes in Nginx config sed -i "/worker_processes\s/c\worker_processes ${USE_NGINX_WORKER_PROCESSES};" /etc/nginx/nginx.conf # Get the URL for static files from the environment variable USE_STATIC_URL=${STATIC_URL:-'/static'} # Get the absolute path of the static files from the environment variable USE_STATIC_PATH=${STATIC_PATH:-'/app/static'} # Get the listen port for Nginx, default to 80 USE_LISTEN_PORT=${LISTEN_PORT:-80} # Generate Nginx config first part using the environment variables echo "server { listen 80; location / { try_files \$uri @app; } location @app { include uwsgi_params; uwsgi_param Host \$host; uwsgi_param X-Real-IP \$remote_addr; uwsgi_param X-Forwarded-For \$proxy_add_x_forwarded_for; uwsgi_pass unix:///tmp/uwsgi.sock; } location /static { alias /app/static; } location /d { alias /libc-database/db; location ~ \.symbols$ { default_type text/plain; } }" > /etc/nginx/conf.d/nginx.conf # If STATIC_INDEX is 1, serve / with /static/index.html directly (or the static URL configured) if [[ $STATIC_INDEX == 1 ]] ; then echo " location = / { index $USE_STATIC_URL/index.html; }" >> /etc/nginx/conf.d/nginx.conf fi # Finish the Nginx config file echo "}" >> /etc/nginx/conf.d/nginx.conf exec "$@"
然后就部署完成了,如果还嫌麻烦,可以用下我这个Dockerfile
项目地址
用法在项目里已经说明了,只是修改了一点点错误
https://github.com/firmianay/CTF-All-In-One
git clone https://github.com/firmianay/CTF-All-In-One
README.md和SUMMARY.md
必备文件
docker search gitbook #可以查看,我用了最高星的那个
docker pull fellah/gitbook
先到项目的目录下
然后
docker run -v $PWD:/srv/gitbook -v $PWD/html:/srv/html fellah/gitbook gitbook build . /srv/html
因为生成的是html静态页面所以需要一个web服务来显示,我用nginx
docker pull nginx docker run --name ctf-all-in-one -v /$PWD/html:/usr/share/nginx/html -d -p 4102:80 nginx
这样就搭建完成了
访问你自己的4100-4102端口看下,是否成功了
git clone https://github.com/ctf-wiki/ctf-challenges
这个说不定哪天就用上了,说不准
因为要快速做题,每次重复的部分整合起来比较好,所以便研究下exp模板如何弄,我是通过修改pwntools里自带的exp模板,生成自己专属的模板的,我建议都弄成自己的exp模板类型吧,因为每个人代码风格不一样,没必要一定用大佬的模板,当然有可能大佬的模板好,但不一定适合自己
第一个是模板的具体内容,第二个是生成模板的方法
你可以find / -name 名称
找到具体位置,最好先备份一份
具体配置自行配置,因为每个人风格不同
<%page args="binary, host=None, port=None, libc=None, local=True"/>\ <% import os import sys from pwnlib.context import context as ctx from pwnlib.elf.elf import ELF from pwnlib.util.sh_string import sh_string from elftools.common.exceptions import ELFError argv = list(sys.argv) argv[0] = os.path.basename(argv[0]) try: if binary: ctx.binary = ELF(binary, checksec=False) except ELFError: pass if not binary: binary = './path/to/binary' exe = os.path.basename(binary) binary_repr = repr(binary) libc_repr = repr(libc) %>\ #!/usr/bin/env python2 # -*- coding: utf-8 -*- from PwnContext.core import * local = True %if ctx.binary: # Set up pwntools for the correct architecture exe = './' + ${binary_repr} elf = context.binary = ELF(exe) <% binary_repr = 'exe.path' %> %else: context.update(arch='i386') exe = ${binary_repr} <% binary_repr = 'exe' %> %endif #don't forget to change it %if host: host = args.HOST or ${repr(host)} %else: host = '127.0.0.1' %endif %if port: port = int(args.PORT or ${port}) %else: port = 10000 %endif #don't forget to change it #ctx.binary = './' + ${repr(binary)} ctx.binary = exe %if not libc: libc = elf.libc ctx.debug_remote_libc = False %else: libc = args.LIBC or ${libc_repr} ctx.debug_remote_libc = True %endif ctx.remote_libc = libc if local: context.log_level = 'debug' try: io = ctx.start() except Exception as e: print(e.args) print("It can't work,may be it can't load the remote libc!") print("It will load the local process") io = process(exe) else: io = remote(host,port) #=========================================================== # EXPLOIT GOES HERE #=========================================================== %if ctx.binary and not quiet: # ${'%-10s%s-%s-%s' % ('Arch:', ctx.binary.arch, ctx.binary.bits, ctx.binary.endian)} %for line in ctx.binary.checksec(color=False).splitlines(): # ${line} %endfor %endif def exp(): pass if __name__ == '__main__': exp() io.interactive()
具体语法可以理解为
%if args
content
%endif
content就是内容,args就是参数,通过这个方法进行模板的生成
#!/usr/bin/env python2 from __future__ import absolute_import import re from pwn import * from pwnlib.commandline import common from mako.lookup import TemplateLookup parser = common.parser_commands.add_parser( 'template', help = 'Generate an exploit template' ) parser.add_argument('exe', nargs='?', help='Target binary') parser.add_argument('--host', help='Remote host / SSH server') parser.add_argument('--port', help='Remote port / SSH port', type=int) parser.add_argument('--libc', help='Remote libc version') parser.add_argument('--local', help='local debug', action='store_true') def main(args): cache = None if cache: cache = os.path.join(context.cache_dir, 'mako') lookup = TemplateLookup( directories = [os.path.join(pwnlib.data.path, 'templates')], module_directory = cache ) template = lookup.get_template('pwnup.mako') output = template.render(args.exe, args.host, args.port, args.libc, args.local, ) # Fix Mako formatting bs output = re.sub('\n\n\n', '\n\n', output) print output if not sys.stdout.isatty(): try: os.fchmod(sys.stdout.fileno(), 0700) except OSError: pass if __name__ == '__main__': pwnlib.commandline.common.main(__file__)
└──╼ $pwn template oreo --libc libc.so.6
#!/usr/bin/env python2 # -*- coding: utf-8 -*- from PwnContext.core import * local = True # Set up pwntools for the correct architecture exe = './' + 'oreo' elf = context.binary = ELF(exe) #don't forget to change it host = '127.0.0.1' port = 10000 #don't forget to change it #ctx.binary = './' + 'oreo' ctx.binary = exe libc = args.LIBC or 'libc.so.6' ctx.debug_remote_libc = True ctx.remote_libc = libc if local: context.log_level = 'debug' try: io = ctx.start() except Exception as e: print(e.args) print("It can't work,may be it can't load the remote libc!") print("It will load the local process") io = process(exe) else: io = remote(host,port) #=========================================================== # EXPLOIT GOES HERE #=========================================================== # Arch: i386-32-little # RELRO: No RELRO # Stack: Canary found # NX: NX enabled # PIE: No PIE (0x8048000) def exp(): pass if __name__ == '__main__': exp() io.interactive()