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

2019-07-27 约 931 字 预计阅读 5 分钟

声明:本文 【论菜鸡pwn手如何在无网环境(ps:类似国赛)下生存】 由作者 NoOne 于 2019-07-27 09:33:00 首发 先知社区 曾经 浏览数 25 次

感谢 NoOne 的辛苦付出!

论菜鸡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()

关键词:[‘安全技术’, ‘CTF’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now