Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gdb_history

This file was deleted.

4 changes: 2 additions & 2 deletions config.json
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"author": "GeekCmore",
"template": "~/.config/cpwn/exp_template.py",
"author": "Squeasp",
"template": "~/.config/cpwn/template/",
"script_name": "exp.py",
"file_path": "~/.config/cpwn/pkgs",
"kernel_file_path": "~/.config/cpwn/kernel_exploit",
Expand Down
115 changes: 88 additions & 27 deletions cpwn.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ def log_base(msg, color):


def log_info(msg):
log_base(msg, "blue")
log_base("[+] " + msg, "blue")

def log_table(msg):
log_base(msg, "blue")

def log_success(msg):
log_base(msg, "green")
log_base("[*] " + msg, "green")


def log_error(msg):
log_base(msg, "red")
log_base("[-] " + msg, "red")
exit(-1)


Expand Down Expand Up @@ -239,16 +241,19 @@ def detect(target_files: dict = {}) -> dict:
return target_files


def get_version_by_libc(file):
result = subprocess.run(
f'strings "{file}" | grep "Ubuntu GLIBC" | tail -n 1',
def get_version_by_libc(file):
result = subprocess.run( #
f'strings "{file}" | grep "Ubuntu GLIBC" | tail -n 1', #在libc文件中查找Ubuntu GLIBC
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True,
)
return result.stdout.split("(Ubuntu GLIBC ")[1].split(")")[0]

try:
version = result.stdout.split("(Ubuntu GLIBC ")[1].split(")")[0]
return version
except:
return 'ERROR'

def get_glibc_files(version: str, arch: str) -> dict:
"""
Expand Down Expand Up @@ -305,7 +310,7 @@ def choose_version():
libc_list = sorted(libc_list, key=lambda x: x)
for i, row in enumerate(libc_list):
table.add_row([str(i), row])
log_info(table)
log_table(table)
idx = int(input("Choose the version you wnat to modify:"))
return libc_list[idx]

Expand Down Expand Up @@ -337,6 +342,8 @@ def do_patch(target_files):
version = choose_version()
else:
version = get_version_by_libc(target_files[BaseFile.LIBC])
if version == 'ERROR':
return version
glibc_files = get_glibc_files(version, arch)
if not os.path.exists(glibc_files[BaseFile.LIBC]) or not os.path.exists(
glibc_files[BaseFile.LD]
Expand All @@ -347,7 +354,7 @@ def do_patch(target_files):
log_info("Start downloading...")
download_give_version_arch(version, arch)
else:
log_error("No suitable glibc!")
return 'ERROR'
prepared_files[BaseFile.LIBC] = glibc_files[BaseFile.LIBC]
prepared_files[BaseFile.LIBC] = glibc_files[BaseFile.LIBC]
prepared_files[BaseFile.LD] = glibc_files[BaseFile.LD]
Expand Down Expand Up @@ -381,21 +388,71 @@ def do_patch(target_files):
)
return prepared_files


def do_error_patch(target_files,template_args):
log_info("patch_failed! No suitable glibc!")
log_info("please patched by yourself! Something useful:")
log_info(f'chmod +x "{target_files[BaseFile.EXECUTABLE]}"')
log_info(f'patchelf --replace-needed libc.so.6 "{target_files[BaseFile.LIBC]}" "{target_files[BaseFile.EXECUTABLE]}"')
log_info(f'patchelf --set-interpreter "{target_files[BaseFile.LD]}" "{target_files[BaseFile.EXECUTABLE]}"')
if prompt(f"Do you want to use the found libc/ld ?"):
target_excutable = target_files[BaseFile.EXECUTABLE] + "_patched"
copy(target_files[BaseFile.EXECUTABLE], target_excutable)
subprocess.run(f'chmod +x "{target_files[BaseFile.EXECUTABLE]}"',text=True, shell=True)
subprocess.run(f'patchelf --replace-needed libc.so.6 "{target_files[BaseFile.LIBC]}" "{target_files[BaseFile.EXECUTABLE]}"',text=True, shell=True)
subprocess.run(f'patchelf --set-interpreter "{target_files[BaseFile.LD]}" "{target_files[BaseFile.EXECUTABLE]}"',text=True, shell=True)
template_args["libc_path"] = {target_files[BaseFile.LIBC]}
template_args["src_path"] = 'error'
template_args["dbg_path"] = 'error'
else:
template_args["dbg_path"] = 'error'
template_args["src_path"] = 'error'
template_args["libc_path"] = 'error'
def do_generate(args: dict):
from jinja2 import Template

template = Template(open(os.path.expanduser(config["template"])).read())
rendered_template = template.render(
filename=os.path.basename(args["target"]) + '_patched',
libcname=args.get("libc_path"),
host=args.get("host"),
port=args.get("port"),
debug_file_directory=args.get("dbg_path"),
source_dircetory=args.get("src_path"),
author=args.get("author"),
time=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
)
import glob
# 展开模板目录路径
template_dir = os.path.expanduser(config["template"])
# 检查template是否是目录
if os.path.isdir(template_dir):
# 获取目录下所有的.py文件作为模板选项
template_files = glob.glob(os.path.join(template_dir, "*.py"))
if not template_files:
log_error(f"No template files found in {template_dir}")
exit(1)
log_info("Available template files:")
for i, template_file in enumerate(template_files, 1):
log_info(f"{i}. {os.path.basename(template_file)}")
while(1):
try:
choice = int(input("Please select a template number: "))
if 1 <= choice <= len(template_files):
selected_template = template_files[choice - 1]
break
else:
log_info(f"Please enter a number between 1 and {len(template_files)}")
except ValueError:
log_info("Invalid number")
exit(1)
# 读取用户选择的模板文件
log_info(f"Using template: {os.path.basename(selected_template)}")
template = Template(open(selected_template).read())
else:
log_error("config template not a directory.")
exit(1)
try:
rendered_template = template.render(
filename=os.path.basename(args["target"])+ '_patched',
libcname=args.get("libc_path"),
host=args.get("host"),
port=args.get("port"),
debug_file_directory=args.get("dbg_path"),
source_dircetory=args.get("src_path"),
author=args.get("author"),
time=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
)
except Exception as e:
log_error(f"Error rendering template: {e}")
exit(1)
if os.path.exists(config["script_name"]):
if not prompt("Script exists, do you want to cover it?"):
log_info("Haven't cover it. No script genarated.")
Expand Down Expand Up @@ -539,7 +596,7 @@ def cli(ctx, verbose, config, threads, force):

@cli.command(help="Initialize pwn game exploit enviroment.")
@click.option("--host", help="Remote host.", default="127.0.0.1")
@click.option("--port", help="Remote port.", default="1337")
@click.option("--port", help="Remote port.", default="9999")
@click.option("--nopatch", help="Just generate exp without patching elf.", is_flag=True, default=False)
@click.option("--noexp", help="Just patch elf without generating exp.", is_flag=True, default=False)
def init(host, port, nopatch:bool, noexp:bool):
Expand All @@ -549,9 +606,13 @@ def init(host, port, nopatch:bool, noexp:bool):
template_args["target"] = target_files[BaseFile.EXECUTABLE]
if not nopatch:
prepared_files = do_patch(target_files)
template_args["dbg_path"] = prepared_files.get(BaseFile.DBG)
template_args["src_path"] = prepared_files.get(BaseFile.SRC)
template_args["libc_path"] = prepared_files.get(BaseFile.LIBC)
if(prepared_files == 'ERROR'):
do_error_patch(target_files,template_args)

else:
template_args["dbg_path"] = prepared_files.get(BaseFile.DBG)
template_args["src_path"] = prepared_files.get(BaseFile.SRC)
template_args["libc_path"] = prepared_files.get(BaseFile.LIBC)
# generate exp
if not noexp:
template_args["host"] = host
Expand Down
Empty file modified kernel_exploit/.gdbinit
100644 → 100755
Empty file.
Empty file modified kernel_exploit/exp.c
100644 → 100755
Empty file.
Empty file modified requirements.txt
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ echo "Start setup!"
pip install -r requirements.txt
sudo apt-get install patchelf
mkdir -p ~/.config/cpwn
cp config.json ~/.config/cpwn/
cp template.py ~/.config/cpwn/exp_template.py
cp config.json ~/.config/cpwn/config.json
cp -r ./template ~/.config/cpwn/template
cp -r ./kernel_exploit ~/.config/cpwn/kernel_exploit
chmod +x cpwn.py
echo "Move cpwn to /usr/bin"
Expand Down
63 changes: 0 additions & 63 deletions template.py

This file was deleted.

48 changes: 48 additions & 0 deletions template/template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
'''
author: {{author}}
time: {{time}}
'''
from pwn import *
from time import sleep
filename = "{{filename}}"
libcname = "{{libcname}}"
host = "{{host}}"
port = {{port}}
elf = context.binary = ELF(filename)
context.terminal = ['tmux', 'neww']
context(arch = 'amd64',log_level = 'debug',os = 'linux')
if libcname:
libc = ELF(libcname)
gs = '''
b main
{% if debug_file_directory %}set debug-file-directory {{debug_file_directory}}{%endif%}
{% if source_dircetory %}set directories {{source_dircetory}}{%endif%}
'''

def start():
if args.GDB:
return gdb.debug(elf.path, gdbscript = gs)
elif args.REMOTE:
return remote(host, port)
else:
return process(elf.path)
#---------------------------------------------------#
r = lambda x:p.recv(x)
rl = lambda:p.recvline(keepends=True)
til = lambda x:p.recvuntil(x,drop=True)
s = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
sa = lambda x,y:p.sendafter(x,y)
sla = lambda x,y:p.sendlineafter(x,y)
suc = lambda x,y:success(x+" -> "+y)
#---------------------------------------------------#
def db() :
gdb.attach(p)
pause()

p = start()

# Your exploit here

p.interactive()
Loading