• 攻防世界题目练习——Web引导模式(三)(持续更新)


    攻防世界题目练习——Web引导模式(四)(持续更新)

    1. mfw

    进去看到网页和页面内容如下:
    在这里插入图片描述
    看到url的参数 ?page=about ,我以为是文件包含什么的,反复试了几次,想用 …/…/…/…/etc/passwd ,但是发现.似乎被过滤了,实在不知道怎么做了,于是找了几篇解题博客:
    攻防世界-mfw-(详细操作)做题笔记
    攻防世界----mfw
    看了博客才知道,存在一种git源码泄露漏洞,相关知识见博客:WEB安全-常见源码泄露 | wh1te

    git源码泄露是:
    当在一个空目录执行 git init 时,Git 会创建一个 .git 目录。 这个目录包含所有的 Git 存储和操作的对象。
    利用方式:
    github上的githack可以把整个.git备份的文件下载下来。它能解析 .git/index 文件,并找到工程中所有的:文件名和文件 sha1,然后去 .git/objects/ 文件夹下下载对应的文件,通过 zlib 解压文件,按原始的目录结构写入源代码。
    于是用url/.git访问,可以看到显示了许多文件,可能是源代码文件。
    在这里插入图片描述
    看了几个目录没有看到flag相关的。
    博客说用githacker下载文件,于是我按照博客攻防世界-mfw-(详细操作)做题笔记中使用githacker下载文件时的路径在我的kali中找githacker,没找到,于是参考别的博客去下载githack:
    GitHack在kali Linux环境下的下载与安装
    下载完成后,因为看到前面的参考博客里是用的__init__.py文件来下载,于是在我下载的githacker-master的目录下的lib目录中找到了这个文件,按照那篇博客上的命令还是没法下载。想到那篇教下载的博客上最后的步骤:

    python2 GitHack.py http://challenge-efb678740fb6553d.sandbox.ctfhub.com:10800/.git
    
    • 1

    用的是python2 GitHack.py url/.git,于是用这个命令尝试,终于成功了,下载存放的位置在GitHacker-master的dist目录下,为了方便我把文件夹更名为了GitHack,如下图:
    在这里插入图片描述
    可以看到里面有一个文件flag.php,打开看里面什么都没看到。里面唯一有有价值信息的就是index.php文件(和templates文件夹在同一目录下,上图未展示),打开查看如下:
    在这里插入图片描述
    可以看到红框框出的部分是两个assert断言,其中第一个的注释"I heard ‘…’ is dangerous!",以及assert中将 ‘$file’ 和 ‘…’ 做匹配,可以解释我在一开始发现的.被过滤掉了的情况,第二个assert是判断文件是否存在。

    我们直接访问flag.php的话是可以访问的,但是没有内容显示。
    在这里插入图片描述
    我们要绕过第一个assert的判断。
    在源码中可以看到如下:

    $file = "templates/" . $page . ".php";
    
    assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
    
    • 1
    • 2
    • 3

    将$file的值代入进去就是:

    assert("strpos('templates/$page.php', '..') === false") or die("Detected hacking attempt!");
    
    • 1

    我们需要让后面和 ‘…’ 进行比较的部分失效,就需要用到 // 将后面的内容注释掉,并用')来与strpos()函数的前半部分('templates/进行闭合。
    这里我将几篇参考博客结合起来看:
    博客1:攻防世界----mfw
    博客2:【攻防世界】十八、mfw
    博客3:攻防世界-mfw-(详细操作)做题笔记

    在博客3讲的拼接不是很详细,没太懂这样构造之后在代码中是怎么拼接的,于是看了博客1.
    博客1对于拼接的替换构造讲的挺清楚,但是我不理解为什么这个博主构造的拼接内容templates前面为什么会有两个单引号:
    在这里插入图片描述

    于是我又查看了博客2,这个构造的拼接后的内容和我理解的一样:
    在这里插入图片描述

    在博客3的评论区中我了解到,这里的.是链式拼接:
    在这里插入图片描述

    在返回的源码中可以看到flag:
    在这里插入图片描述

    在linux下没法直接看到flag.php的内容,猜测可能是因为php文件有些内容要在网页中才能显示?
    在这里插入图片描述

    再来尝试一下用or system('cat templates/flag.php');//,发现用or system只显示了一次flag,如下图:
    在这里插入图片描述

    博客1对于这个的解释是这样的,但我还是没看懂为什么:
    在这里插入图片描述
    但是我仍然有个疑问,在page=').system('cat templates/flag.php');//拼接之后,assert的")也被注释掉了,这样为什么可以正常执行system命令呢。
    所以我想试试page=') or system('cat templates/flag.php'));//,用两个括号,把assert也闭合掉看看。
    失败了,不行诶,有点没搞懂。
    又仔细看了看博客1,说的是 “利用assert()函数执行cat ./template/flag.php获得flag” 。但是注释符不是会把后面的内容全部注释掉吗,这样的话怎么利用assert()函数呢,真的迷惑。

    对上面的疑问,我终于明白了TAT:
    assert("strpos('templates/') or system('cat templates/flag.php');//.php', '..') === false")中,
    本身//""的包裹下会被当作普通字符,但是assert会将字符串当作php代码来解析执行,所以解析到//这部分时将//解析为注释,所以后面这一部分.php', '..') === false都被当初注释处理了,//的注释作用只作用到.php', '..') === false这一部分为止,不包括后面assert函数的闭合部分“)。

    2. Cat

    题目:
    在这里插入图片描述
    看了看网页源码没有什么发现,于是抓包查看:
    在这里插入图片描述
    抓包也没有看到什么有用的信息,只看到了是get方式的请求,参数名为 “url” 。尝试了一下也不是sql注入。
    看看别人的解析吧,参考博客如下:
    [CTF题目总结-web篇]攻防世界:Cat
    以及攻防世界里本题的用户darkless的WP

    根据几篇题解来看,我们需要转换思路入手,这里要求输入的内容是一个域名,那么此时想到的不应该是普通的sql注入,域名是ip地址的映射,输入ip地址意味着访问的动作,这时应想到的是命令执行。
    一个访问ip的命令要可以执行,那么我们输入的这个域名应该是有效的可以访问的。
    我先输入了www.baidu.com,无事发生。
    WriteUp中发现这里是可以输入ip地址的,于是我又尝试了114.114.114.114。
    在这里插入图片描述
    包丢失但是有回显。
    题解里的思路是输入127.0.0.1来进行测试(这是一个需要记住的思路),通过输入127.0.0.1,我们既可以看到回显,又可以看到返回的有用的信息,如下图:
    在这里插入图片描述
    可以看到本题中Submit提交执行的是 ping 命令,并且ping通后返回了一条路径。
    因此我们在这里考虑尝试命令拼接执行,但是会发现尝试的拼接符都会被过滤。
    然后题解博客里都是用FUZZ来进行测试,根据报文返回长度看哪些字符没被过滤,但是我不知道哪种fuzz工具好用,并且感觉BurpSuite也可以做到这个功能,所以这里我就用BurpSuite爆破一下。
    爆破我得录入所有可见的ascii码字符,但网上全是表格,所以写了个脚本T_T:

    s = ""
    for c in range(32, 127):
        s += chr(c)
        s += "\n"
    print(s)
    '''
     (空格)
    !
    "
    #
    $
    %
    &
    '
    (
    )
    *
    +
    ,
    -
    .
    /
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    :
    ;
    <
    =
    >
    ?
    @
    A
    B
    C
    D
    E
    F
    G
    H
    I
    J
    K
    L
    M
    N
    O
    P
    Q
    R
    S
    T
    U
    V
    W
    X
    Y
    Z
    [
    \
    ]
    ^
    _
    `
    a
    b
    c
    d
    e
    f
    g
    h
    i
    j
    k
    l
    m
    n
    o
    p
    q
    r
    s
    t
    u
    v
    w
    x
    y
    z
    {
    |
    }
    ~
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    把除了字母之外的其他字符复制进去进行爆破:
    在这里插入图片描述
    可以看到这些报文返回长度为458的是没有出现报错,也就是没有被过滤的字符:
    在这里插入图片描述
    然后题解里说注意到了输入的数据采用url编码,但是我真的很迷惑啊,感觉有时候输入的被url编码了有的又没有,啊啊啊啊啊,烦人。
    然后就开始用url编码来试探了,就是输入了超过ascii编码的最大值的url编码后,页面就会报错,那就把这个也当作一个试探的小技巧吧。
    只能直接在url里输入,不能在提交框里。
    在这里插入图片描述
    把内容复制下来保存为html文件,再用浏览器打开:
    在这里插入图片描述
    用户darkless的WP中对本题的突破点的原理进行了解释,如下:
    在这里插入图片描述
    这位大佬后面用@查看setting.py来查看的步骤有点多余,就在最开始的报错页面后面就有setting部分的内容:
    在这里插入图片描述
    在这里可以看到数据库的相关信息,包括数据库的绝对路径,于是接下来在绝对路径前加@查看:
    在这里插入图片描述
    再次将内容复制保存为html文件用浏览器打开,在post内容的最后可以看到flag的信息。
    在这里插入图片描述
    (真无语,前面几个字母根本不知道哪些是包含在flag里的,试了半天)

    3. ics-05

    访问网址看到如下页面:
    在这里插入图片描述
    只有设备维护中心能访问,进入设备维护中心之后,点击别的地方都没有反应,只有点击左上角设备维护中心时页面会显示内容并且url发生变化:
    在这里插入图片描述
    尝试修改page=后面的内容,内容都会回显,于是考虑文件包含漏洞,尝试page=../../../../../etc/passwd,成功看到内容显示:
    在这里插入图片描述
    尝试用php://input和data://text/plain上传system命令列出存在的文件,但是页面没有回显内容,于是参考了一下别的博客:
    攻防世界XCTF:ics-05
    因为现在已知的只有index.php文件,所以可以用php://filter查看index.php源代码:
    在这里插入图片描述
    将内容用base64解密后,关键代码内容如下:

    //方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试
    
    if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {
    //如果X-FORWARDED-FOR=127.0.0.1
        echo "
    Welcome My Admin !
    "
    ; //就可以进入admin模式 $pattern = $_GET[pat]; $replacement = $_GET[rep]; $subject = $_GET[sub]; if (isset($pattern) && isset($replacement) && isset($subject)) { preg_replace($pattern, $replacement, $subject); //preg_replace()函数搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换 }else{ die(); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    首先是一个if语句判断,需要我们在请求报文中添加:X-Forwarded-for: 127.0.0.1
    接下来是最后的preg_replace函数部分
    参考博客:
    PHP preg_replace() 函数 | 菜鸟教程
    关键点在于preg_replace()函数存在可执行模式的漏洞,详情如下:
    preg_replace /e 模式 漏洞分析总结
    /e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。
    因此,我们需要上传3个GET请求参数:pat、rep、sub,令rep=我们希望执行的system命令,令pattern匹配的内容与subject完全相同,以实现将replacement中的内容完全替换到subject中。由于正则匹配的语法规则,pattern用于列举要搜索匹配的模式串需要用到一对//定界符,然后在末尾加上e表示作为可执行模式,因此,令pat=/hello/e&rep=system('ls')&sub=hello
    在这里插入图片描述
    然后我们查看名字比较特殊一点的目录:s3chahahaDir。
    这里需要用到命令拼接符&&,A&&B是B依据A执行的结果来执行,A执行成功,则B在A的结果下执行。
    rep=system('cd s3chahahaDir&&ls')
    要注意 空格和&&在url中可能不会被识别为参数的内容,可能作为了分隔符,因此需要对其进行url编码来传递进去
    在这里插入图片描述
    不确定flag是一个目录还是一个文件:
    rep=system('cd s3chahahaDir&&cd flag&&ls')
    在这里插入图片描述
    rep=system('cd s3chahahaDir/flag&&cat flag.php')
    在这里插入图片描述

    4. easytornado

    进入网页如图:
    在这里插入图片描述
    查看各个文件内容如下图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    看到题目写的是Tornado 框架,因此搜索了一下Tornado框架漏洞,有文件读取漏洞,还有文件注入漏洞,结合我们在welcom.txt中看到的render,有一个漏洞是比较符合该题目的:
    python SSTI tornado render模板注入

    在hints.txt文件中,我们可以看到一个md5加密的式子,里面用到了cookie_secret与filename文件名,再结合我们在url中看到的filehash,因此猜测,我们需要获取cookie_secret再结合文件名fllllllllllllag来访问查看到flag。

    参考博客中可以看到如下内容:
    tornado render是python中的一个渲染函数,也就是一种模板,通过调用的参数不同,生成不同的网页,如果用户对render内容可控,不仅可以注入XSS代码,而且还可以通过{{}}进行传递变量和执行简单的表达式。
    在这里插入图片描述
    在上面的内容中我们可以看到,可以通过{{}}访问handler.settings变量来查看到cookie_secret内容,如下图:
    在这里插入图片描述
    ‘cookie_secret’: ‘bcc697f9-f999-4fd3-af9c-ee78e4a3d744’

    接下来,我们结合cookie_secret与fllllllllllllag文件名来生成filehash,脚本如下:

    # coding=gbk
    import hashlib
    
    cookie_secret = 'bcc697f9-f999-4fd3-af9c-ee78e4a3d744'
    filename = '/fllllllllllllag'
    m = hashlib.md5()
    filename_ = m.update(filename.encode())
    filename_hash = m.hexdigest()
    # 生成filename的md5加密内容
    # hashlib.md5()重新实例化,去除前面的update()的干扰
    m = hashlib.md5()
    filehash = m.update(cookie_secret.encode())
    filehash = m.update(filename_hash.encode())
    filehash = m.hexdigest()
    print(filehash)
    #f66bc84f5cf258ae8bea0e7b1b8cd358
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    一开始用filename = 'fllllllllllllag’生成的filehash并不正确,看了另一篇参考博客tornado框架漏洞 攻防世界(easytornado)才知道文件名前面要加上/,filename = ‘/fllllllllllllag’

    md5使用参考博客如下:
    python使用md5函数怎么调库:
    python hashlib库(MD5,sha1,sha256,sha512,pbkdf2_hmac)用法及pbkdf2原理
    发现没法直接用hashlib.m5(cookie_secret+hashlib.m5(filename)),会出现报错:
    Strings must be encoded before hashing
    学习如何正确使用md5加密的步骤
    python中的md5加密
    Python hashlib模块中的md5加密
    想要清空update的内容,重新更换内容进行加密,就要重新对hashlib.m5()进行实例化:
    python md5_Python之md5.update才过的哪些坑
    在这里插入图片描述
    PS:
    然后瞅了眼官方解析,发现他是先定义了md5函数:
    这样果然方便了很多,呜呜学到了

    def md5(s):
        md5 = hashlib.md5()
        md5.update(s)
        return md5.hexdigest()
    
    print(md5(cookie_secret+md5(filename)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5. lottery

    如下,题目给了下载附件,打开发现是源码。
    在这里插入图片描述
    在附件中可以找到robots.txt,打开看到不允许爬取/.git/目录:
    在这里插入图片描述
    因此猜测可能和git源码泄露有关,但是源码已经全部给我们了,不需要再用githack下载。
    参考博客:
    攻防世界Web lottery
    首先查看index.php:
    在这里插入图片描述
    可以看到有两个比较重要的文件header.php和buy.php,先点开header.php看看:
    在这里插入图片描述
    可以看到几个主要文件index.php、buy.php、account.php、market.php分别对应网页首页的4个跳转页面,并且根据index.php的内容,“play to win"这个链接对应的应该也是buy.php:
    在这里插入图片描述
    然后看看buy.php、account.php、market.php里有没有什么有用的信息,
    market.php页面的内容:
    也就是我们要中彩票凑到足够多的钱才能买到flag
    在这里插入图片描述
    buy.php页面中是我们输入数字匹配中奖号的位置:
    在这里插入图片描述
    在这里应该会有和中奖号进行匹配的源码内容:
    在这里插入图片描述
    可以看到,在点击buy按钮之后,后面的内容是"Please wait…”,而在这之间应该就是进行计算匹配的程序,如上图看可以看到会加载buy.js这个文件,因此我们再查看buy.js:
    在这里插入图片描述
    这个buy应该就是进行匹配的函数,但是并没有看到进行计算的源码,看到一个ajax的内容里出现了api.php,搜索了一下ajax是什么:
    JavaScript之Ajax(一篇入门Ajax就够了)
    大概理解为通过ajax的方式又请求api.php的内容,然后我们来看api.php:
    在这里插入图片描述
    可以看到api.php里有很多函数,buy()函数应该就是最关键的匹配中奖号码的函数,win_numbers是通过random_win_nums()函数随机产生的,后面用if($numbers[$i] == $win_numbers[$i])来进行判断。
    在前面攻防世界题目练习——Web难度1的12.simple_php题中我第一次接触到了php的弱等于(==)绕过,再深入学习一下:
    php比较绕过(强比较“===”/弱比较“==“)
    可以看到true和除0以外的任何字符串都相等,0和false相等,这就是突破口,可以考虑先随便输入一串数字,然后在BurpSuite抓包时对它进行修改为全为true。

    可以看到生成随机数的代码如下,数字为0的概率应该比较小(大概,应该):
    在这里插入图片描述
    然后抓包:
    (我敲 火狐网页好卡 一个页面半天加载不出来 垃圾,只能换成google浏览器开全局代理了TAT)
    在这里插入图片描述
    然后把numbers后面的"1234567"改为列表[true,true,true,true,true,true,true]
    在这里插入图片描述
    像这样多来几次,赚够钱,再去买flag
    在这里插入图片描述

  • 相关阅读:
    golang八股文整理(持续搬运)
    使用JavaMailSender进行邮件发送
    Spring中各个jar包的作用
    保姆级cat系统搭建过程
    Acwing 3302. 表达式求值
    【Python】模拟windows文件名排序
    Matlab:十六进制和二进制值
    自动化测试有必要学吗?
    OC-NSNumber和NSValue一般用来装箱拆箱
    驱动代码整理
  • 原文地址:https://blog.csdn.net/qq_48550824/article/details/133793351