论菜鸡pwn手如何在无网环境(ps:类似国赛)下生存

引言:在打完一次无网环境后,觉得没网环境实在难受,查个libc都没得查。。没准备好,那时碰巧我下了ctf-challenge,在那里碰巧弄到了libc,可能有人喜欢用libc-searcher那个py版本的项目,我不怎么喜欢,用那个导入库查找感觉较慢,还是喜欢手动泄露后到网页查找,于是有了这篇文章

pwntools安装

pip install pwntools

出错自己解决啊,那些个错误都查得到

one_gadget

gem install one_gadget

gdb配置

我个人觉得,peda和pwndbg必备,gef也可以用上,随你
自己写了个脚本,很渣,自选用不用
项目地址
三个插件一起用会冲突,一部分功能失效,建议注释掉.gdbinit里的gef部分

welpwn

这个项目是国防科技大学弄的,挺好用的,最主要是能加载libc

git clone https://github.com/matrix1001/welpwn

到项目目录下然后

sudo python setup.py install

用法你可以看他项目里的介绍

ctf-wiki本地搭建

作为一个不是啥都熟的选手,ctf-wiki还是必备的,打比赛的时候查查exp,查查用法什么都好

首先安装docker

这个不讲了

docker pull镜像

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端口

部署libc-database

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
项目地址
用法在项目里已经说明了,只是修改了一点点错误

者本地搭建ctf-all-in-one

https://github.com/firmianay/CTF-All-In-One

下载项目

git clone https://github.com/firmianay/CTF-All-In-One

GitBook基础

README.md和SUMMARY.md
必备文件

利用Docker安装Gitbook

docker search gitbook #可以查看,我用了最高星的那个
docker pull fellah/gitbook

先到项目的目录下
然后

docker run -v $PWD:/srv/gitbook -v $PWD/html:/srv/html fellah/gitbook gitbook build . /srv/html

展示Gitbook文件

因为生成的是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端口看下,是否成功了

下载ctf-challenge,例题以及exp

git clone https://github.com/ctf-wiki/ctf-challenges
这个说不定哪天就用上了,说不准

exp模板构建

因为要快速做题,每次重复的部分整合起来比较好,所以便研究下exp模板如何弄,我是通过修改pwntools里自带的exp模板,生成自己专属的模板的,我建议都弄成自己的exp模板类型吧,因为每个人代码风格不一样,没必要一定用大佬的模板,当然有可能大佬的模板好,但不一定适合自己

模板位置

第一个是模板的具体内容,第二个是生成模板的方法

  • pwnup.mako
  • template.py

你可以find / -name 名称
找到具体位置,最好先备份一份

具体配置自行配置,因为每个人风格不同

pwntools exp模板自定义

<%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就是参数,通过这个方法进行模板的生成

pwntools exp模板生成方法

#!/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()

点击收藏 | 4 关注 | 2
  • 动动手指,沙发就是你的了!
登录 后跟帖