2019年1月14日星期一
任务一、把 elfpass 拷贝进 seed 虚拟机,设成 root 所有 suid 程序,用普通用户去攻击获得 root权限。可以先静态分析,搞不定再用 gdb 动态调试。
先查看反汇编代码:
根据上述流程易得比较的值为unixvwindows
任务二:运行 win.pyc,要求输出'You Win'代表成功
反编译后代码为:
def encrypt(key, seed, string):
rst = []
for v in string:
rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
seed = (seed + 1) % len(key)
return rst
if __name__ == '__main__':
print "Welcome to idf's python crackme"
flag = input('Enter the Flag: ')
KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
KEY2 = [124,48,52,59,164,50,37,62,67,52,48,6,1,122,3,22,72,1,1,14,46,27,232]
en_out = encrypt(KEY1, 5, flag)
if KEY2 == en_out:
print 'You Win'
else:
print 'Try Again !'
解码代码为:
#coding=utf-8
key1='Maybe you are good at decryptint Byte Code, have a try!'
key2=[124, 48, 52, 59, 164, 50, 37, 62, 67, 52, 48, 6, 1, 122, 3, 22, 72, 1, 1, 14, 46, 27,
232]
v1=[]
def getv(inp,result):
for v in range(255):
if (v+inp)%255==result:
return v
def decode(key,seed):
for x in key2:
for v in range(255):
if(v+seed^ord(key[seed]))%255==x:
break
v1.append(chr(v))
seed=(seed+1)%len(key)
print(v1)
decode(key1,5)
获得密钥:['W', 'C', 'T', 'F', '{', 'I', 'L', 'O', 'V', 'E', 'P', 'Y', 'T', 'H', 'O', 'N', 'S', 'O', 'M', 'U', 'C', 'H', '}']
WCTF{ILOVEPYTHONSOMUCH}
任务三、阅读以下文章,学习ELF文件格式及其相关内容
https://www.cnblogs.com/brotherlittlefish/p/5557476.html
https://blog.csdn.net/feglass/article/details/51469511
1、ELF文件基础知识:
对象文件(object files)有三个种类
1)可重定位对象文件(relocatable file)【目标文件或者静态共享文件 .a .o】
2)可执行对象文件(executable file)【bash、gcc】
3)共享对象文件(shared object file)【共享库 .so】
ELF包括三个索引表:
1)ELF header ---ELF头,在文件的开始,保存了路线图,描述了文件的组织情况
2)program header table ---程序头部表,告诉程序如何创建进程映像
3)section header table ---节区头补表,包含了描述文件节区的信息,大小,偏移
2、ELF文件格式
ELF提供两种视图,分别是链接视图和执行视图
链接视图以节为单位,是在链接的时候用到的视图
执行视图以段为单位,是在执行的时候用到的视图
使用readelf –S task 查看可执行文件中有哪些section
查看文件的执行视图 readelf –s(egment) task查看文件执行视图
3、ELF Header
ELF文件中常用的数据格式
ELF结构体:
#define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
ELF32_Half e_type;
ELF32_Half e_machine;
ELF32_Word e_version;
ELF32__Addr e_entry;
ELF32_Off e_phoff;
ELF32_Off e_shoff;
ELF32_Word e_flags;
ELF32_Half e_ehsize;
ELF32_Half e_phentsize;
ELF32_Half e_phnum;
ELF32_Half e_shentsize;
ELF32_Half e_shnum;
ELF32_Half e_shstrndx;
}Elf32_Ehdr;
Readelf –h task 查看ELF Header结构的内容
4、Section header Table
Section
符号表(.dynsym)
字符串表(.dynstr)
重定位表
5、Program Header Table
程序结构如下:
typedef struct {
Elf32_Word p_type; //此数组元素描述的段的类型,或者如何解释此数组元素的信息。
Elf32_Off p_offset; //此成员给出从文件头到该段第一个字节的偏移
Elf32_Addr p_vaddr; //此成员给出段的第一个字节将被放到内存中的虚拟地址
Elf32_Addr p_paddr; //此成员仅用于与物理地址相关的系统中。System V忽略所有应用程序的物理地址信息。
Elf32_Word p_filesz; //此成员给出段在文件映像中所占的字节数。可以为0。
Elf32_Word p_memsz; //此成员给出段在内存映像中占用的字节数。可以为0。
Elf32_Word p_flags; //此成员给出与段相关的标志。
Elf32_Word p_align; //此成员给出段在文件中和内存中如何对齐。
} Elf32_phdr;
任务四、详解.NET IL代码(IL语言如何在NET下运行)
引用:https://blog.csdn.net/cnhk1225/article/details/53568996
IL指的是Intermediate Language
C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言数据
Language Complier(语言编译器)无论是VB Code还是C# code都会被Language Complier转换为MSIL
JIT编译器把MSIL中间语言指令转为及其识别的机器代码
分析IL代码:
Managed Heap(托管堆):这就是NET中的托管堆,用来存放引用类型,他是由GC(垃圾回收器自动进行回收)
Call Stack(调用堆栈):调用堆栈是一个方法列表,它会安装调用顺序保存所有在运行期间被调用的方法
Evaluation Stack(计算堆栈):每个线程都有自己的线程类,IL里面的任何计算,都发生在Evaluation Stack上,其实就是一个Stack结构,可以Push,也可以Pop
会用到的IL指令:
nop:无操作
ret:从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
call:调用由传递的方法说明符指示的方法。
box:将值类转换为对象引用,就是装箱,同理可以知道拆箱unbox
ldc.i4.X:把int32的值推送到计算堆栈
stloc.X:把计算堆栈顶部的值放到调用堆栈索引为X处
ldloc.X:把调用堆栈X处的值复制到计算堆栈
例子:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint //程序入口
// 代码大小 42 (0x2a)
.maxstack 2 // 计算出计算堆栈的能存几个值
.locals init ([0] int32 i,
[1] int32 j,
[2] int32 k,
[3] int32 answer) //定义int32类型的i,j,k,answer
IL_0000: nop //无操作
IL_0001: ldc.i4.1 //把i的值放到计算堆栈上
IL_0002: stloc.0 //把计算堆栈顶部的值(i的值)放到调用堆栈索引0处
IL_0003: ldc.i4.2 //把j的值放到计算堆栈上
IL_0004: stloc.1 //把计算堆栈顶部的值(j的值)放到调用堆栈索引1处
IL_0005: ldc.i4.3 //把k的值放到计算堆栈上
IL_0006: stloc.2 //把计算堆栈顶部的值(k的值)放到调用堆栈索引2处
IL_0007: ldloc.0 //把调用堆栈索引为0处的值复制到计算堆栈
IL_0008: ldloc.1 //把调用堆栈索引为1处的值复制到计算堆栈
IL_0009: add //相加
IL_000a: ldloc.2 //把调用堆栈索引为2处的值复制到计算堆栈
IL_000b: add //相加
IL_000c: stloc.3 //把计算堆栈顶部的值(add的值)放到调用堆栈索引3处
IL_000d: ldstr "i+j+k=" //推送对元数据中存储的字符串的新对象引用。
IL_0012: ldloc.3 //把调用堆栈索引为3处的值复制到计算堆栈
IL_0013: box [mscorlib]System.Int32 //装箱
IL_0018: call string [mscorlib]System.String::Concat(object,object) //调用内部方法
IL_001d: call void [mscorlib]System.Console::WriteLine(string) //调用WriteLine
IL_0022: nop //无操作
IL_0023: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey() //调用ConsoleKey
IL_0028: pop //无操作
IL_0029: ret //return
} // end of method Program::Main
任务五、常用文件头和文件尾格式总结
文件格式 |
文件头 |
文件尾 |
JPEG(jpg) |
FF D8 FF |
FF D9 |
PNG(png) |
89 50 4E 47 |
AE 42 60 82 |
GIF(gif) |
47 49 46 38 |
00 3B |
ZIP(zip) |
50 4B 03 04 |
50 4B |
TIFF(tif) |
49 49 2A 00 |
|
bmp |
42 4D |
|
XML(xml) |
3C 3F 78 6D 6C |
|
HTML(html) |
68 76 6D 6C |
|
RAR(rar) |
52 61 72 21 |